Skip to content

Commit

Permalink
Keep and rethrow suspended exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Apr 5, 2023
1 parent 160068a commit cad4e8e
Showing 1 changed file with 24 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.enso.interpreter.runtime.callable.atom.unboxing;

import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.callable.InvokeCallableNode;
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
Expand All @@ -9,7 +11,8 @@
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.state.State;

/** Getter node that reads a field value. If the value is a thunk the node
/**
* Getter node that reads a field value. If the value is a thunk the node
* evaluates it and replaces the original lazy value with the new value.
*
*/
Expand All @@ -20,7 +23,7 @@ final class SuspendedFieldGetterNode extends UnboxingAtom.FieldGetterNode {
private UnboxingAtom.FieldGetterNode get;
@Node.Child
private InvokeFunctionNode invoke = InvokeFunctionNode.build(
new CallArgumentInfo[0], InvokeCallableNode.DefaultsExecutionMode.EXECUTE, InvokeCallableNode.ArgumentsExecutionMode.EXECUTE
new CallArgumentInfo[0], InvokeCallableNode.DefaultsExecutionMode.EXECUTE, InvokeCallableNode.ArgumentsExecutionMode.EXECUTE
);

private SuspendedFieldGetterNode(UnboxingAtom.FieldGetterNode get, UnboxingAtom.FieldSetterNode set) {
Expand All @@ -36,13 +39,28 @@ static UnboxingAtom.FieldGetterNode build(UnboxingAtom.FieldGetterNode get, Unbo
public Object execute(Atom atom) {
java.lang.Object value = get.execute(atom);
if (value instanceof Function fn && fn.isThunk()) {
org.enso.interpreter.runtime.EnsoContext ctx = EnsoContext.get(this);
java.lang.Object newValue = invoke.execute(fn, null, State.create(ctx), new Object[0]);
set.execute(atom, newValue);
return newValue;
try {
org.enso.interpreter.runtime.EnsoContext ctx = EnsoContext.get(this);
java.lang.Object newValue = invoke.execute(fn, null, State.create(ctx), new Object[0]);
set.execute(atom, newValue);
return newValue;
} catch (AbstractTruffleException ex) {
var rethrow = new SuspendedException(ex);
set.execute(atom, rethrow);
throw ex;
}
} else if (value instanceof SuspendedException suspended) {
throw suspended.ex;
} else {
return value;
}
}

private static final class SuspendedException implements TruffleObject {
final AbstractTruffleException ex;

SuspendedException(AbstractTruffleException ex) {
this.ex = ex;
}
}
}

0 comments on commit cad4e8e

Please sign in to comment.