Skip to content

Commit

Permalink
Implement Runtime.Context.Dataflow_Stack_Trace for dataflow errors th…
Browse files Browse the repository at this point in the history
…rown from Enso (#9625)
  • Loading branch information
GregoryTravis authored Jul 26, 2024
1 parent 74acc1d commit f0e9616
Show file tree
Hide file tree
Showing 22 changed files with 88 additions and 47 deletions.
8 changes: 7 additions & 1 deletion distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import project.Runtime.Source_Location.Source_Location
import project.System
from project.Data.Boolean import Boolean, False, True
from project.Data.Text.Extensions import all
from project.Runtime.Context import Input, Output
from project.Runtime.Context import Dataflow_Stack_Trace, Input, Output

## Utilities for interacting with the runtime.

Expand Down Expand Up @@ -146,10 +146,15 @@ type Context
## PRIVATE
ADVANCED
Input

## PRIVATE
ADVANCED
Output

## PRIVATE
ADVANCED
Dataflow_Stack_Trace

## PRIVATE
ADVANCED

Expand All @@ -160,6 +165,7 @@ type Context
case self of
Input -> "Input"
Output -> "Output"
Dataflow_Stack_Trace -> "Dataflow_Stack_Trace"

## PRIVATE
ADVANCED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1201,12 +1201,12 @@ class RuntimeErrorsTest
contextId,
xId,
Api.MethodCall(Api.MethodPointer(moduleName, moduleName, "foo")),
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId, xId))
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId))
),
TestMessages.error(
contextId,
yId,
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId, xId))
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId))
),
TestMessages.update(contextId, mainResId, ConstantsGen.NOTHING),
context.executionComplete(contextId)
Expand Down Expand Up @@ -1238,12 +1238,12 @@ class RuntimeErrorsTest
Api.MethodCall(Api.MethodPointer(moduleName, moduleName, "foo")),
fromCache = false,
typeChanged = false,
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId, xId))
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId))
),
TestMessages.error(
contextId,
yId,
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId, xId)),
Api.ExpressionUpdate.Payload.DataflowError(Seq(fooThrowId)),
typeChanged = false
),
TestMessages.update(
Expand Down Expand Up @@ -2036,12 +2036,12 @@ class RuntimeErrorsTest
contextId,
xId,
Api.MethodCall(Api.MethodPointer(moduleName, moduleName, "foo")),
Api.ExpressionUpdate.Payload.DataflowError(Seq(xId))
Api.ExpressionUpdate.Payload.DataflowError(Seq())
),
TestMessages.error(
contextId,
yId,
Api.ExpressionUpdate.Payload.DataflowError(Seq(xId))
Api.ExpressionUpdate.Payload.DataflowError(Seq())
),
TestMessages.update(
contextId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.state.State;

@BuiltinMethod(
type = "Error",
name = "throw",
description = "Returns a new value error with given payload.",
inlineable = true)
public class ThrowErrorNode extends Node {
public Object execute(VirtualFrame giveMeAStackFrame, Object payload) {
return DataflowError.withoutTrace(payload, this);
public Object execute(VirtualFrame giveMeAStackFrame, State state, Object payload) {
return DataflowError.withDefaultTrace(state, payload, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private static Atom createProjectDescriptionAtom(EnsoContext ctx, Package<Truffl
}

private DataflowError unsupportedArgsError(Object moduleActual) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this)
.getBuiltins()
.error()
Expand All @@ -116,7 +116,7 @@ private DataflowError unsupportedArgsError(Object moduleActual) {
}

private DataflowError notInModuleError(EnsoContext ctx) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
ctx.getBuiltins().error().makeModuleNotInPackageError(), this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ final PanicException panicOtherwise(double self, Object that) {
final DataflowError incomparableError(Object self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var incomparableErr = builtins.error().makeIncomparableValues(self, that);
return DataflowError.withoutTrace(incomparableErr, this);
return DataflowError.withDefaultTrace(incomparableErr, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Object doLongShiftLeftExplicit(long self, long that) {
} else if (positiveFitsInInt.profile(BigIntegerOps.fitsInInt(that))) {
return toEnsoNumberNode.execute(BigIntegerOps.bitShiftLeft(self, (int) that));
} else {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
}
}
Expand Down Expand Up @@ -75,7 +75,7 @@ Object doBigInteger(long self, EnsoBigInteger that) {
return self >= 0 ? 0L : -1L;
} else {
// Note [Well-Formed BigIntegers]
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
}
}
Expand All @@ -93,7 +93,7 @@ Object doBigIntShiftLeftExplicit(
if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) {
return doBigIntShiftLeft(self, that);
} else {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
}
}
Expand All @@ -120,7 +120,7 @@ Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) {
if (!BigIntegerOps.nonNegative(that.getValue())) {
return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L;
} else {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Object doLong(long self, long that) {
try {
return self / that;
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand All @@ -42,7 +42,7 @@ Object doLong(EnsoBigInteger self, long that) {
try {
return toEnsoNumberNode.execute(BigIntegerOps.divide(self.getValue(), that));
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ Object doInterop(
Object doOther(Object self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
return DataflowError.withoutTrace(incomparableValsErr, this);
return DataflowError.withDefaultTrace(incomparableValsErr, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ Object doInterop(
Object doOther(Object self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
return DataflowError.withoutTrace(incomparableValsErr, this);
return DataflowError.withDefaultTrace(incomparableValsErr, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ Object doInterop(
Object doOther(Object self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
return DataflowError.withoutTrace(incomparableValsErr, this);
return DataflowError.withDefaultTrace(incomparableValsErr, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ Object doInterop(
Object doOther(Object self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
return DataflowError.withoutTrace(incomparableValsErr, this);
return DataflowError.withDefaultTrace(incomparableValsErr, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Object doLong(long self, long that) {
try {
return self % that;
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand All @@ -47,7 +47,7 @@ Object doBigInteger(long self, EnsoBigInteger that) {
try {
return toEnsoNumberNode.execute(BigIntegerOps.modulo(selfBigInt, that.getValue()));
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand All @@ -57,7 +57,7 @@ Object doLong(EnsoBigInteger self, long that) {
try {
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that));
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand All @@ -74,7 +74,7 @@ Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
try {
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that.getValue()));
} catch (ArithmeticException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Object execute(Text value, long radix) {
noEx2.enter();
var errors = EnsoContext.get(this).getBuiltins().error();
var err = errors.makeNumberParseError(ex.getMessage());
return DataflowError.withoutTrace(err, this);
return DataflowError.withDefaultTrace(err, this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Object sortPrimitives(
try {
return sortPrimitiveVector(elems, javaComparator);
} catch (CompareException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
incomparableValuesError(e.leftOperand, e.rightOperand), this);
}
}
Expand Down Expand Up @@ -266,7 +266,7 @@ Object sortGeneric(
ctx.getBuiltins()
.error()
.makeIncomparableValues(firstIncomparableElem, secondIncomparableElem);
return DataflowError.withoutTrace(err, this);
return DataflowError.withDefaultTrace(err, this);
} else {
// Just one comparator, different from Default_Comparator
if (!gatheredWarnings.isEmpty()) {
Expand All @@ -289,7 +289,7 @@ Object sortGeneric(
default -> throw EnsoContext.get(this).raiseAssertionPanic(this, "unreachable", null);
}
} catch (CompareException e) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
incomparableValuesError(e.leftOperand, e.rightOperand), this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@
public class Context extends Builtin {
@Override
protected List<Cons> getDeclaredConstructors() {
return List.of(new Cons(INPUT_NAME), new Cons(OUTPUT_NAME));
return List.of(
new Cons(INPUT_NAME), new Cons(OUTPUT_NAME), new Cons(DATAFLOW_STACK_TRACE_NAME));
}

public static final String INPUT_NAME = "Input";

public static final String OUTPUT_NAME = "Output";

public static final String DATAFLOW_STACK_TRACE_NAME = "Dataflow_Stack_Trace";

public AtomConstructor getInput() {
return getConstructors()[0];
}

public AtomConstructor getOutput() {
return getConstructors()[1];
}

public AtomConstructor getDataflowStackTrace() {
return getConstructors()[2];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ public static EnsoObject fromString(EnsoContext context, String path)
.getBuiltins()
.error()
.makeUnsupportedArgumentsError(new Object[] {Text.create(path)}, ex.getMessage());
return DataflowError.withoutTrace(err, null);
return DataflowError.withDefaultTrace(err, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ EnsoHashMap removeFromEnsoMap(
if (mapBuilder.remove(frame, key, hashCodeNode, equalsNode)) {
return mapBuilder.build();
} else {
throw DataflowError.withoutTrace("No such key", null);
throw DataflowError.withDefaultTrace("No such key", null);
}
}

Expand Down Expand Up @@ -92,7 +92,7 @@ EnsoHashMap removeFromInteropMap(
return EnsoHashMap.createWithBuilder(mapBuilder);
} else {
CompilerDirectives.transferToInterpreter();
throw DataflowError.withoutTrace("No such key " + keyToRemove, interop);
throw DataflowError.withDefaultTrace("No such key " + keyToRemove, interop);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.state.State;

/**
* A runtime object representing an arbitrary, user-created dataflow error.
Expand All @@ -29,14 +30,6 @@ public final class DataflowError extends AbstractTruffleException implements Ens
/** Signals (local) values that haven't yet been initialized */
public static final DataflowError UNINITIALIZED = new DataflowError(null, (Node) null);

private static final boolean assertsOn;

static {
var b = false;
assert b = true;
assertsOn = b;
}

private final Object payload;
private final boolean ownTrace;

Expand All @@ -49,9 +42,11 @@ public final class DataflowError extends AbstractTruffleException implements Ens
* @param location the node in which the error was created
* @return a new dataflow error
*/
public static DataflowError withoutTrace(Object payload, Node location) {
public static DataflowError withDefaultTrace(State state, Object payload, Node location) {
assert payload != null;
if (assertsOn) {
boolean attachFullStackTrace =
state == null ? true : state.currentEnvironment().hasContextEnabled("Dataflow_Stack_Trace");
if (attachFullStackTrace) {
var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location);
TruffleStackTrace.fillIn(result);
return result;
Expand All @@ -61,6 +56,10 @@ public static DataflowError withoutTrace(Object payload, Node location) {
}
}

public static DataflowError withDefaultTrace(Object payload, Node location) {
return withDefaultTrace(null, payload, location);
}

/**
* Construct a new dataflow error with the provided stack trace.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Object doType(
@Fallback
@CompilerDirectives.TruffleBoundary
Object doAny(Object value) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this)
.getBuiltins()
.error()
Expand Down Expand Up @@ -197,7 +197,7 @@ Object doMetaObject(
@Fallback
@CompilerDirectives.TruffleBoundary
Object doAny(Interop any, Object value) {
return DataflowError.withoutTrace(
return DataflowError.withDefaultTrace(
EnsoContext.get(this)
.getBuiltins()
.error()
Expand Down
Loading

0 comments on commit f0e9616

Please sign in to comment.