-
Notifications
You must be signed in to change notification settings - Fork 319
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Suspended atom fields are evaluated only once (#6151)
Implements #6134. # Important Notes One can define lazy atom fields as: ```haskell type Lazy Value ~x ~y ``` the evaluation of the `x` and `y` fields is then delayed until they are needed. The evaluation happens once. Then the computed value is kept in the atom for further use.
- Loading branch information
1 parent
4805193
commit 741b394
Showing
9 changed files
with
274 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 0 additions & 80 deletions
80
distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/Lazy.enso
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
...in/java/org/enso/interpreter/runtime/callable/atom/unboxing/SuspendedFieldGetterNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
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; | ||
import org.enso.interpreter.runtime.EnsoContext; | ||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo; | ||
import org.enso.interpreter.runtime.callable.atom.Atom; | ||
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 | ||
* evaluates it and replaces the original lazy value with the new value. | ||
*/ | ||
final class SuspendedFieldGetterNode extends UnboxingAtom.FieldGetterNode { | ||
@Node.Child | ||
private UnboxingAtom.FieldSetterNode set; | ||
@Node.Child | ||
private UnboxingAtom.FieldGetterNode get; | ||
@Node.Child | ||
private InvokeFunctionNode invoke = InvokeFunctionNode.build( | ||
new CallArgumentInfo[0], InvokeCallableNode.DefaultsExecutionMode.EXECUTE, InvokeCallableNode.ArgumentsExecutionMode.EXECUTE | ||
); | ||
|
||
private SuspendedFieldGetterNode(UnboxingAtom.FieldGetterNode get, UnboxingAtom.FieldSetterNode set) { | ||
this.get = get; | ||
this.set = set; | ||
} | ||
|
||
static UnboxingAtom.FieldGetterNode build(UnboxingAtom.FieldGetterNode get, UnboxingAtom.FieldSetterNode set) { | ||
return new SuspendedFieldGetterNode(get, set); | ||
} | ||
|
||
@Override | ||
public Object execute(Atom atom) { | ||
java.lang.Object value = get.execute(atom); | ||
if (value instanceof Function fn && fn.isThunk()) { | ||
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; | ||
} | ||
} | ||
} |
Oops, something went wrong.