Avoid long existing ModuleScope.Builder

This commit is contained in:
Jaroslav Tulach 2024-06-10 22:04:56 +02:00
parent f12e985b3a
commit b4aaa51676
11 changed files with 274 additions and 180 deletions

View File

@ -264,12 +264,8 @@ public final class EnsoLanguage extends TruffleLanguage<EnsoContext> {
var mod = newInlineContext.getModule(); var mod = newInlineContext.getModule();
var m = org.enso.interpreter.runtime.Module.fromCompilerModule(mod); var m = org.enso.interpreter.runtime.Module.fromCompilerModule(mod);
var toTruffle = var toTruffle =
new IrToTruffle( new IrToTruffle(context, request.getSource(), m, redirectConfigWithStrictErrors);
context, exprNode = toTruffle.runInline(m.getScope(), ir, sco, "<inline_source>");
request.getSource(),
m.getScopeBuilder(),
redirectConfigWithStrictErrors);
exprNode = toTruffle.runInline(ir, sco, "<inline_source>");
} else { } else {
exprNode = null; exprNode = null;
} }

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition; import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.AtomConstructor; import org.enso.interpreter.runtime.data.atom.AtomConstructor;
@ -18,8 +19,10 @@ public abstract class Builtin {
this(name, Arrays.asList(params)); this(name, Arrays.asList(params));
} }
private AtomConstructor build(EnsoLanguage language, ModuleScope.Builder scope, Type type) { private AtomConstructor build(
var res = new AtomConstructor(name, scope.getModule(), type, true); EnsoLanguage language, ModuleScope.Builder builder, ModuleScope scope, Type type) {
var res = new AtomConstructor(name, builder.getModule(), type, true);
res.initializeBuilder(language, builder);
res.initializeFields( res.initializeFields(
language, language,
scope, scope,
@ -52,30 +55,33 @@ public abstract class Builtin {
public final void initialize( public final void initialize(
EnsoLanguage language, EnsoLanguage language,
ModuleScope.Builder scope, Module module,
ModuleScope.Builder builder,
ModuleScope scope,
Map<Class<? extends Builtin>, Builtin> builtins) { Map<Class<? extends Builtin>, Builtin> builtins) {
if (type == null) { if (type == null) {
Type supertype = null; Type supertype = null;
if (getSuperType() != null) { if (getSuperType() != null) {
var s = builtins.get(getSuperType()); var s = builtins.get(getSuperType());
s.initialize(language, scope, builtins); s.initialize(language, module, builder, scope, builtins);
supertype = s.getType(); supertype = s.getType();
} }
type = type =
containsValues() containsValues()
? Type.create(name, scope, supertype, builtins.get(Any.class).getType(), true, false) ? Type.create(
: Type.createSingleton(name, scope, supertype, true, false); name, module, builder, supertype, builtins.get(Any.class).getType(), true, false)
: Type.createSingleton(name, module, supertype, true, false);
} }
if (constructors == null) { if (constructors == null) {
var conses = getDeclaredConstructors(); var conses = getDeclaredConstructors();
constructors = new AtomConstructor[conses.size()]; constructors = new AtomConstructor[conses.size()];
for (int i = 0; i < constructors.length; i++) { for (int i = 0; i < constructors.length; i++) {
var cons = conses.get(i).build(language, scope, type); var cons = conses.get(i).build(language, builder, scope, type);
constructors[i] = cons; constructors[i] = cons;
type.registerConstructor(cons); type.registerConstructor(cons);
} }
} }
type.generateGetters(language); type.generateGetters(builder, language);
postInitialize(); postInitialize();
} }

View File

@ -86,8 +86,8 @@ public abstract class EvalNode extends BaseNode {
var sco = newInlineContext.localScope().getOrElse(LocalScope::root); var sco = newInlineContext.localScope().getOrElse(LocalScope::root);
var mod = newInlineContext.getModule(); var mod = newInlineContext.getModule();
var m = org.enso.interpreter.runtime.Module.fromCompilerModule(mod); var m = org.enso.interpreter.runtime.Module.fromCompilerModule(mod);
var toTruffle = new IrToTruffle(context, src, m.getScopeBuilder(), compiler.getConfig()); var toTruffle = new IrToTruffle(context, src, m, compiler.getConfig());
var expr = toTruffle.runInline(ir, sco, "<inline_source>"); var expr = toTruffle.runInline(m.getScope(), ir, sco, "<inline_source>");
if (shouldCaptureResultScope) { if (shouldCaptureResultScope) {
expr = CaptureResultScopeNode.build(expr); expr = CaptureResultScopeNode.build(expr);

View File

@ -55,7 +55,7 @@ import org.enso.text.buffer.Rope;
public final class Module implements EnsoObject { public final class Module implements EnsoObject {
private ModuleSources sources; private ModuleSources sources;
private QualifiedName name; private QualifiedName name;
private ModuleScope.Builder scopeBuilder; private ModuleScope moduleScope;
private final Package<TruffleFile> pkg; private final Package<TruffleFile> pkg;
private final Cache<ModuleCache.CachedModule, ModuleCache.Metadata> cache; private final Cache<ModuleCache.CachedModule, ModuleCache.Metadata> cache;
private boolean wasLoadedFromCache; private boolean wasLoadedFromCache;
@ -87,7 +87,7 @@ public final class Module implements EnsoObject {
public Module(QualifiedName name, Package<TruffleFile> pkg, TruffleFile sourceFile) { public Module(QualifiedName name, Package<TruffleFile> pkg, TruffleFile sourceFile) {
this.sources = ModuleSources.NONE.newWith(sourceFile); this.sources = ModuleSources.NONE.newWith(sourceFile);
this.name = name; this.name = name;
this.scopeBuilder = new ModuleScope.Builder(this); this.moduleScope = new ModuleScope.Builder(this).build();
this.pkg = pkg; this.pkg = pkg;
this.cache = ModuleCache.create(this); this.cache = ModuleCache.create(this);
this.wasLoadedFromCache = false; this.wasLoadedFromCache = false;
@ -105,7 +105,7 @@ public final class Module implements EnsoObject {
public Module(QualifiedName name, Package<TruffleFile> pkg, String literalSource) { public Module(QualifiedName name, Package<TruffleFile> pkg, String literalSource) {
this.sources = ModuleSources.NONE.newWith(Rope.apply(literalSource)); this.sources = ModuleSources.NONE.newWith(Rope.apply(literalSource));
this.name = name; this.name = name;
this.scopeBuilder = new ModuleScope.Builder(this); this.moduleScope = new ModuleScope.Builder(this).build();
this.pkg = pkg; this.pkg = pkg;
this.cache = ModuleCache.create(this); this.cache = ModuleCache.create(this);
this.wasLoadedFromCache = false; this.wasLoadedFromCache = false;
@ -124,7 +124,7 @@ public final class Module implements EnsoObject {
public Module(QualifiedName name, Package<TruffleFile> pkg, Rope literalSource) { public Module(QualifiedName name, Package<TruffleFile> pkg, Rope literalSource) {
this.sources = ModuleSources.NONE.newWith(literalSource); this.sources = ModuleSources.NONE.newWith(literalSource);
this.name = name; this.name = name;
this.scopeBuilder = new ModuleScope.Builder(this); this.moduleScope = new ModuleScope.Builder(this).build();
this.pkg = pkg; this.pkg = pkg;
this.cache = ModuleCache.create(this); this.cache = ModuleCache.create(this);
this.wasLoadedFromCache = false; this.wasLoadedFromCache = false;
@ -144,14 +144,13 @@ public final class Module implements EnsoObject {
this.sources = this.sources =
literalSource == null ? ModuleSources.NONE : ModuleSources.NONE.newWith(literalSource); literalSource == null ? ModuleSources.NONE : ModuleSources.NONE.newWith(literalSource);
this.name = name; this.name = name;
this.scopeBuilder = new ModuleScope.Builder(this); this.moduleScope = new ModuleScope.Builder(this).build();
this.pkg = pkg; this.pkg = pkg;
this.cache = ModuleCache.create(this); this.cache = ModuleCache.create(this);
this.wasLoadedFromCache = false; this.wasLoadedFromCache = false;
this.synthetic = synthetic; this.synthetic = synthetic;
if (synthetic) { if (synthetic) {
this.compilationStage = CompilationStage.INITIAL; this.compilationStage = CompilationStage.INITIAL;
scopeBuilder.build();
} else { } else {
this.compilationStage = CompilationStage.AFTER_CODEGEN; this.compilationStage = CompilationStage.AFTER_CODEGEN;
} }
@ -328,7 +327,7 @@ public final class Module implements EnsoObject {
} catch (IOException ignored) { } catch (IOException ignored) {
} }
} }
return scopeBuilder.build(); return moduleScope;
} }
/** /**
@ -386,7 +385,7 @@ public final class Module implements EnsoObject {
private void compile(EnsoContext context) throws IOException { private void compile(EnsoContext context) throws IOException {
Source source = getSource(); Source source = getSource();
if (source == null) return; if (source == null) return;
scopeBuilder = newScopeBuilder(false); moduleScope = newScopeBuilder(false).build();
compilationStage = CompilationStage.INITIAL; compilationStage = CompilationStage.INITIAL;
context.getCompiler().run(asCompilerModule()); context.getCompiler().run(asCompilerModule());
} }
@ -456,20 +455,14 @@ public final class Module implements EnsoObject {
* @return the runtime scope of this module. * @return the runtime scope of this module.
*/ */
public ModuleScope getScope() { public ModuleScope getScope() {
return scopeBuilder.asModuleScope(); return moduleScope;
}
public ModuleScope.Builder getScopeBuilder() {
return scopeBuilder;
} }
public ModuleScope.Builder newScopeBuilder(boolean inheritTypes) { public ModuleScope.Builder newScopeBuilder(boolean inheritTypes) {
if (inheritTypes) { var builder = // inheritTypes ?
this.scopeBuilder = this.scopeBuilder.newBuilderInheritingTypes(); // this.scopeBuilder.newBuilderInheritingTypes();
} else { new ModuleScope.Builder(this);
this.scopeBuilder = new ModuleScope.Builder(this); return builder;
}
return this.scopeBuilder;
} }
/** /**

View File

@ -146,7 +146,7 @@ final class TruffleCompilerContext implements CompilerContext {
var s = var s =
org.enso.interpreter.runtime.scope.ModuleScope.Builder.fromCompilerModuleScopeBuilder( org.enso.interpreter.runtime.scope.ModuleScope.Builder.fromCompilerModuleScopeBuilder(
scopeBuilder); scopeBuilder);
new IrToTruffle(context, m.getSource(), s, config).run(module.getIr()); new IrToTruffle(context, m.getSource(), m, config).run(module.getIr());
} }
// module related // module related
@ -823,7 +823,7 @@ final class TruffleCompilerContext implements CompilerContext {
@Override @Override
public CompilerContext.ModuleScopeBuilder getScopeBuilder() { public CompilerContext.ModuleScopeBuilder getScopeBuilder() {
return new org.enso.interpreter.runtime.scope.TruffleCompilerModuleScopeBuilder( return new org.enso.interpreter.runtime.scope.TruffleCompilerModuleScopeBuilder(
module.getScopeBuilder()); module.newScopeBuilder(true));
} }
@Override @Override

View File

@ -129,7 +129,9 @@ public final class Builtins {
module.compileScope(context); // Dummy compilation for an empty module module.compileScope(context); // Dummy compilation for an empty module
ModuleScope.Builder scopeBuilder = module.newScopeBuilder(false); ModuleScope.Builder scopeBuilder = module.newScopeBuilder(false);
builtins = initializeBuiltinTypes(loadedBuiltinConstructors, language, scopeBuilder); builtins =
initializeBuiltinTypes(
loadedBuiltinConstructors, language, scopeBuilder, null /* as no scope */);
builtinsByName = builtinsByName =
builtins.values().stream() builtins.values().stream()
.collect( .collect(
@ -239,7 +241,7 @@ public final class Builtins {
} }
String builtinMethodOwner = builtinName[0]; String builtinMethodOwner = builtinName[0];
String builtinMethodName = builtinName[1]; String builtinMethodName = builtinName[1];
Optional.ofNullable(scope.asModuleScope().getType(builtinMethodOwner, true)) Optional.ofNullable(scope.getType(builtinMethodOwner, true))
.ifPresentOrElse( .ifPresentOrElse(
constr -> { constr -> {
Map<String, Supplier<LoadedBuiltinMethod>> atomNodes = Map<String, Supplier<LoadedBuiltinMethod>> atomNodes =
@ -375,11 +377,12 @@ public final class Builtins {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/** Initialize builting types in the context of the given language and module scope */ /** Initialize builting types in the context of the given language and module builder */
private Map<Class<? extends Builtin>, Builtin> initializeBuiltinTypes( private Map<Class<? extends Builtin>, Builtin> initializeBuiltinTypes(
List<Constructor<? extends Builtin>> constrs, List<Constructor<? extends Builtin>> constrs,
EnsoLanguage language, EnsoLanguage language,
ModuleScope.Builder scope) { ModuleScope.Builder builder,
ModuleScope scope) {
Map<Class<? extends Builtin>, Builtin> builtins = new HashMap<>(); Map<Class<? extends Builtin>, Builtin> builtins = new HashMap<>();
for (var constr : constrs) { for (var constr : constrs) {
@ -391,7 +394,7 @@ public final class Builtins {
} }
} }
for (var b : builtins.values()) { for (var b : builtins.values()) {
b.initialize(language, scope, builtins); b.initialize(language, getModule(), builder, scope, builtins);
} }
return builtins; return builtins;
} }
@ -400,11 +403,11 @@ public final class Builtins {
* Returns a map of Builtin methods associated with their owner. * Returns a map of Builtin methods associated with their owner.
* *
* @param classes a map of (already loaded) builtin methods * @param classes a map of (already loaded) builtin methods
* @param scope Builtins scope * @param builder Builtins builder
* @return A map of builtin method nodes per builtin type name * @return A map of builtin method nodes per builtin type name
*/ */
private Map<String, Map<String, Supplier<LoadedBuiltinMethod>>> readBuiltinMethodsMetadata( private Map<String, Map<String, Supplier<LoadedBuiltinMethod>>> readBuiltinMethodsMetadata(
Map<String, LoadedBuiltinMethod> classes, ModuleScope.Builder scope) { Map<String, LoadedBuiltinMethod> classes, ModuleScope.Builder builder) {
Map<String, Map<String, Supplier<LoadedBuiltinMethod>>> methodNodes = new HashMap<>(); Map<String, Map<String, Supplier<LoadedBuiltinMethod>>> methodNodes = new HashMap<>();
classes.forEach( classes.forEach(
@ -415,7 +418,7 @@ public final class Builtins {
} }
String builtinMethodOwner = builtinName[0]; String builtinMethodOwner = builtinName[0];
String builtinMethodName = builtinName[1]; String builtinMethodName = builtinName[1];
Optional.ofNullable(scope.asModuleScope().getType(builtinMethodOwner, true)) Optional.ofNullable(builder.getType(builtinMethodOwner, true))
.ifPresentOrElse( .ifPresentOrElse(
constr -> { constr -> {
Map<String, Supplier<LoadedBuiltinMethod>> atomNodes = Map<String, Supplier<LoadedBuiltinMethod>> atomNodes =

View File

@ -16,6 +16,7 @@ import org.enso.interpreter.Constants;
import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.node.ConstantNode; import org.enso.interpreter.node.ConstantNode;
import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition; import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.function.Function; import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema; import org.enso.interpreter.runtime.callable.function.FunctionSchema;
@ -30,7 +31,7 @@ import org.enso.pkg.QualifiedName;
public final class Type implements EnsoObject { public final class Type implements EnsoObject {
private final String name; private final String name;
private @CompilerDirectives.CompilationFinal ModuleScope.Builder definitionScope; private final Module definingModule;
private final boolean builtin; private final boolean builtin;
private final Type supertype; private final Type supertype;
private final Type eigentype; private final Type eigentype;
@ -41,13 +42,13 @@ public final class Type implements EnsoObject {
private Type( private Type(
String name, String name,
ModuleScope.Builder definitionScope, Module definingModule,
Type supertype, Type supertype,
Type eigentype, Type eigentype,
boolean builtin, boolean builtin,
boolean isProjectPrivate) { boolean isProjectPrivate) {
this.name = name; this.name = name;
this.definitionScope = definitionScope; this.definingModule = definingModule;
this.supertype = supertype; this.supertype = supertype;
this.builtin = builtin; this.builtin = builtin;
this.isProjectPrivate = isProjectPrivate; this.isProjectPrivate = isProjectPrivate;
@ -57,23 +58,24 @@ public final class Type implements EnsoObject {
public static Type createSingleton( public static Type createSingleton(
String name, String name,
ModuleScope.Builder definitionScope, Module definingModule,
Type supertype, Type supertype,
boolean builtin, boolean builtin,
boolean isProjectPrivate) { boolean isProjectPrivate) {
return new Type(name, definitionScope, supertype, null, builtin, isProjectPrivate); return new Type(name, definingModule, supertype, null, builtin, isProjectPrivate);
} }
public static Type create( public static Type create(
String name, String name,
ModuleScope.Builder definitionScope, Module definingModule,
ModuleScope.Builder builder,
Type supertype, Type supertype,
Type any, Type any,
boolean builtin, boolean builtin,
boolean isProjectPrivate) { boolean isProjectPrivate) {
var eigentype = new Type(name + ".type", definitionScope, any, null, builtin, isProjectPrivate); var eigentype = new Type(name + ".type", definingModule, any, null, builtin, isProjectPrivate);
var result = new Type(name, definitionScope, supertype, eigentype, builtin, isProjectPrivate); var result = new Type(name, definingModule, supertype, eigentype, builtin, isProjectPrivate);
result.generateQualifiedAccessor(); result.generateQualifiedAccessor(builder);
return result; return result;
} }
@ -81,7 +83,7 @@ public final class Type implements EnsoObject {
return new Type("null", null, null, null, false, false); return new Type("null", null, null, null, false, false);
} }
private void generateQualifiedAccessor() { private void generateQualifiedAccessor(ModuleScope.Builder builder) {
var node = new ConstantNode(null, this); var node = new ConstantNode(null, this);
var schemaBldr = var schemaBldr =
FunctionSchema.newBuilder() FunctionSchema.newBuilder()
@ -92,29 +94,27 @@ public final class Type implements EnsoObject {
schemaBldr.projectPrivate(); schemaBldr.projectPrivate();
} }
var function = new Function(node.getCallTarget(), null, schemaBldr.build()); var function = new Function(node.getCallTarget(), null, schemaBldr.build());
definitionScope.registerMethod( builder.registerMethod(null /* as builder.getAssociatedType() */, this.name, function);
definitionScope.asModuleScope().getAssociatedType(), this.name, function);
} }
public QualifiedName getQualifiedName() { public QualifiedName getQualifiedName() {
if (this == this.getDefinitionScope().getAssociatedType()) { if (this == this.getDefinitionScope().getAssociatedType()) {
return definitionScope.getModule().getName(); return definingModule.getName();
} else { } else {
return definitionScope.getModule().getName().createChild(getName()); return definingModule.getName().createChild(getName());
} }
} }
public void setShadowDefinitions(ModuleScope.Builder scope, boolean generateAccessorsInTarget) { public void setShadowDefinitions(ModuleScope.Builder builder, boolean generateAccessorsInTarget) {
if (builtin) { if (builtin) {
// Ensure that synthetic methods, such as getters for fields are in the scope. // Ensure that synthetic methods, such as getters for fields are in the builder.
CompilerAsserts.neverPartOfCompilation(); CompilerAsserts.neverPartOfCompilation();
this.definitionScope.registerAllMethodsOfTypeToScope(this, scope); this.definingModule.getScope().registerAllMethodsOfTypeToScope(this, builder);
this.definitionScope = scope;
if (generateAccessorsInTarget) { if (generateAccessorsInTarget) {
generateQualifiedAccessor(); generateQualifiedAccessor(builder);
} }
if (getEigentype() != this) { if (getEigentype() != this) {
getEigentype().setShadowDefinitions(scope, false); getEigentype().setShadowDefinitions(builder, false);
} }
} else { } else {
throw new RuntimeException( throw new RuntimeException(
@ -127,7 +127,7 @@ public final class Type implements EnsoObject {
} }
public ModuleScope getDefinitionScope() { public ModuleScope getDefinitionScope() {
return definitionScope.asModuleScope(); return definingModule.getScope();
} }
public boolean isBuiltin() { public boolean isBuiltin() {
@ -174,7 +174,7 @@ public final class Type implements EnsoObject {
return allTypes; return allTypes;
} }
public void generateGetters(EnsoLanguage language) { public void generateGetters(ModuleScope.Builder builder, EnsoLanguage language) {
if (gettersGenerated) return; if (gettersGenerated) return;
gettersGenerated = true; gettersGenerated = true;
var roots = AtomConstructor.collectFieldAccessors(language, this); var roots = AtomConstructor.collectFieldAccessors(language, this);
@ -194,7 +194,7 @@ public final class Type implements EnsoObject {
} }
var funcSchema = schemaBldr.build(); var funcSchema = schemaBldr.build();
var f = new Function(node.getCallTarget(), null, funcSchema); var f = new Function(node.getCallTarget(), null, funcSchema);
definitionScope.registerMethod(this, name, f); builder.registerMethod(this, name, f);
}); });
} }

View File

@ -104,7 +104,7 @@ public final class AtomConstructor implements EnsoObject {
* @return {@code this}, for convenience * @return {@code this}, for convenience
*/ */
public AtomConstructor initializeFields( public AtomConstructor initializeFields(
EnsoLanguage language, ModuleScope.Builder scopeBuilder, ArgumentDefinition... args) { EnsoLanguage language, ModuleScope scope, ArgumentDefinition... args) {
ExpressionNode[] reads = new ExpressionNode[args.length]; ExpressionNode[] reads = new ExpressionNode[args.length];
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
reads[i] = ReadArgumentNode.build(i, null, null); reads[i] = ReadArgumentNode.build(i, null, null);
@ -113,13 +113,25 @@ public final class AtomConstructor implements EnsoObject {
language, language,
null, null,
LocalScope.root(), LocalScope.root(),
scopeBuilder, scope,
new ExpressionNode[0], new ExpressionNode[0],
reads, reads,
new Annotation[0], new Annotation[0],
args); args);
} }
/**
* Sets the fields of this {@link AtomConstructor} and generates a constructor function.
*
* @param scopeBuilder the module scope's builder where the accessor should be registered at
* @return {@code this}, for convenience
*/
public AtomConstructor initializeBuilder(
EnsoLanguage language, ModuleScope.Builder scopeBuilder) {
this.accessor = generateQualifiedAccessor(language, scopeBuilder);
return this;
}
/** /**
* Sets the fields of this {@link AtomConstructor} and generates a constructor function. * Sets the fields of this {@link AtomConstructor} and generates a constructor function.
* *
@ -133,7 +145,7 @@ public final class AtomConstructor implements EnsoObject {
EnsoLanguage language, EnsoLanguage language,
SourceSection section, SourceSection section,
LocalScope localScope, LocalScope localScope,
ModuleScope.Builder scopeBuilder, ModuleScope scope,
ExpressionNode[] assignments, ExpressionNode[] assignments,
ExpressionNode[] varReads, ExpressionNode[] varReads,
Annotation[] annotations, Annotation[] annotations,
@ -148,8 +160,7 @@ public final class AtomConstructor implements EnsoObject {
boxedLayout = Layout.createBoxed(args); boxedLayout = Layout.createBoxed(args);
this.constructorFunction = this.constructorFunction =
buildConstructorFunction( buildConstructorFunction(
language, section, localScope, scopeBuilder, assignments, varReads, annotations, args); language, section, localScope, scope, assignments, varReads, annotations, args);
this.accessor = generateQualifiedAccessor(language, scopeBuilder);
return this; return this;
} }
@ -170,7 +181,7 @@ public final class AtomConstructor implements EnsoObject {
EnsoLanguage language, EnsoLanguage language,
SourceSection section, SourceSection section,
LocalScope localScope, LocalScope localScope,
ModuleScope.Builder scopeBuilder, ModuleScope scope,
ExpressionNode[] assignments, ExpressionNode[] assignments,
ExpressionNode[] varReads, ExpressionNode[] varReads,
Annotation[] annotations, Annotation[] annotations,
@ -182,7 +193,7 @@ public final class AtomConstructor implements EnsoObject {
BlockNode instantiateBlock = BlockNode.buildSilent(assignments, instantiateNode); BlockNode instantiateBlock = BlockNode.buildSilent(assignments, instantiateNode);
RootNode rootNode = RootNode rootNode =
MethodRootNode.buildConstructor( MethodRootNode.buildConstructor(
language, localScope, scopeBuilder.asModuleScope(), instantiateBlock, section, this); language, localScope, scope, instantiateBlock, section, this);
RootCallTarget callTarget = rootNode.getCallTarget(); RootCallTarget callTarget = rootNode.getCallTarget();
var schemaBldr = FunctionSchema.newBuilder().annotations(annotations).argumentDefinitions(args); var schemaBldr = FunctionSchema.newBuilder().annotations(annotations).argumentDefinitions(args);
if (type.isProjectPrivate()) { if (type.isProjectPrivate()) {

View File

@ -255,6 +255,21 @@ public final class ModuleScope implements EnsoObject {
return "Scope" + module; return "Scope" + module;
} }
/**
* Registers all methods of a type in the provided scope.
*
* @param tpe the methods of which type should be registered
* @param scope target scope where methods should be registered to
*/
public void registerAllMethodsOfTypeToScope(Type tpe, ModuleScope.Builder scope) {
// FIXME: because of Builtins can't enable 'assert moduleScope == null;'
Type tpeKey = tpe == null ? noTypeKey : tpe;
var allTypeMethods = methods.get(tpeKey);
if (allTypeMethods != null) {
allTypeMethods.forEach((name, fun) -> scope.registerMethod(tpeKey, name, fun));
}
}
public static class Builder { public static class Builder {
@CompilerDirectives.CompilationFinal private ModuleScope moduleScope = null; @CompilerDirectives.CompilationFinal private ModuleScope moduleScope = null;
@ -275,7 +290,8 @@ public final class ModuleScope implements EnsoObject {
this.conversions = new LinkedHashMap<>(); this.conversions = new LinkedHashMap<>();
this.imports = new LinkedHashSet<>(); this.imports = new LinkedHashSet<>();
this.exports = new LinkedHashSet<>(); this.exports = new LinkedHashSet<>();
this.associatedType = Type.createSingleton(module.getName().item(), this, null, false, false); this.associatedType =
Type.createSingleton(module.getName().item(), module, null, false, false);
} }
public Builder(Module module, Map<String, Type> types) { public Builder(Module module, Map<String, Type> types) {
@ -286,7 +302,8 @@ public final class ModuleScope implements EnsoObject {
this.conversions = new LinkedHashMap<>(); this.conversions = new LinkedHashMap<>();
this.imports = new LinkedHashSet<>(); this.imports = new LinkedHashSet<>();
this.exports = new LinkedHashSet<>(); this.exports = new LinkedHashSet<>();
this.associatedType = Type.createSingleton(module.getName().item(), this, null, false, false); this.associatedType =
Type.createSingleton(module.getName().item(), module, null, false, false);
} }
public Builder( public Builder(
@ -314,6 +331,20 @@ public final class ModuleScope implements EnsoObject {
return current == null ? type : current; return current == null ? type : current;
} }
/**
* Get a type registered in this builder.
*
* @param name name of the type
* @param ignoreAssociatedType ignore associated type or not?
* @return type or {@code null}
*/
public Type getType(String name, boolean ignoreAssociatedType) {
if (!ignoreAssociatedType && associatedType.getName().equals(name)) {
return associatedType;
}
return types.get(name);
}
/** /**
* Returns a map of methods defined in this module for a given type. * Returns a map of methods defined in this module for a given type.
* *
@ -354,6 +385,9 @@ public final class ModuleScope implements EnsoObject {
*/ */
public void registerMethod(Type type, String method, Supplier<Function> supply) { public void registerMethod(Type type, String method, Supplier<Function> supply) {
assert moduleScope == null; assert moduleScope == null;
if (type == null) {
type = this.associatedType;
}
Map<String, Supplier<Function>> methodMap = ensureMethodMapFor(type); Map<String, Supplier<Function>> methodMap = ensureMethodMapFor(type);
// Builtin types will have double definition because of // Builtin types will have double definition because of
@ -393,21 +427,6 @@ public final class ModuleScope implements EnsoObject {
polyglotSymbols.put(name, sym); polyglotSymbols.put(name, sym);
} }
/**
* Registers all methods of a type in the provided scope.
*
* @param tpe the methods of which type should be registered
* @param scope target scope where methods should be registered to
*/
public void registerAllMethodsOfTypeToScope(Type tpe, ModuleScope.Builder scope) {
// FIXME: because of Builtins can't enable 'assert moduleScope == null;'
Type tpeKey = tpe == null ? noTypeKey : tpe;
var allTypeMethods = methods.get(tpeKey);
if (allTypeMethods != null) {
allTypeMethods.forEach((name, fun) -> scope.registerMethod(tpeKey, name, fun));
}
}
/** /**
* Adds a dependency for this module. * Adds a dependency for this module.
* *
@ -450,7 +469,7 @@ public final class ModuleScope implements EnsoObject {
*/ */
public ModuleScope build() { public ModuleScope build() {
if (moduleScope == null) { if (moduleScope == null) {
moduleScope = return moduleScope =
new ModuleScope( new ModuleScope(
module, module,
associatedType, associatedType,
@ -460,8 +479,9 @@ public final class ModuleScope implements EnsoObject {
Collections.unmodifiableMap(conversions), Collections.unmodifiableMap(conversions),
Collections.unmodifiableSet(imports), Collections.unmodifiableSet(imports),
Collections.unmodifiableSet(exports)); Collections.unmodifiableSet(exports));
} else {
throw new AssertionError("Already built");
} }
return moduleScope;
} }
public static ModuleScope.Builder fromCompilerModuleScopeBuilder( public static ModuleScope.Builder fromCompilerModuleScopeBuilder(
@ -469,26 +489,6 @@ public final class ModuleScope implements EnsoObject {
return ((TruffleCompilerModuleScopeBuilder) scopeBuilder).unsafeScopeBuilder(); return ((TruffleCompilerModuleScopeBuilder) scopeBuilder).unsafeScopeBuilder();
} }
/**
* Return a view on `this` as a ModuleScope, rather than its builder.
*
* @return ModuleScope, if the builder has already been `built`, a proxy instance with the
* currently registered entities
*/
public ModuleScope asModuleScope() {
if (moduleScope != null) return moduleScope;
else
return new ModuleScope(
module,
associatedType,
Collections.unmodifiableMap(polyglotSymbols),
Collections.unmodifiableMap(types),
Collections.unmodifiableMap(methods),
Collections.unmodifiableMap(conversions),
Collections.unmodifiableSet(imports),
Collections.unmodifiableSet(exports));
}
@Override @Override
public java.lang.String toString() { public java.lang.String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@ -126,13 +126,13 @@ import org.enso.interpreter.runtime.error.DataflowError
* @param context the language context instance for which this is executing * @param context the language context instance for which this is executing
* @param source the source code that corresponds to the text for which code * @param source the source code that corresponds to the text for which code
* is being generated * is being generated
* @param scopeBuilder the scope's builder of the module for which code is being generated * @param module the module for which we are building the Truffle representation
* @param compilerConfig the configuration for the compiler * @param compilerConfig the configuration for the compiler
*/ */
class IrToTruffle( class IrToTruffle(
val context: EnsoContext, val context: EnsoContext,
val source: Source, val source: Source,
val scopeBuilder: ModuleScope.Builder, val module: org.enso.interpreter.runtime.Module,
val compilerConfig: CompilerConfig val compilerConfig: CompilerConfig
) { ) {
@ -164,6 +164,7 @@ class IrToTruffle(
* @return an truffle expression representing `ir` * @return an truffle expression representing `ir`
*/ */
def runInline( def runInline(
moduleScope: ModuleScope,
ir: Expression, ir: Expression,
localScope: LocalScope, localScope: LocalScope,
scopeName: String scopeName: String
@ -171,8 +172,8 @@ class IrToTruffle(
new ExpressionProcessor( new ExpressionProcessor(
localScope, localScope,
scopeName, scopeName,
scopeBuilder.getModule().getName().toString() module.getName().toString()
).runInline(ir) ).runInline(moduleScope, ir)
} }
// ========================================================================== // ==========================================================================
@ -188,7 +189,8 @@ class IrToTruffle(
* @param module the module for which code should be generated * @param module the module for which code should be generated
*/ */
private def processModule(module: Module): Unit = { private def processModule(module: Module): Unit = {
generateReExportBindings(module) val scopeBuilder = this.module.newScopeBuilder(true)
generateReExportBindings(scopeBuilder, module)
val bindingsMap = val bindingsMap =
module module
.unsafeGetMetadata( .unsafeGetMetadata(
@ -229,7 +231,7 @@ class IrToTruffle(
) )
hostSymbol = DataflowError.withoutTrace(err, null) hostSymbol = DataflowError.withoutTrace(err, null)
} }
this.scopeBuilder.registerPolyglotSymbol( scopeBuilder.registerPolyglotSymbol(
poly.getVisibleName, poly.getVisibleName,
hostSymbol hostSymbol
) )
@ -238,10 +240,30 @@ class IrToTruffle(
} }
val typeDefs = module.bindings.collect { case tp: Definition.Type => tp } val typeDefs = module.bindings.collect { case tp: Definition.Type => tp }
typeDefs.foreach { tpDef => typeDefs.foreach { tpDef =>
// Register the atoms and their constructors in scope // Register the atoms and their constructors in scope
val atomDefs = tpDef.members val atomDefs = tpDef.members
val asType = scopeBuilder.asModuleScope().getType(tpDef.name.name, true) val asType = scopeBuilder.getType(tpDef.name.name, true)
val atomConstructors =
atomDefs.map(cons => asType.getConstructors.get(cons.name.name))
atomConstructors
.zip(atomDefs)
.foreach { case (atomCons, _) =>
atomCons.initializeBuilder(
language,
scopeBuilder
)
}
asType.generateGetters(scopeBuilder, language)
}
val moduleScope = scopeBuilder.build()
typeDefs.foreach { tpDef =>
// Register the atoms and their constructors in scope
val atomDefs = tpDef.members
val asType = moduleScope.getType(tpDef.name.name, true)
val atomConstructors = val atomConstructors =
atomDefs.map(cons => asType.getConstructors.get(cons.name.name)) atomDefs.map(cons => asType.getConstructors.get(cons.name.name))
atomConstructors atomConstructors
@ -267,6 +289,7 @@ class IrToTruffle(
val argFactory = val argFactory =
new DefinitionArgumentProcessor( new DefinitionArgumentProcessor(
moduleScope = moduleScope,
scope = localScope, scope = localScope,
initialName = "Type " + tpDef.name initialName = "Type " + tpDef.name
) )
@ -278,7 +301,8 @@ class IrToTruffle(
for (idx <- atomDefn.arguments.indices) { for (idx <- atomDefn.arguments.indices) {
val unprocessedArg = atomDefn.arguments(idx) val unprocessedArg = atomDefn.arguments(idx)
val checkNode = checkAsTypes(unprocessedArg) val checkNode = checkAsTypes(unprocessedArg)
val arg = argFactory.run(unprocessedArg, idx, checkNode) val arg =
argFactory.run(moduleScope, unprocessedArg, idx, checkNode)
val occInfo = unprocessedArg val occInfo = unprocessedArg
.unsafeGetMetadata( .unsafeGetMetadata(
AliasAnalysis, AliasAnalysis,
@ -317,14 +341,14 @@ class IrToTruffle(
atomDefn.name.name atomDefn.name.name
) )
val expressionNode = val expressionNode =
expressionProcessor.run(annotation.expression, true) expressionProcessor.run(moduleScope, annotation.expression, true)
val closureName = s"<default::$scopeName>" val closureName = s"<default::$scopeName>"
val closureRootNode = ClosureRootNode.build( val closureRootNode = ClosureRootNode.build(
language, language,
expressionProcessor.scope, expressionProcessor.scope,
scopeBuilder.asModuleScope(), moduleScope,
expressionNode, expressionNode,
makeSection(scopeBuilder.getModule, annotation.location), makeSection(this.module, annotation.location),
closureName, closureName,
true, true,
false false
@ -334,9 +358,9 @@ class IrToTruffle(
if (!atomCons.isInitialized) { if (!atomCons.isInitialized) {
atomCons.initializeFields( atomCons.initializeFields(
language, language,
makeSection(scopeBuilder.getModule, atomDefn.location), makeSection(this.module, atomDefn.location),
localScope, localScope,
scopeBuilder, moduleScope,
assignments.toArray, assignments.toArray,
reads.toArray, reads.toArray,
annotations.toArray, annotations.toArray,
@ -344,7 +368,6 @@ class IrToTruffle(
) )
} }
} }
asType.generateGetters(language)
} }
// Register the method definitions in scope // Register the method definitions in scope
@ -498,6 +521,7 @@ class IrToTruffle(
} }
val bodyBuilder = val bodyBuilder =
new expressionProcessor.BuildFunctionBody( new expressionProcessor.BuildFunctionBody(
moduleScope,
m.getFunction.getName, m.getFunction.getName,
fn.arguments, fn.arguments,
fn.body, fn.body,
@ -508,7 +532,7 @@ class IrToTruffle(
m.getFunction.getCallTarget.getRootNode m.getFunction.getCallTarget.getRootNode
.asInstanceOf[BuiltinRootNode] .asInstanceOf[BuiltinRootNode]
builtinRootNode builtinRootNode
.setModuleName(scopeBuilder.getModule.getName) .setModuleName(this.module.getName)
builtinRootNode.setTypeName(cons.getQualifiedName) builtinRootNode.setTypeName(cons.getQualifiedName)
val funcSchemaBldr = FunctionSchema val funcSchemaBldr = FunctionSchema
.newBuilder() .newBuilder()
@ -530,6 +554,7 @@ class IrToTruffle(
case fn: Function => case fn: Function =>
val bodyBuilder = val bodyBuilder =
new expressionProcessor.BuildFunctionBody( new expressionProcessor.BuildFunctionBody(
moduleScope,
fullMethodDefName, fullMethodDefName,
fn.arguments, fn.arguments,
fn.body, fn.body,
@ -550,11 +575,11 @@ class IrToTruffle(
MethodRootNode.buildOperator( MethodRootNode.buildOperator(
language, language,
expressionProcessor.scope, expressionProcessor.scope,
scopeBuilder.asModuleScope(), moduleScope,
() => bodyBuilder.argsExpr._1(0), () => bodyBuilder.argsExpr._1(0),
() => bodyBuilder.argsExpr._1(1), () => bodyBuilder.argsExpr._1(1),
() => bodyBuilder.argsExpr._2, () => bodyBuilder.argsExpr._2,
makeSection(scopeBuilder.getModule, methodDef.location), makeSection(this.module, methodDef.location),
cons, cons,
methodDef.methodName.name methodDef.methodName.name
) )
@ -562,9 +587,9 @@ class IrToTruffle(
MethodRootNode.build( MethodRootNode.build(
language, language,
expressionProcessor.scope, expressionProcessor.scope,
scopeBuilder.asModuleScope(), moduleScope,
() => bodyBuilder.bodyNode(), () => bodyBuilder.bodyNode(),
makeSection(scopeBuilder.getModule, methodDef.location), makeSection(this.module, methodDef.location),
cons, cons,
methodDef.methodName.name methodDef.methodName.name
) )
@ -607,16 +632,17 @@ class IrToTruffle(
methodDef.methodName.name methodDef.methodName.name
) )
val expressionNode = val expressionNode =
expressionProcessor.run(annotation.expression, true) expressionProcessor
.run(moduleScope, annotation.expression, true)
val closureName = val closureName =
s"<default::${expressionProcessor.scopeName}>" s"<default::${expressionProcessor.scopeName}>"
val closureRootNode = ClosureRootNode.build( val closureRootNode = ClosureRootNode.build(
language, language,
expressionProcessor.scope, expressionProcessor.scope,
scopeBuilder.asModuleScope(), moduleScope,
expressionNode, expressionNode,
makeSection( makeSection(
scopeBuilder.getModule, this.module,
annotation.location annotation.location
), ),
closureName, closureName,
@ -706,6 +732,7 @@ class IrToTruffle(
case fn: Function => case fn: Function =>
val bodyBuilder = val bodyBuilder =
new expressionProcessor.BuildFunctionBody( new expressionProcessor.BuildFunctionBody(
moduleScope,
methodDef.methodName.name, methodDef.methodName.name,
fn.arguments, fn.arguments,
fn.body, fn.body,
@ -715,9 +742,9 @@ class IrToTruffle(
val rootNode = MethodRootNode.build( val rootNode = MethodRootNode.build(
language, language,
expressionProcessor.scope, expressionProcessor.scope,
scopeBuilder.asModuleScope(), moduleScope,
() => bodyBuilder.bodyNode(), () => bodyBuilder.bodyNode(),
makeSection(scopeBuilder.getModule, methodDef.location), makeSection(this.module, methodDef.location),
toType, toType,
methodDef.methodName.name methodDef.methodName.name
) )
@ -897,7 +924,10 @@ class IrToTruffle(
expr expr
} }
private def generateReExportBindings(module: Module): Unit = { private def generateReExportBindings(
scopeBuilder: ModuleScope.Builder,
module: Module
): Unit = {
def mkConsGetter(constructor: AtomConstructor): RuntimeFunction = def mkConsGetter(constructor: AtomConstructor): RuntimeFunction =
constructor.getAccessorFunction() constructor.getAccessorFunction()
@ -930,7 +960,7 @@ class IrToTruffle(
if ( if (
resolution.isInstanceOf[ResolvedConstructor] || !resolution.module resolution.isInstanceOf[ResolvedConstructor] || !resolution.module
.unsafeAsModule() .unsafeAsModule()
.equals(scopeBuilder.getModule.asCompilerModule) .equals(module)
) { ) {
resolution match { resolution match {
case binding @ BindingsMap.ResolvedType(_, _) => case binding @ BindingsMap.ResolvedType(_, _) =>
@ -1051,25 +1081,28 @@ class IrToTruffle(
* @return a truffle expression that represents the same program as `ir` * @return a truffle expression that represents the same program as `ir`
*/ */
def run( def run(
moduleScope: ModuleScope,
ir: Expression, ir: Expression,
subjectToInstrumentation: Boolean subjectToInstrumentation: Boolean
): RuntimeExpression = run(ir, false, subjectToInstrumentation) ): RuntimeExpression = run(moduleScope, ir, false, subjectToInstrumentation)
private def run( private def run(
moduleScope: ModuleScope,
ir: Expression, ir: Expression,
binding: Boolean, binding: Boolean,
subjectToInstrumentation: Boolean subjectToInstrumentation: Boolean
): RuntimeExpression = { ): RuntimeExpression = {
var runtimeExpression = ir match { var runtimeExpression = ir match {
case block: Expression.Block => processBlock(block) case block: Expression.Block => processBlock(moduleScope, block)
case literal: Literal => processLiteral(literal) case literal: Literal => processLiteral(literal)
case app: Application => case app: Application =>
processApplication(app, subjectToInstrumentation) processApplication(moduleScope, app, subjectToInstrumentation)
case name: Name => processName(name) case name: Name => processName(moduleScope, name)
case function: Function => processFunction(function, binding) case function: Function =>
case binding: Expression.Binding => processBinding(binding) processFunction(moduleScope, function, binding)
case binding: Expression.Binding => processBinding(moduleScope, binding)
case caseExpr: Case => case caseExpr: Case =>
processCase(caseExpr, subjectToInstrumentation) processCase(moduleScope, caseExpr, subjectToInstrumentation)
case typ: Tpe => processType(typ) case typ: Tpe => processType(typ)
case _: Empty => case _: Empty =>
processEmpty() processEmpty()
@ -1108,8 +1141,11 @@ class IrToTruffle(
* @param ir the IR to generate code for * @param ir the IR to generate code for
* @return a truffle expression that represents the same program as `ir` * @return a truffle expression that represents the same program as `ir`
*/ */
def runInline(ir: Expression): RuntimeExpression = { def runInline(
val expression = run(ir, false) moduleScope: ModuleScope,
ir: Expression
): RuntimeExpression = {
val expression = run(moduleScope, ir, false)
expression expression
} }
@ -1120,7 +1156,10 @@ class IrToTruffle(
* @param block the block to generate code for * @param block the block to generate code for
* @return the truffle nodes corresponding to `block` * @return the truffle nodes corresponding to `block`
*/ */
private def processBlock(block: Expression.Block): RuntimeExpression = { private def processBlock(
moduleScope: ModuleScope,
block: Expression.Block
): RuntimeExpression = {
if (block.suspended) { if (block.suspended) {
val scopeInfo = block val scopeInfo = block
.unsafeGetMetadata( .unsafeGetMetadata(
@ -1136,14 +1175,15 @@ class IrToTruffle(
) )
val childScope = childFactory.scope val childScope = childFactory.scope
val blockNode = childFactory.processBlock(block.copy(suspended = false)) val blockNode =
childFactory.processBlock(moduleScope, block.copy(suspended = false))
val defaultRootNode = ClosureRootNode.build( val defaultRootNode = ClosureRootNode.build(
language, language,
childScope, childScope,
scopeBuilder.asModuleScope(), moduleScope,
blockNode, blockNode,
makeSection(scopeBuilder.getModule, block.location), makeSection(module, block.location),
currentVarName, currentVarName,
false, false,
false false
@ -1152,8 +1192,9 @@ class IrToTruffle(
val callTarget = defaultRootNode.getCallTarget val callTarget = defaultRootNode.getCallTarget
setLocation(CreateThunkNode.build(callTarget), block.location) setLocation(CreateThunkNode.build(callTarget), block.location)
} else { } else {
val statementExprs = block.expressions.map(this.run(_, true)).toArray val statementExprs =
val retExpr = this.run(block.returnValue, true) block.expressions.map(this.run(moduleScope, _, true)).toArray
val retExpr = this.run(moduleScope, block.returnValue, true)
val blockNode = BlockNode.build(statementExprs, retExpr) val blockNode = BlockNode.build(statementExprs, retExpr)
setLocation(blockNode, block.location) setLocation(blockNode, block.location)
@ -1186,14 +1227,16 @@ class IrToTruffle(
* @return the truffle nodes corresponding to `caseExpr` * @return the truffle nodes corresponding to `caseExpr`
*/ */
def processCase( def processCase(
moduleScope: ModuleScope,
caseExpr: Case, caseExpr: Case,
subjectToInstrumentation: Boolean subjectToInstrumentation: Boolean
): RuntimeExpression = ): RuntimeExpression =
caseExpr match { caseExpr match {
case Case.Expr(scrutinee, branches, isNested, location, _, _) => case Case.Expr(scrutinee, branches, isNested, location, _, _) =>
val scrutineeNode = this.run(scrutinee, subjectToInstrumentation) val scrutineeNode =
this.run(moduleScope, scrutinee, subjectToInstrumentation)
val maybeCases = branches.map(processCaseBranch) val maybeCases = branches.map(processCaseBranch(moduleScope, _))
val allCasesValid = maybeCases.forall(_.isRight) val allCasesValid = maybeCases.forall(_.isRight)
if (allCasesValid) { if (allCasesValid) {
@ -1234,6 +1277,7 @@ class IrToTruffle(
* the match is invalid * the match is invalid
*/ */
def processCaseBranch( def processCaseBranch(
moduleScope: ModuleScope,
branch: Case.Branch branch: Case.Branch
): Either[BadPatternMatch, BranchNode] = { ): Either[BadPatternMatch, BranchNode] = {
val scopeInfo = branch val scopeInfo = branch
@ -1255,6 +1299,7 @@ class IrToTruffle(
val arg = List(genArgFromMatchField(named)) val arg = List(genArgFromMatchField(named))
val branchCodeNode = childProcessor.processFunctionBody( val branchCodeNode = childProcessor.processFunctionBody(
moduleScope,
arg, arg,
branch.expression, branch.expression,
branch.location branch.location
@ -1276,6 +1321,7 @@ class IrToTruffle(
val fieldsAsArgs = fieldNames.map(genArgFromMatchField) val fieldsAsArgs = fieldNames.map(genArgFromMatchField)
val branchCodeNode = childProcessor.processFunctionBody( val branchCodeNode = childProcessor.processFunctionBody(
moduleScope,
fieldsAsArgs, fieldsAsArgs,
branch.expression, branch.expression,
branch.location branch.location
@ -1421,6 +1467,7 @@ class IrToTruffle(
} }
case literalPattern: Pattern.Literal => case literalPattern: Pattern.Literal =>
val branchCodeNode = childProcessor.processFunctionBody( val branchCodeNode = childProcessor.processFunctionBody(
moduleScope,
Nil, Nil,
branch.expression, branch.expression,
branch.location branch.location
@ -1494,6 +1541,7 @@ class IrToTruffle(
) )
val branchCodeNode = childProcessor.processFunctionBody( val branchCodeNode = childProcessor.processFunctionBody(
moduleScope,
argOfType, argOfType,
branch.expression, branch.expression,
branch.location branch.location
@ -1528,6 +1576,7 @@ class IrToTruffle(
) )
val branchCodeNode = childProcessor.processFunctionBody( val branchCodeNode = childProcessor.processFunctionBody(
moduleScope,
argOfType, argOfType,
branch.expression, branch.expression,
branch.location branch.location
@ -1594,6 +1643,7 @@ class IrToTruffle(
* @return the truffle nodes corresponding to `binding` * @return the truffle nodes corresponding to `binding`
*/ */
private def processBinding( private def processBinding(
moduleScope: ModuleScope,
binding: Expression.Binding binding: Expression.Binding
): RuntimeExpression = { ): RuntimeExpression = {
val occInfo = binding val occInfo = binding
@ -1608,7 +1658,10 @@ class IrToTruffle(
val slotIdx = scope.getVarSlotIdx(occInfo.id) val slotIdx = scope.getVarSlotIdx(occInfo.id)
setLocation( setLocation(
AssignmentNode.build(this.run(binding.expression, true, true), slotIdx), AssignmentNode.build(
this.run(moduleScope, binding.expression, true, true),
slotIdx
),
binding.location binding.location
) )
} }
@ -1620,6 +1673,7 @@ class IrToTruffle(
* @return the truffle nodes corresponding to `function` * @return the truffle nodes corresponding to `function`
*/ */
private def processFunction( private def processFunction(
moduleScope: ModuleScope,
function: Function, function: Function,
binding: Boolean binding: Boolean
): RuntimeExpression = { ): RuntimeExpression = {
@ -1644,6 +1698,7 @@ class IrToTruffle(
this.createChild(scopeName, scopeInfo.scope, "case " + currentVarName) this.createChild(scopeName, scopeInfo.scope, "case " + currentVarName)
val fn = child.processFunctionBody( val fn = child.processFunctionBody(
moduleScope,
function.arguments, function.arguments,
function.body, function.body,
function.location, function.location,
@ -1658,7 +1713,7 @@ class IrToTruffle(
* @param name the name to generate code for * @param name the name to generate code for
* @return the truffle nodes corresponding to `name` * @return the truffle nodes corresponding to `name`
*/ */
def processName(name: Name): RuntimeExpression = { def processName(moduleScope: ModuleScope, name: Name): RuntimeExpression = {
val nameExpr = name match { val nameExpr = name match {
case Name.Literal(nameStr, _, _, _, _, _) => case Name.Literal(nameStr, _, _, _, _, _) =>
val useInfo = name val useInfo = name
@ -1677,11 +1732,11 @@ class IrToTruffle(
nodeForResolution(resolution) nodeForResolution(resolution)
} else if (nameStr == ConstantsNames.FROM_MEMBER) { } else if (nameStr == ConstantsNames.FROM_MEMBER) {
ConstantObjectNode.build( ConstantObjectNode.build(
UnresolvedConversion.build(scopeBuilder.asModuleScope()) UnresolvedConversion.build(moduleScope)
) )
} else { } else {
DynamicSymbolNode.build( DynamicSymbolNode.build(
UnresolvedSymbol.build(nameStr, scopeBuilder.asModuleScope()) UnresolvedSymbol.build(nameStr, moduleScope)
) )
} }
case Name.MethodReference( case Name.MethodReference(
@ -1694,6 +1749,7 @@ class IrToTruffle(
DynamicSymbolNode.buildUnresolvedConstructor(nameStr) DynamicSymbolNode.buildUnresolvedConstructor(nameStr)
case Name.Self(location, _, passData, _) => case Name.Self(location, _, passData, _) =>
processName( processName(
moduleScope,
Name.Literal( Name.Literal(
ConstantsNames.SELF_ARGUMENT, ConstantsNames.SELF_ARGUMENT,
isMethod = false, isMethod = false,
@ -1892,6 +1948,7 @@ class IrToTruffle(
* argument definitions. * argument definitions.
*/ */
class BuildFunctionBody( class BuildFunctionBody(
val moduleScope: ModuleScope,
val initialName: String, val initialName: String,
val arguments: List[DefinitionArgument], val arguments: List[DefinitionArgument],
val body: Expression, val body: Expression,
@ -1899,7 +1956,12 @@ class IrToTruffle(
val subjectToInstrumentation: Boolean val subjectToInstrumentation: Boolean
) { ) {
private val argFactory = private val argFactory =
new DefinitionArgumentProcessor(scopeName, scope, initialName) new DefinitionArgumentProcessor(
moduleScope,
scopeName,
scope,
initialName
)
private lazy val slots = computeSlots() private lazy val slots = computeSlots()
lazy val argsExpr = computeArgsAndExpression() lazy val argsExpr = computeArgsAndExpression()
@ -1921,7 +1983,12 @@ class IrToTruffle(
argSlotIdxs argSlotIdxs
) )
case _ => case _ =>
ExpressionProcessor.this.run(body, false, subjectToInstrumentation) ExpressionProcessor.this.run(
moduleScope,
body,
false,
subjectToInstrumentation
)
} }
(argExpressions.toArray, bodyExpr) (argExpressions.toArray, bodyExpr)
} }
@ -1938,7 +2005,8 @@ class IrToTruffle(
val argSlots = arguments.zipWithIndex.map { val argSlots = arguments.zipWithIndex.map {
case (unprocessedArg, idx) => case (unprocessedArg, idx) =>
val checkNode = checkAsTypes(unprocessedArg) val checkNode = checkAsTypes(unprocessedArg)
val arg = argFactory.run(unprocessedArg, idx, checkNode) val arg =
argFactory.run(moduleScope, unprocessedArg, idx, checkNode)
argDefinitions(idx) = arg argDefinitions(idx) = arg
val occInfo = unprocessedArg val occInfo = unprocessedArg
.unsafeGetMetadata( .unsafeGetMetadata(
@ -2007,19 +2075,27 @@ class IrToTruffle(
* @return a truffle node representing the described function * @return a truffle node representing the described function
*/ */
private def processFunctionBody( private def processFunctionBody(
moduleScope: ModuleScope,
arguments: List[DefinitionArgument], arguments: List[DefinitionArgument],
body: Expression, body: Expression,
location: Option[IdentifiedLocation], location: Option[IdentifiedLocation],
binding: Boolean = false binding: Boolean = false
): CreateFunctionNode = { ): CreateFunctionNode = {
val bodyBuilder = val bodyBuilder =
new BuildFunctionBody(scopeName, arguments, body, None, false) new BuildFunctionBody(
moduleScope,
scopeName,
arguments,
body,
None,
false
)
val fnRootNode = ClosureRootNode.build( val fnRootNode = ClosureRootNode.build(
language, language,
scope, scope,
scopeBuilder.asModuleScope(), moduleScope,
bodyBuilder.bodyNode(), bodyBuilder.bodyNode(),
makeSection(scopeBuilder.getModule, location), makeSection(module, location),
scopeName, scopeName,
false, false,
binding binding
@ -2061,21 +2137,25 @@ class IrToTruffle(
* @return the truffle nodes corresponding to `application` * @return the truffle nodes corresponding to `application`
*/ */
private def processApplication( private def processApplication(
moduleScope: ModuleScope,
application: Application, application: Application,
subjectToInstrumentation: Boolean subjectToInstrumentation: Boolean
): RuntimeExpression = ): RuntimeExpression =
application match { application match {
case Application.Prefix(fn, Nil, true, _, _, _) => case Application.Prefix(fn, Nil, true, _, _, _) =>
run(fn, subjectToInstrumentation) run(moduleScope, fn, subjectToInstrumentation)
case app: Application.Prefix => case app: Application.Prefix =>
processApplicationWithArgs(app, subjectToInstrumentation) processApplicationWithArgs(moduleScope, app, subjectToInstrumentation)
case Application.Force(expr, location, _, _) => case Application.Force(expr, location, _, _) =>
setLocation( setLocation(
ForceNode.build(this.run(expr, subjectToInstrumentation)), ForceNode.build(
this.run(moduleScope, expr, subjectToInstrumentation)
),
location location
) )
case Application.Sequence(items, location, _, _) => case Application.Sequence(items, location, _, _) =>
val itemNodes = items.map(run(_, subjectToInstrumentation)).toArray val itemNodes =
items.map(run(moduleScope, _, subjectToInstrumentation)).toArray
setLocation(SequenceLiteralNode.build(itemNodes), location) setLocation(SequenceLiteralNode.build(itemNodes), location)
case _: Application.Typeset => case _: Application.Typeset =>
setLocation( setLocation(
@ -2102,13 +2182,14 @@ class IrToTruffle(
} }
private def processApplicationWithArgs( private def processApplicationWithArgs(
moduleScope: ModuleScope,
application: Application.Prefix, application: Application.Prefix,
subjectToInstrumentation: Boolean subjectToInstrumentation: Boolean
): RuntimeExpression = { ): RuntimeExpression = {
val Application.Prefix(fn, args, hasDefaultsSuspended, loc, _, _) = val Application.Prefix(fn, args, hasDefaultsSuspended, loc, _, _) =
application application
val callArgFactory = val callArgFactory =
new CallArgumentProcessor(scope, scopeName, currentVarName) new CallArgumentProcessor(moduleScope, scope, scopeName, currentVarName)
val arguments = args val arguments = args
val callArgs = new ArrayBuffer[callable.argument.CallArgument]() val callArgs = new ArrayBuffer[callable.argument.CallArgument]()
@ -2126,7 +2207,7 @@ class IrToTruffle(
} }
val appNode = ApplicationNode.build( val appNode = ApplicationNode.build(
this.run(fn, subjectToInstrumentation), this.run(moduleScope, fn, subjectToInstrumentation),
callArgs.toArray, callArgs.toArray,
defaultsExecutionMode defaultsExecutionMode
) )
@ -2147,6 +2228,7 @@ class IrToTruffle(
* @param initialName suggested name for a first closure * @param initialName suggested name for a first closure
*/ */
sealed private class CallArgumentProcessor( sealed private class CallArgumentProcessor(
val moduleScope: ModuleScope,
val scope: LocalScope, val scope: LocalScope,
val scopeName: String, val scopeName: String,
private val initialName: String private val initialName: String
@ -2196,7 +2278,7 @@ class IrToTruffle(
} }
val argumentExpression = val argumentExpression =
new ExpressionProcessor(childScope, scopeName, initialName) new ExpressionProcessor(childScope, scopeName, initialName)
.run(value, subjectToInstrumentation) .run(moduleScope, value, subjectToInstrumentation)
val result = if (!shouldCreateClosureRootNode) { val result = if (!shouldCreateClosureRootNode) {
argumentExpression argumentExpression
@ -2213,7 +2295,7 @@ class IrToTruffle(
val closureRootNode = ClosureRootNode.build( val closureRootNode = ClosureRootNode.build(
language, language,
childScope, childScope,
scopeBuilder.asModuleScope(), moduleScope,
argumentExpression, argumentExpression,
section, section,
displayName, displayName,
@ -2254,6 +2336,7 @@ class IrToTruffle(
* @param initialName suggested name for a first closure * @param initialName suggested name for a first closure
*/ */
sealed private class DefinitionArgumentProcessor( sealed private class DefinitionArgumentProcessor(
private val moduleScope: ModuleScope,
val scopeName: String = "<root>", val scopeName: String = "<root>",
val scope: LocalScope, val scope: LocalScope,
private val initialName: String private val initialName: String
@ -2280,6 +2363,7 @@ class IrToTruffle(
* given function * given function
*/ */
def run( def run(
moduleScope: ModuleScope,
inputArg: DefinitionArgument, inputArg: DefinitionArgument,
position: Int, position: Int,
types: ReadArgumentCheckNode types: ReadArgumentCheckNode
@ -2289,7 +2373,7 @@ class IrToTruffle(
val defaultExpression = arg.defaultValue val defaultExpression = arg.defaultValue
.map( .map(
new ExpressionProcessor(scope, scopeName, initialName) new ExpressionProcessor(scope, scopeName, initialName)
.run(_, false) .run(moduleScope, _, false)
) )
.orNull .orNull
@ -2299,10 +2383,10 @@ class IrToTruffle(
val defaultRootNode = ClosureRootNode.build( val defaultRootNode = ClosureRootNode.build(
language, language,
scope, scope,
scopeBuilder.asModuleScope(), moduleScope,
defaultExpression, defaultExpression,
makeSection( makeSection(
scopeBuilder.getModule, module,
arg.defaultValue.get.location() arg.defaultValue.get.location()
), ),
s"<default::$scopeName::${arg.name.showCode()}>", s"<default::$scopeName::${arg.name.showCode()}>",
@ -2354,5 +2438,5 @@ class IrToTruffle(
} }
private def scopeAssociatedType = private def scopeAssociatedType =
scopeBuilder.asModuleScope().getAssociatedType module.getScope.getAssociatedType
} }

View File

@ -52,6 +52,7 @@ class RuntimeStubsGenerator(builtins: Builtins) {
if (tp.members.nonEmpty || tp.builtinType) { if (tp.members.nonEmpty || tp.builtinType) {
Type.create( Type.create(
tp.name, tp.name,
builtins.getModule(),
scope, scope,
builtins.any(), builtins.any(),
builtins.any(), builtins.any(),
@ -61,7 +62,7 @@ class RuntimeStubsGenerator(builtins: Builtins) {
} else { } else {
Type.createSingleton( Type.createSingleton(
tp.name, tp.name,
scope, builtins.getModule(),
builtins.any(), builtins.any(),
false, false,
isTypeProjectPrivate isTypeProjectPrivate