Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataflow Errors #1433

Merged
merged 8 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions distribution/std-lib/Test/src/Test.enso
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,17 @@ Any.should verb argument = verb Verbs this argument
## Fail a test with the given message.
fail message = Panic.throw (Failure message)

## Expect a function to fail with the provided error.
expect_fail_with ~action matcher =
## Expect a function to fail with the provided dataflow error.
expect_error_with ~action matcher =
result = action
fail_msg = "Expected an error " + matcher.to_text + "but none occurred."
if result.is_error.not then here.fail fail_msg else
caught = result.catch x->x
if caught.is_a matcher then Nothing else
here.fail ("Unexpected error " + caught.to_text + " thrown.")

## Expect a function to fail with the provided panic.
expect_panic_with ~action matcher =
res = Panic.recover action
case res of
_ -> here.fail ("Expected a " + matcher.to_text + " to be thrown, but the action succeeded.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.NotInvokableException;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.state.Stateful;

/**
Expand Down Expand Up @@ -93,6 +94,32 @@ Stateful invokeConstructor(
invokeFunctionNode);
}

@Specialization
Stateful invokeDataflowError(
DataflowError error,
MaterializedFrame callerFrame,
Object state,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail) {
return new Stateful(state, error);
}

@Specialization
Stateful invokePanicSentinel(
PanicSentinel sentinel,
MaterializedFrame callerFrame,
Object state,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail) {
throw sentinel;
}

@Specialization
public Stateful invokeDynamicSymbol(
UnresolvedSymbol symbol,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.enso.interpreter.node.callable;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.ReportPolymorphism;
Expand Down Expand Up @@ -28,6 +29,7 @@
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.number.EnsoBigInteger;
import org.enso.interpreter.runtime.state.Stateful;

Expand Down Expand Up @@ -281,6 +283,20 @@ Stateful doDataflowError(
}
}

@Specialization
Stateful doPanicSentinel(
MaterializedFrame frame,
Object state,
UnresolvedSymbol symbol,
PanicSentinel _this,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail) {
throw _this;
}

@Specialization
Stateful doArray(
MaterializedFrame frame,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.NotInvokableException;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.state.Stateful;

/**
Expand Down Expand Up @@ -142,6 +143,18 @@ Stateful invokeConstructor(
return invokeFunction(constructor.getConstructorFunction(), callerFrame, state, arguments);
}

@Specialization
Stateful invokeDataflowError(
DataflowError error, VirtualFrame callerFrame, Object state, Object[] arguments) {
return new Stateful(state, error);
}

@Specialization
Stateful invokePanicSentinel(
PanicSentinel sentinel, VirtualFrame callerFrame, Object state, Object[] arguments) {
throw sentinel;
}

@Specialization
public Stateful invokeDynamicSymbol(
UnresolvedSymbol symbol, VirtualFrame callerFrame, Object state, Object[] arguments) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.enso.interpreter.node.callable;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import java.util.UUID;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
import org.enso.interpreter.node.callable.resolver.ArrayResolverNode;
Expand All @@ -28,11 +28,10 @@
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.number.EnsoBigInteger;
import org.enso.interpreter.runtime.state.Stateful;

import java.util.UUID;

public abstract class InvokeMethodNode extends BaseNode {
private @Child InvokeFunctionNode invokeFunctionNode;
private final ConditionProfile errorProfile = ConditionProfile.createCountingProfile();
Expand Down Expand Up @@ -181,6 +180,16 @@ Stateful doDataflowError(
}
}

@Specialization
Stateful doPanicSentinel(
VirtualFrame frame,
Object state,
UnresolvedSymbol symbol,
PanicSentinel _this,
Object[] arguments) {
throw _this;
}

@Specialization
Stateful doArray(
VirtualFrame frame,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.enso.interpreter.runtime.Context;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.type.TypesGen;

/**
Expand Down Expand Up @@ -58,6 +59,19 @@ public Object doError(VirtualFrame frame, DataflowError error) {
return error;
}

/**
* Rethrows a panic sentinel if it encounters one.
*
* @param frame the stack frame in which to execute
* @param sentinel the sentinel being matched against
* @return nothing
*/
@Specialization
public Object doPanicSentinel(VirtualFrame frame, PanicSentinel sentinel) {
iamrecursion marked this conversation as resolved.
Show resolved Hide resolved
CompilerDirectives.transferToInterpreter();
throw sentinel;
}

/**
* Executes the case expression.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
Expand All @@ -18,13 +19,16 @@ public class InstantiateNode extends ExpressionNode {
private final AtomConstructor constructor;
private @Children ExpressionNode[] arguments;
private @CompilationFinal(dimensions = 1) ConditionProfile[] profiles;
private @CompilationFinal(dimensions = 1) BranchProfile[] sentinelProfiles;

InstantiateNode(AtomConstructor constructor, ExpressionNode[] arguments) {
this.constructor = constructor;
this.arguments = arguments;
this.profiles = new ConditionProfile[arguments.length];
this.sentinelProfiles = new BranchProfile[arguments.length];
for (int i = 0; i < arguments.length; ++i) {
this.profiles[i] = ConditionProfile.createCountingProfile();
this.sentinelProfiles[i] = BranchProfile.create();
}
}

Expand All @@ -51,8 +55,17 @@ public static InstantiateNode build(AtomConstructor constructor, ExpressionNode[
public Object executeGeneric(VirtualFrame frame) {
Object[] argumentValues = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
ConditionProfile profile = profiles[i];
BranchProfile sentinelProfile = sentinelProfiles[i];
Object argument = arguments[i].executeGeneric(frame);
argumentValues[i] = argument;
if (profile.profile(TypesGen.isDataflowError(argument))) {
return argument;
} else if (TypesGen.isPanicSentinel(argument)) {
sentinelProfile.enter();
throw TypesGen.asPanicSentinel(argument);
} else {
argumentValues[i] = argument;
}
}
return constructor.newInstance(argumentValues);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.enso.interpreter.node.expression.builtin.io;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CachedContext;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import java.io.PrintStream;
import org.enso.interpreter.Language;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.dsl.MonadicState;
import org.enso.interpreter.node.callable.InvokeCallableNode;
Expand All @@ -19,8 +20,6 @@
import org.enso.interpreter.runtime.state.Stateful;
import org.enso.interpreter.runtime.type.TypesGen;

import java.io.PrintStream;

@BuiltinMethod(
type = "IO",
name = "print_err",
Expand All @@ -31,7 +30,7 @@ static PrintErrNode build() {
}

abstract Stateful execute(
VirtualFrame frame, @MonadicState Object state, Object _this, Object message);
VirtualFrame frame, @MonadicState Object state, Object _this, @AcceptsError Object message);

@Specialization
Stateful doPrintText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CachedContext;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import java.io.PrintStream;
import org.enso.interpreter.Language;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.dsl.MonadicState;
import org.enso.interpreter.node.callable.InvokeCallableNode;
Expand All @@ -29,13 +29,13 @@ public abstract class PrintlnNode extends Node {
InvokeCallableNode.ArgumentsExecutionMode.PRE_EXECUTED);

abstract Stateful execute(
VirtualFrame frame, @MonadicState Object state, Object _this, Object message);
VirtualFrame frame, @MonadicState Object state, Object _this, @AcceptsError Object message);

@Specialization
Stateful doPrintText(
VirtualFrame frame,
Object state,
Object self,
Object _this,
Text message,
@CachedContext(Language.class) Context ctx,
@Cached("build()") ToJavaStringNode toJavaStringNode) {
Expand All @@ -47,7 +47,7 @@ Stateful doPrintText(
Stateful doPrint(
VirtualFrame frame,
Object state,
Object self,
Object _this,
Object message,
@CachedContext(Language.class) Context ctx,
@Cached("buildSymbol(ctx)") UnresolvedSymbol symbol,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.enso.interpreter.node.expression.builtin.meta;

import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.type.TypesGen;

Expand All @@ -9,7 +10,7 @@
name = "is_atom_constructor",
description = "Checks if the argument is a constructor.")
public class IsAtomConstructorNode extends Node {
boolean execute(Object _this, Object value) {
boolean execute(Object _this, @AcceptsError Object value) {
return TypesGen.isAtomConstructor(value);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.enso.interpreter.node.expression.builtin.meta;

import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Meta", name = "is_atom", description = "Checks if the argument is an atom")
public class IsAtomNode extends Node {
boolean execute(Object _this, Object value) {
boolean execute(Object _this, @AcceptsError Object value) {
return TypesGen.isAtom(value);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.enso.interpreter.node.expression.builtin.meta;

import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.type.TypesGen;

Expand All @@ -9,7 +10,7 @@
name = "is_error",
description = "Checks if the argument is an error.")
public class IsErrorNode extends Node {
boolean execute(Object _this, Object value) {
boolean execute(Object _this, @AcceptsError Object value) {
return TypesGen.isDataflowError(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.Language;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.Context;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(
type = "Meta",
Expand All @@ -17,7 +17,7 @@ static IsPolyglotNode build() {
return IsPolyglotNodeGen.create();
}

abstract boolean execute(Object _this, Object value);
abstract boolean execute(Object _this, @AcceptsError Object value);

@Specialization
boolean doExecute(Object _this, Object value, @CachedContext(Language.class) Context context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.enso.interpreter.node.expression.builtin.meta;

import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(
type = "Meta",
name = "is_same_object",
description = "Checks if the two arguments share an underlying reference.")
public class IsSameObjectNode extends Node {
boolean execute(Object _this, Object value_1, Object value_2) {
boolean execute(Object _this, @AcceptsError Object value_1, @AcceptsError Object value_2) {
return value_1 == value_2;
}
}
Loading