From 2864de82f9da928f86492c86fefe7dbb0dc90797 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sun, 20 Oct 2024 10:38:58 +0200 Subject: [PATCH] Lazily instantiate functions representing branches --- .../interpreter/node/ClosureRootNode.java | 7 +++--- .../enso/interpreter/node/MethodRootNode.java | 3 ++- .../node/expression/debug/EvalNode.java | 24 +++++++++++++------ .../callable/UnresolvedConstructor.java | 9 ++++++- .../interpreter/runtime/IrToTruffle.scala | 22 ++++++++--------- 5 files changed, 42 insertions(+), 23 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/ClosureRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/ClosureRootNode.java index f2ac6c9653fb..0c81ccf7a2a6 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/ClosureRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/ClosureRootNode.java @@ -5,6 +5,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; +import java.util.function.Supplier; import org.enso.compiler.context.LocalScope; import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.runtime.scope.ModuleScope; @@ -44,7 +45,7 @@ public class ClosureRootNode extends EnsoRootNode { * @param language the language identifier * @param localScope a description of the local scope * @param moduleScope a description of the module scope - * @param body the program body to be executed + * @param body supplier of the program body to be executed * @param section a mapping from {@code body} to the program source * @param name a name for the node * @param subjectToInstrumentation shall this node be instrumented @@ -55,7 +56,7 @@ public static ClosureRootNode build( EnsoLanguage language, LocalScope localScope, ModuleScope moduleScope, - ExpressionNode body, + Supplier body, SourceSection section, String name, Boolean subjectToInstrumentation, @@ -64,7 +65,7 @@ public static ClosureRootNode build( language, localScope, moduleScope, - body, + new MethodRootNode.LazyBodyNode(body), section, name, subjectToInstrumentation, diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/MethodRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/MethodRootNode.java index fa1517967415..5c2b8f8c491c 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/MethodRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/MethodRootNode.java @@ -187,7 +187,7 @@ public Node copy() { return super.copy(); } - private static class LazyBodyNode extends ExpressionNode { + static class LazyBodyNode extends ExpressionNode { private final Supplier provider; LazyBodyNode(Supplier body) { @@ -210,6 +210,7 @@ public Object executeGeneric(VirtualFrame frame) { final ExpressionNode replaceItself() { try { ExpressionNode newNode = replace(provider.get()); + System.err.println("Node inserted: " + newNode.getEncapsulatingSourceSection()); notifyInserted(newNode); return newNode; } catch (CompilerError abnormalException) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java index d4a8f180e6e0..646153836f96 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java @@ -87,15 +87,25 @@ RootCallTarget parseExpression(LocalScope scope, ModuleScope moduleScope, String var sco = newInlineContext.localScope().getOrElse(LocalScope::empty); var mod = newInlineContext.getModule(); var m = org.enso.interpreter.runtime.Module.fromCompilerModule(mod); - var toTruffle = new IrToTruffle(context, src, m.getScopeBuilder(), compiler.getConfig()); - var expr = toTruffle.runInline(ir, sco, ""); - - if (shouldCaptureResultScope) { - expr = CaptureResultScopeNode.build(expr); - } ClosureRootNode framedNode = ClosureRootNode.build( - context.getLanguage(), localScope, moduleScope, expr, null, "", false, false); + context.getLanguage(), + localScope, + moduleScope, + () -> { + var toTruffle = + new IrToTruffle(context, src, m.getScopeBuilder(), compiler.getConfig()); + var expr = toTruffle.runInline(ir, sco, ""); + + if (shouldCaptureResultScope) { + expr = CaptureResultScopeNode.build(expr); + } + return expr; + }, + null, + "", + false, + false); return framedNode.getCallTarget(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java index 1933cb9e2725..5df3ebb0137d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java @@ -207,7 +207,14 @@ static DirectCallNode buildApplication(UnresolvedConstructor prototype) { body.adoptChildren(); var root = ClosureRootNode.build( - lang, LocalScope.empty(), scope, body, section, prototype.getName(), true, true); + lang, + LocalScope.empty(), + scope, + () -> body, + section, + prototype.getName(), + true, + true); root.adoptChildren(); assert Objects.equals(expr.getSourceSection(), section) : "Expr: " + expr.getSourceSection() + " orig: " + section; diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala b/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala index f2d24d34da3d..6a0296ccff7d 100644 --- a/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala +++ b/engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala @@ -336,14 +336,14 @@ class IrToTruffle( atomDefn.name.name, frameInfo ) - val expressionNode = + def expressionNode = expressionProcessor.run(annotation.expression, true) val closureName = s"" val closureRootNode = ClosureRootNode.build( language, expressionProcessor.scope, scopeBuilder.asModuleScope(), - expressionNode, + () => expressionNode, makeSection(scopeBuilder.getModule, annotation.location), closureName, true, @@ -572,7 +572,7 @@ class IrToTruffle( methodDef.methodName.name, frameInfo ) - val expressionNode = + def expressionNode = expressionProcessor.run(annotation.expression, true) val closureName = s"" @@ -580,7 +580,7 @@ class IrToTruffle( language, expressionProcessor.scope, scopeBuilder.asModuleScope(), - expressionNode, + () => expressionNode, makeSection( scopeBuilder.getModule, annotation.location @@ -1384,13 +1384,13 @@ class IrToTruffle( ) val childScope = childFactory.scope - val blockNode = childFactory.processBlock(block.copy(suspended = false)) + def blockNode = childFactory.processBlock(block.copy(suspended = false)) val defaultRootNode = ClosureRootNode.build( language, childScope, scopeBuilder.asModuleScope(), - blockNode, + () => blockNode, makeSection(scopeBuilder.getModule, block.location), currentVarName, false, @@ -2325,7 +2325,7 @@ class IrToTruffle( language, scope, scopeBuilder.asModuleScope(), - bodyBuilder.bodyNode(), + () => bodyBuilder.bodyNode(), makeSection(scopeBuilder.getModule, location), scopeName, false, @@ -2501,7 +2501,7 @@ class IrToTruffle( // Note [Scope Flattening] scope.createChild(() => scopeInfo().scope, flattenToParent = true) } - val argumentExpression = + def argumentExpression = new ExpressionProcessor(childScope, scopeName, initialName) .run(value, subjectToInstrumentation) @@ -2521,7 +2521,7 @@ class IrToTruffle( language, childScope, scopeBuilder.asModuleScope(), - argumentExpression, + () => argumentExpression, section, displayName, subjectToInstrumentation, @@ -2593,7 +2593,7 @@ class IrToTruffle( ): ArgumentDefinition = inputArg match { case arg: DefinitionArgument.Specified => - val defaultExpression = arg.defaultValue + def defaultExpression = arg.defaultValue .map( new ExpressionProcessor(scope, scopeName, initialName) .run(_, false) @@ -2607,7 +2607,7 @@ class IrToTruffle( language, scope, scopeBuilder.asModuleScope(), - defaultExpression, + () => defaultExpression, makeSection( scopeBuilder.getModule, arg.defaultValue.get.location()