diff --git a/engine/runtime-compiler/src/main/java/org/enso/compiler/context/NameResolutionAlgorithm.java b/engine/runtime-compiler/src/main/java/org/enso/compiler/context/NameResolutionAlgorithm.java
index 7321924e544b..dc62bdd49758 100644
--- a/engine/runtime-compiler/src/main/java/org/enso/compiler/context/NameResolutionAlgorithm.java
+++ b/engine/runtime-compiler/src/main/java/org/enso/compiler/context/NameResolutionAlgorithm.java
@@ -2,10 +2,8 @@
import org.enso.compiler.MetadataInteropHelpers;
import org.enso.compiler.core.ConstantsNames;
-import org.enso.compiler.core.ir.Name;
+import org.enso.compiler.core.ir.Name.Literal;
import org.enso.compiler.data.BindingsMap;
-import org.enso.compiler.pass.analyse.AliasAnalysis$;
-import org.enso.compiler.pass.analyse.alias.AliasMetadata;
import org.enso.compiler.pass.resolve.GlobalNames$;
import scala.Option;
@@ -15,7 +13,8 @@
*
The same logic is needed in two places:
*
*
- * - in the runtime ({@link org.enso.interpreter.runtime.IrToTruffle.ExpressionProcessor#processName}),
+ *
- in the runtime ({@link
+ * org.enso.interpreter.runtime.IrToTruffle.ExpressionProcessor#processName}),
*
- in the type checker ({@link
* org.enso.compiler.pass.analyse.types.TypePropagation#processName}).
*
@@ -27,15 +26,23 @@
* @param The type describing a link to a local name in a current scope.
* Depending on the context this may be a Graph.Link (in the compiler) or a FramePointer (in the
* runtime).
+ * @param Type of the metadata that is associated with the name IR that is resolved.
*/
-public abstract class NameResolutionAlgorithm {
- public final ResultType resolveName(Name.Literal name) {
- AliasMetadata.Occurrence occurrenceMetadata =
- MetadataInteropHelpers.getMetadata(
- name, AliasAnalysis$.MODULE$, AliasMetadata.Occurrence.class);
- var maybeLocalLink = findLocalLink(occurrenceMetadata);
- if (maybeLocalLink.isDefined()) {
- return resolveLocalName(maybeLocalLink.get());
+public abstract class NameResolutionAlgorithm {
+
+ /**
+ * Resolves a name to {@code ResultType}.
+ *
+ * @param name literal name to be resolved
+ * @param meta Nullable metadata gathered from the {@code name} IR.
+ * @return The result of the resolution process.
+ */
+ public final ResultType resolveName(Literal name, MetadataType meta) {
+ if (meta != null) {
+ var maybeLocalLink = findLocalLink(meta);
+ if (maybeLocalLink.isDefined()) {
+ return resolveLocalName(maybeLocalLink.get());
+ }
}
BindingsMap.Resolution global =
@@ -53,8 +60,13 @@ public final ResultType resolveName(Name.Literal name) {
return resolveUnresolvedSymbol(name.name());
}
- protected abstract Option findLocalLink(
- AliasMetadata.Occurrence occurrenceMetadata);
+ /**
+ * Finds a local link in the current scope from the given {@code metadata}.
+ *
+ * @param metadata Not null.
+ * @return The local link if found, {@code None} otherwise.
+ */
+ protected abstract Option findLocalLink(MetadataType metadata);
protected abstract ResultType resolveLocalName(LocalNameLinkType localLink);
diff --git a/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/types/TypePropagation.java b/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/types/TypePropagation.java
index d9c3493216ee..27f254c31679 100644
--- a/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/types/TypePropagation.java
+++ b/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/types/TypePropagation.java
@@ -4,6 +4,7 @@
import static org.enso.compiler.MetadataInteropHelpers.getMetadataOrNull;
import java.util.List;
+import org.enso.compiler.MetadataInteropHelpers;
import org.enso.compiler.context.NameResolutionAlgorithm;
import org.enso.compiler.core.CompilerError;
import org.enso.compiler.core.IR;
@@ -159,7 +160,10 @@ private TypeRepresentation processCaseExpression(
private TypeRepresentation processName(
Name.Literal literalName, LocalBindingsTyping localBindingsTyping) {
var resolver = new CompilerNameResolution(localBindingsTyping);
- return resolver.resolveName(literalName);
+ var occMeta =
+ MetadataInteropHelpers.getMetadataOrNull(
+ literalName, AliasAnalysis$.MODULE$, AliasMetadata.Occurrence.class);
+ return resolver.resolveName(literalName, occMeta);
}
private TypeRepresentation processLiteral(Literal literal) {
@@ -333,7 +337,8 @@ private TypeRepresentation processUnresolvedSymbolApplication(
}
private class CompilerNameResolution
- extends NameResolutionAlgorithm {
+ extends NameResolutionAlgorithm<
+ TypeRepresentation, CompilerNameResolution.LinkInfo, AliasMetadata.Occurrence> {
private final LocalBindingsTyping localBindingsTyping;
private CompilerNameResolution(LocalBindingsTyping localBindingsTyping) {
diff --git a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
index 7f0861e69b45..1822ba2b1550 100644
--- a/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
+++ b/engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
@@ -388,6 +388,10 @@ case object FramePointerAnalysis extends IRPass {
) extends IRMetadata {
override val metadataName: String = "FramePointer"
+ def parentLevel(): Int = framePointer.parentLevel
+
+ def frameSlotIdx(): Int = framePointer.frameSlotIdx
+
/** @inheritdoc
*/
override def duplicate(): Option[Metadata] = {
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 9bd5ea3aba5a..944c51849019 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
@@ -51,6 +51,7 @@ import org.enso.compiler.pass.analyse.{
AliasAnalysis,
BindingAnalysis,
DataflowAnalysis,
+ FramePointerAnalysis,
TailCall
}
import org.enso.compiler.pass.analyse.alias.AliasMetadata
@@ -302,13 +303,12 @@ class IrToTruffle(
val unprocessedArg = atomDefn.arguments(idx)
val checkNode = checkAsTypes(unprocessedArg)
val arg = argFactory.run(unprocessedArg, idx, checkNode)
- val occInfo = unprocessedArg
+ val fp = unprocessedArg
.unsafeGetMetadata(
- AliasAnalysis,
- "No occurrence on an argument definition."
+ FramePointerAnalysis,
+ "No frame pointer on an argument definition."
)
- .unsafeAs[alias.AliasMetadata.Occurrence]
- val slotIdx = localScope.getVarSlotIdx(occInfo.id)
+ val slotIdx = fp.frameSlotIdx()
argDefs(idx) = arg
val readArg =
ReadArgumentNode.build(
@@ -1823,17 +1823,14 @@ class IrToTruffle(
private def processBinding(
binding: Expression.Binding
): RuntimeExpression = {
- val occInfo = binding
+ val fp = binding
.unsafeGetMetadata(
- AliasAnalysis,
- "Binding with missing occurrence information."
+ FramePointerAnalysis,
+ "Binding with missing frame pointer."
)
- .unsafeAs[AliasMetadata.Occurrence]
currentVarName = binding.name.name
-
- val slotIdx = scope.getVarSlotIdx(occInfo.id)
-
+ val slotIdx = fp.frameSlotIdx()
setLocation(
AssignmentNode.build(this.run(binding.expression, true, true), slotIdx),
binding.location
@@ -1889,7 +1886,11 @@ class IrToTruffle(
val nameExpr = name match {
case literalName: Name.Literal =>
val resolver = new RuntimeNameResolution()
- resolver.resolveName(literalName)
+ val fpMeta = literalName.passData.get(FramePointerAnalysis) match {
+ case Some(meta: FramePointerAnalysis.FramePointerMeta) => meta
+ case _ => null
+ }
+ resolver.resolveName(literalName, fpMeta)
case Name.MethodReference(
None,
Name.Literal(nameStr, _, _, _, _, _),
@@ -1945,11 +1946,22 @@ class IrToTruffle(
}
private class RuntimeNameResolution
- extends NameResolutionAlgorithm[RuntimeExpression, FramePointer] {
+ extends NameResolutionAlgorithm[
+ RuntimeExpression,
+ FramePointer,
+ FramePointerAnalysis.FramePointerMeta
+ ] {
override protected def findLocalLink(
- occurrenceMetadata: org.enso.compiler.pass.analyse.alias.AliasMetadata.Occurrence
- ): Option[FramePointer] =
- scope.getFramePointer(occurrenceMetadata.id)
+ fpMeta: FramePointerAnalysis.FramePointerMeta
+ ): Option[FramePointer] = {
+ if (scope.flattenToParent && fpMeta.parentLevel() > 0) {
+ Some(
+ new FramePointer(fpMeta.parentLevel() - 1, fpMeta.frameSlotIdx())
+ )
+ } else {
+ Some(fpMeta.framePointer)
+ }
+ }
override protected def resolveLocalName(
localLink: FramePointer
@@ -2191,14 +2203,12 @@ class IrToTruffle(
val checkNode = checkAsTypes(unprocessedArg)
val arg = argFactory.run(unprocessedArg, idx, checkNode)
argDefinitions(idx) = arg
- val occInfo = unprocessedArg
+ val fp = unprocessedArg
.unsafeGetMetadata(
- AliasAnalysis,
- "No occurrence on an argument definition."
+ FramePointerAnalysis,
+ "No frame pointer on an argument definition."
)
- .unsafeAs[AliasMetadata.Occurrence]
-
- val slotIdx = scope.getVarSlotIdx(occInfo.id)
+ val slotIdx = fp.frameSlotIdx()
val readArg =
ReadArgumentNode.build(
idx,