mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 15:12:15 +03:00
Avoid Compiler compile time dependency on EnsoContext (#7299)
This commit is contained in:
parent
7264d81f2a
commit
6864792653
@ -0,0 +1,38 @@
|
||||
package org.enso.polyglot;
|
||||
|
||||
/** Defines a stage of compilation of the module. */
|
||||
public enum CompilationStage {
|
||||
INITIAL(0),
|
||||
AFTER_PARSING(1),
|
||||
AFTER_IMPORT_RESOLUTION(2),
|
||||
AFTER_GLOBAL_TYPES(3),
|
||||
AFTER_STATIC_PASSES(4),
|
||||
AFTER_RUNTIME_STUBS(5),
|
||||
AFTER_CODEGEN(6);
|
||||
|
||||
private final int ordinal;
|
||||
|
||||
CompilationStage(int ordinal) {
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current compilation stage is at least as advanced as the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is at least as advanced as {@code stage}.
|
||||
*/
|
||||
public boolean isAtLeast(CompilationStage stage) {
|
||||
return ordinal >= stage.ordinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the current compilation stage is before the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is before then {@code stage}.
|
||||
*/
|
||||
public boolean isBefore(CompilationStage stage) {
|
||||
return ordinal < stage.ordinal;
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@ import java.util.logging.Level;
|
||||
import org.enso.compiler.SerializationManager;
|
||||
import org.enso.interpreter.instrument.execution.RuntimeContext;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
import org.enso.pkg.QualifiedName;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
|
||||
/** The job that serializes module. */
|
||||
@ -36,7 +36,7 @@ public final class SerializeModuleJob extends BackgroundJob<Void> {
|
||||
.findModule(moduleName.toString())
|
||||
.ifPresent(
|
||||
module -> {
|
||||
if (module.getCompilationStage().isBefore(Module.CompilationStage.AFTER_CODEGEN)) {
|
||||
if (module.getCompilationStage().isBefore(CompilationStage.AFTER_CODEGEN)) {
|
||||
ctx.executionService()
|
||||
.getLogger()
|
||||
.log(
|
||||
|
@ -22,6 +22,7 @@ import org.enso.interpreter.instrument.{
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.interpreter.service.error.ModuleNotFoundForFileException
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.polyglot.CompilationStage
|
||||
import org.enso.polyglot.runtime.Runtime.Api
|
||||
import org.enso.polyglot.runtime.Runtime.Api.StackItem
|
||||
import org.enso.text.buffer.Rope
|
||||
@ -217,7 +218,7 @@ final class EnsureCompiledJob(protected val files: Iterable[File])
|
||||
)(implicit ctx: RuntimeContext): Either[Throwable, CompilerResult] =
|
||||
Either.catchNonFatal {
|
||||
val compilationStage = module.getCompilationStage
|
||||
if (!compilationStage.isAtLeast(Module.CompilationStage.AFTER_CODEGEN)) {
|
||||
if (!compilationStage.isAtLeast(CompilationStage.AFTER_CODEGEN)) {
|
||||
ctx.executionService.getLogger
|
||||
.log(Level.FINEST, s"Compiling ${module.getName}.")
|
||||
val result = ctx.executionService.getContext.getCompiler.run(module)
|
||||
|
@ -13,6 +13,7 @@ import org.enso.compiler.core.IR;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
@ -49,7 +50,7 @@ public final class ModuleCache extends Cache<ModuleCache.CachedModule, ModuleCac
|
||||
try (var stream = new ObjectInputStream(new ByteArrayInputStream(data))) {
|
||||
if (stream.readObject() instanceof IR.Module ir) {
|
||||
try {
|
||||
return new CachedModule(ir, Module.CompilationStage.valueOf(meta.compilationStage()), module.getSource());
|
||||
return new CachedModule(ir,CompilationStage.valueOf(meta.compilationStage()), module.getSource());
|
||||
} catch (IOException ioe) {
|
||||
throw new ClassNotFoundException(ioe.getMessage());
|
||||
}
|
||||
@ -178,9 +179,9 @@ public final class ModuleCache extends Cache<ModuleCache.CachedModule, ModuleCac
|
||||
// CachedModule is not a record **on purpose**. There appears to be a Frgaal bug leading to invalid compilation error.
|
||||
static class CachedModule {
|
||||
private final IR.Module _moduleIR;
|
||||
private final Module.CompilationStage _compilationStage;
|
||||
private final CompilationStage _compilationStage;
|
||||
private final Source _source;
|
||||
public CachedModule(IR.Module moduleIR, Module.CompilationStage compilationStage, Source source) {
|
||||
public CachedModule(IR.Module moduleIR, CompilationStage compilationStage, Source source) {
|
||||
this._moduleIR = moduleIR;
|
||||
this._compilationStage = compilationStage;
|
||||
this._source = source;
|
||||
@ -189,7 +190,7 @@ public final class ModuleCache extends Cache<ModuleCache.CachedModule, ModuleCac
|
||||
IR.Module moduleIR() {
|
||||
return _moduleIR;
|
||||
}
|
||||
Module.CompilationStage compilationStage() {
|
||||
CompilationStage compilationStage() {
|
||||
return _compilationStage;
|
||||
}
|
||||
Source source() {
|
||||
|
@ -0,0 +1,98 @@
|
||||
package org.enso.compiler.context;
|
||||
|
||||
import com.oracle.truffle.api.TruffleFile;
|
||||
import com.oracle.truffle.api.source.Source;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.compiler.Cache;
|
||||
import org.enso.compiler.Compiler;
|
||||
import org.enso.compiler.PackageRepository;
|
||||
import org.enso.compiler.core.IR;
|
||||
import org.enso.compiler.data.CompilerConfig;
|
||||
import org.enso.interpreter.node.ExpressionNode;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
import org.enso.interpreter.runtime.scope.TopLevelScope;
|
||||
import org.enso.pkg.QualifiedName;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
|
||||
/**
|
||||
* Interface that encapsulate all services {@link Compiler} needs from Truffle or other environment.
|
||||
*/
|
||||
public interface CompilerContext {
|
||||
boolean isIrCachingDisabled();
|
||||
|
||||
boolean isUseGlobalCacheLocations();
|
||||
|
||||
boolean isInteractiveMode();
|
||||
|
||||
PackageRepository getPackageRepository();
|
||||
|
||||
PrintStream getErr();
|
||||
|
||||
PrintStream getOut();
|
||||
|
||||
void log(Level level, String msg, Object... args);
|
||||
|
||||
void logSerializationManager(Level level, String msg, Object... args);
|
||||
|
||||
void notifySerializeModule(QualifiedName moduleName);
|
||||
|
||||
TopLevelScope getTopScope();
|
||||
|
||||
// threads
|
||||
boolean isCreateThreadAllowed();
|
||||
|
||||
Thread createThread(Runnable r);
|
||||
|
||||
Thread createSystemThread(Runnable r);
|
||||
|
||||
// Truffle related
|
||||
|
||||
void truffleRunCodegen(Module module, CompilerConfig config) throws IOException;
|
||||
|
||||
void truffleRunCodegen(Source source, ModuleScope scope, CompilerConfig config, IR.Module ir);
|
||||
|
||||
ExpressionNode truffleRunInline(
|
||||
Source source, InlineContext scope, CompilerConfig config, IR.Expression ir);
|
||||
|
||||
// module related
|
||||
QualifiedName getModuleName(Module module);
|
||||
|
||||
CharSequence getCharacters(Module module) throws IOException;
|
||||
|
||||
void updateModule(Module module, Consumer<Updater> callback);
|
||||
|
||||
boolean isSynthetic(Module module);
|
||||
|
||||
boolean isInteractive(Module module);
|
||||
|
||||
boolean wasLoadedFromCache(Module module);
|
||||
|
||||
boolean hasCrossModuleLinks(Module module);
|
||||
|
||||
IR.Module getIr(Module module);
|
||||
|
||||
CompilationStage getCompilationStage(Module module);
|
||||
|
||||
<T> Optional<T> loadCache(Cache<T, ?> cache);
|
||||
|
||||
<T> Optional<TruffleFile> saveCache(Cache<T, ?> cache, T entry, boolean useGlobalCacheLocations);
|
||||
|
||||
public static interface Updater {
|
||||
void ir(IR.Module ir);
|
||||
|
||||
void compilationStage(CompilationStage stage);
|
||||
|
||||
void loadedFromCache(boolean b);
|
||||
|
||||
void hasCrossModuleLinks(boolean b);
|
||||
|
||||
void resetScope();
|
||||
|
||||
void invalidateCache();
|
||||
}
|
||||
}
|
@ -166,7 +166,8 @@ public class EnsoContext {
|
||||
builtins,
|
||||
notificationHandler);
|
||||
topScope = new TopLevelScope(builtins, packageRepository);
|
||||
this.compiler = new Compiler(this, builtins, packageRepository, compilerConfig);
|
||||
this.compiler =
|
||||
new Compiler(new TruffleCompilerContext(this), builtins, packageRepository, compilerConfig);
|
||||
|
||||
projectPackage.ifPresent(
|
||||
pkg -> packageRepository.registerMainProjectPackage(pkg.libraryName(), pkg));
|
||||
|
@ -40,6 +40,7 @@ import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
import org.enso.interpreter.runtime.type.Types;
|
||||
import org.enso.pkg.Package;
|
||||
import org.enso.pkg.QualifiedName;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
import org.enso.polyglot.LanguageInfo;
|
||||
import org.enso.polyglot.MethodNames;
|
||||
import org.enso.text.buffer.Rope;
|
||||
@ -48,44 +49,6 @@ import scala.Function1;
|
||||
/** Represents a source module with a known location. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public final class Module implements TruffleObject {
|
||||
|
||||
/** Defines a stage of compilation of the module. */
|
||||
public enum CompilationStage {
|
||||
INITIAL(0),
|
||||
AFTER_PARSING(1),
|
||||
AFTER_IMPORT_RESOLUTION(2),
|
||||
AFTER_GLOBAL_TYPES(3),
|
||||
AFTER_STATIC_PASSES(4),
|
||||
AFTER_RUNTIME_STUBS(5),
|
||||
AFTER_CODEGEN(6);
|
||||
|
||||
private final int ordinal;
|
||||
|
||||
CompilationStage(int ordinal) {
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current compilation stage is at least as advanced as the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is at least as advanced as {@code stage}.
|
||||
*/
|
||||
public boolean isAtLeast(CompilationStage stage) {
|
||||
return ordinal >= stage.ordinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the current compilation stage is before the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is before then {@code stage}.
|
||||
*/
|
||||
public boolean isBefore(CompilationStage stage) {
|
||||
return ordinal < stage.ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleScope scope;
|
||||
private ModuleSources sources;
|
||||
private PatchedModuleValues patchedValues;
|
||||
@ -446,7 +409,7 @@ public final class Module implements TruffleObject {
|
||||
*
|
||||
* @param compilationStage the new compilation stage for the module.
|
||||
*/
|
||||
public void unsafeSetCompilationStage(CompilationStage compilationStage) {
|
||||
void unsafeSetCompilationStage(CompilationStage compilationStage) {
|
||||
this.compilationStage = compilationStage;
|
||||
}
|
||||
|
||||
@ -459,7 +422,7 @@ public final class Module implements TruffleObject {
|
||||
*
|
||||
* @param ir the new IR for the module.
|
||||
*/
|
||||
public void unsafeSetIr(IR.Module ir) {
|
||||
void unsafeSetIr(IR.Module ir) {
|
||||
this.ir = ir;
|
||||
this.uuidsMap = null;
|
||||
}
|
||||
@ -532,7 +495,7 @@ public final class Module implements TruffleObject {
|
||||
}
|
||||
|
||||
/** @param wasLoadedFromCache whether or not the module was loaded from the cache */
|
||||
public void setLoadedFromCache(boolean wasLoadedFromCache) {
|
||||
void setLoadedFromCache(boolean wasLoadedFromCache) {
|
||||
this.wasLoadedFromCache = wasLoadedFromCache;
|
||||
}
|
||||
|
||||
@ -545,7 +508,7 @@ public final class Module implements TruffleObject {
|
||||
}
|
||||
|
||||
/** @param hasCrossModuleLinks whether or not the module has cross-module links restored */
|
||||
public void setHasCrossModuleLinks(boolean hasCrossModuleLinks) {
|
||||
void setHasCrossModuleLinks(boolean hasCrossModuleLinks) {
|
||||
this.hasCrossModuleLinks = hasCrossModuleLinks;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,246 @@
|
||||
package org.enso.interpreter.runtime;
|
||||
|
||||
import com.oracle.truffle.api.TruffleFile;
|
||||
import com.oracle.truffle.api.TruffleLogger;
|
||||
import com.oracle.truffle.api.source.Source;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.compiler.Cache;
|
||||
import org.enso.compiler.Compiler;
|
||||
import org.enso.compiler.PackageRepository;
|
||||
import org.enso.compiler.SerializationManager;
|
||||
import org.enso.compiler.codegen.IrToTruffle;
|
||||
import org.enso.compiler.context.CompilerContext;
|
||||
import org.enso.compiler.context.InlineContext;
|
||||
import org.enso.compiler.core.IR;
|
||||
import org.enso.compiler.data.CompilerConfig;
|
||||
import org.enso.interpreter.node.ExpressionNode;
|
||||
import org.enso.interpreter.runtime.scope.LocalScope;
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
import org.enso.interpreter.runtime.scope.TopLevelScope;
|
||||
import org.enso.pkg.QualifiedName;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
|
||||
final class TruffleCompilerContext implements CompilerContext {
|
||||
private final EnsoContext context;
|
||||
private final TruffleLogger compiler;
|
||||
private final TruffleLogger serializationManager;
|
||||
|
||||
TruffleCompilerContext(EnsoContext context) {
|
||||
this.context = context;
|
||||
this.compiler = context.getLogger(Compiler.class);
|
||||
this.serializationManager = context.getLogger(SerializationManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIrCachingDisabled() {
|
||||
return context.isIrCachingDisabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseGlobalCacheLocations() {
|
||||
return context
|
||||
.getEnvironment()
|
||||
.getOptions()
|
||||
.get(RuntimeOptions.USE_GLOBAL_IR_CACHE_LOCATION_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInteractiveMode() {
|
||||
return context.getEnvironment().getOptions().get(RuntimeOptions.INTERACTIVE_MODE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageRepository getPackageRepository() {
|
||||
return context.getPackageRepository();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintStream getErr() {
|
||||
return context.getErr();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintStream getOut() {
|
||||
return context.getOut();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, String msg, Object... args) {
|
||||
compiler.log(level, msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSerializationManager(Level level, String msg, Object... args) {
|
||||
serializationManager.log(level, msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifySerializeModule(QualifiedName moduleName) {
|
||||
context.getNotificationHandler().serializeModule(moduleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopLevelScope getTopScope() {
|
||||
return context.getTopScope();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreateThreadAllowed() {
|
||||
return context.getEnvironment().isCreateThreadAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread createThread(Runnable r) {
|
||||
return context.getEnvironment().createThread(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread createSystemThread(Runnable r) {
|
||||
return context.getEnvironment().createSystemThread(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void truffleRunCodegen(Module module, CompilerConfig config) throws IOException {
|
||||
truffleRunCodegen(module.getSource(), module.getScope(), config, module.getIr());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void truffleRunCodegen(
|
||||
Source source, ModuleScope scope, CompilerConfig config, IR.Module ir) {
|
||||
new IrToTruffle(context, source, scope, config).run(ir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionNode truffleRunInline(
|
||||
Source source, InlineContext inlineContext, CompilerConfig config, IR.Expression ir) {
|
||||
var localScope =
|
||||
inlineContext.localScope().isDefined()
|
||||
? inlineContext.localScope().get()
|
||||
: LocalScope.root();
|
||||
return new IrToTruffle(context, source, inlineContext.module().getScope(), config)
|
||||
.runInline(ir, localScope, "<inline_source>");
|
||||
}
|
||||
|
||||
// module related
|
||||
@Override
|
||||
public QualifiedName getModuleName(Module module) {
|
||||
return module.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharacters(Module module) throws IOException {
|
||||
return module.getSource().getCharacters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynthetic(Module module) {
|
||||
return module.isSynthetic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInteractive(Module module) {
|
||||
return module.isInteractive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasLoadedFromCache(Module module) {
|
||||
return module.wasLoadedFromCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCrossModuleLinks(Module module) {
|
||||
return module.hasCrossModuleLinks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IR.Module getIr(Module module) {
|
||||
return module.getIr();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompilationStage getCompilationStage(Module module) {
|
||||
return module.getCompilationStage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModule(Module module, Consumer<Updater> callback) {
|
||||
try (var u = new ModuleUpdater(module)) {
|
||||
callback.accept(u);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> loadCache(Cache<T, ?> cache) {
|
||||
return cache.load(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<TruffleFile> saveCache(
|
||||
Cache<T, ?> cache, T entry, boolean useGlobalCacheLocations) {
|
||||
return cache.save(entry, context, useGlobalCacheLocations);
|
||||
}
|
||||
|
||||
private final class ModuleUpdater implements Updater, AutoCloseable {
|
||||
private final Module module;
|
||||
private IR.Module ir;
|
||||
private CompilationStage stage;
|
||||
private Boolean loadedFromCache;
|
||||
private Boolean hasCrossModuleLinks;
|
||||
private boolean resetScope;
|
||||
private boolean invalidateCache;
|
||||
|
||||
private ModuleUpdater(org.enso.interpreter.runtime.Module module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ir(IR.Module ir) {
|
||||
this.ir = ir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compilationStage(CompilationStage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadedFromCache(boolean b) {
|
||||
this.loadedFromCache = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasCrossModuleLinks(boolean b) {
|
||||
this.hasCrossModuleLinks = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetScope() {
|
||||
this.resetScope = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCache() {
|
||||
this.invalidateCache = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (ir != null) module.unsafeSetIr(ir);
|
||||
if (stage != null) module.unsafeSetCompilationStage(stage);
|
||||
if (loadedFromCache != null) module.setLoadedFromCache(loadedFromCache);
|
||||
if (hasCrossModuleLinks != null) module.setHasCrossModuleLinks(hasCrossModuleLinks);
|
||||
if (resetScope) {
|
||||
module.ensureScopeExists();
|
||||
module.getScope().reset();
|
||||
}
|
||||
if (invalidateCache) {
|
||||
module.getCache().invalidate(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.enso.compiler.context.CompilerContext;
|
||||
import org.enso.compiler.Passes;
|
||||
import org.enso.compiler.context.FreshNameSupply;
|
||||
import org.enso.compiler.core.CompilerError;
|
||||
@ -216,12 +217,12 @@ public final class Builtins {
|
||||
* @param passes the passes manager for the compiler
|
||||
*/
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public void initializeBuiltinsIr(FreshNameSupply freshNameSupply, Passes passes) {
|
||||
public void initializeBuiltinsIr(CompilerContext context, FreshNameSupply freshNameSupply, Passes passes) {
|
||||
try {
|
||||
if (module.getSource() == null) {
|
||||
initializeBuiltinsSource();
|
||||
}
|
||||
BuiltinsIrBuilder.build(module, freshNameSupply, passes);
|
||||
BuiltinsIrBuilder.build(context, module, freshNameSupply, passes);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package org.enso.compiler
|
||||
|
||||
import com.oracle.truffle.api.TruffleLogger
|
||||
import com.oracle.truffle.api.source.{Source, SourceSection}
|
||||
import org.enso.compiler.codegen.{IrToTruffle, RuntimeStubsGenerator}
|
||||
import org.enso.compiler.context.{FreshNameSupply, InlineContext, ModuleContext}
|
||||
import org.enso.compiler.codegen.RuntimeStubsGenerator
|
||||
import org.enso.compiler.context.{
|
||||
CompilerContext,
|
||||
FreshNameSupply,
|
||||
InlineContext,
|
||||
ModuleContext
|
||||
}
|
||||
import org.enso.compiler.core.CompilerError
|
||||
import org.enso.compiler.core.CompilerStub
|
||||
import org.enso.compiler.core.IR
|
||||
@ -20,12 +24,11 @@ import org.enso.compiler.phase.{
|
||||
import org.enso.editions.LibraryName
|
||||
import org.enso.interpreter.node.{ExpressionNode => RuntimeExpression}
|
||||
import org.enso.interpreter.runtime.builtin.Builtins
|
||||
import org.enso.interpreter.runtime.scope.{LocalScope, ModuleScope}
|
||||
import org.enso.interpreter.runtime.{EnsoContext, Module}
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.polyglot.{LanguageInfo, RuntimeOptions}
|
||||
//import org.enso.syntax.text.Parser
|
||||
//import org.enso.syntax.text.Parser.IDMap
|
||||
import org.enso.polyglot.LanguageInfo
|
||||
import org.enso.polyglot.CompilationStage
|
||||
import org.enso.syntax2.Tree
|
||||
|
||||
import java.io.{PrintStream, StringReader}
|
||||
@ -47,7 +50,7 @@ import scala.jdk.OptionConverters._
|
||||
* @param context the language context
|
||||
*/
|
||||
class Compiler(
|
||||
val context: EnsoContext,
|
||||
val context: CompilerContext,
|
||||
val builtins: Builtins,
|
||||
val packageRepository: PackageRepository,
|
||||
config: CompilerConfig
|
||||
@ -58,15 +61,11 @@ class Compiler(
|
||||
private val importResolver: ImportResolver = new ImportResolver(this)
|
||||
private val stubsGenerator: RuntimeStubsGenerator =
|
||||
new RuntimeStubsGenerator(builtins)
|
||||
private val irCachingEnabled = !context.isIrCachingDisabled
|
||||
private val useGlobalCacheLocations = context.getEnvironment.getOptions.get(
|
||||
RuntimeOptions.USE_GLOBAL_IR_CACHE_LOCATION_KEY
|
||||
)
|
||||
private val isInteractiveMode =
|
||||
context.getEnvironment.getOptions.get(RuntimeOptions.INTERACTIVE_MODE_KEY)
|
||||
private val irCachingEnabled = !context.isIrCachingDisabled
|
||||
private val useGlobalCacheLocations = context.isUseGlobalCacheLocations
|
||||
private val isInteractiveMode = context.isInteractiveMode()
|
||||
private val serializationManager: SerializationManager =
|
||||
new SerializationManager(this)
|
||||
private val logger: TruffleLogger = context.getLogger(getClass)
|
||||
private val output: PrintStream =
|
||||
if (config.outputRedirect.isDefined)
|
||||
new PrintStream(config.outputRedirect.get)
|
||||
@ -82,7 +81,7 @@ class Compiler(
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingDeque[Runnable](),
|
||||
(runnable: Runnable) => {
|
||||
context.getEnvironment.createThread(runnable)
|
||||
context.createThread(runnable)
|
||||
}
|
||||
)
|
||||
} else null
|
||||
@ -108,7 +107,7 @@ class Compiler(
|
||||
/** Lazy-initializes the IR for the builtins module. */
|
||||
private def initializeBuiltinsIr(): Unit = {
|
||||
if (!builtins.isIrInitialized) {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Initialising IR for [{0}].",
|
||||
builtins.getModule.getName
|
||||
@ -120,20 +119,28 @@ class Compiler(
|
||||
serializationManager.deserialize(builtins.getModule) match {
|
||||
case Some(true) =>
|
||||
// Ensure that builtins doesn't try and have codegen run on it.
|
||||
builtins.getModule.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_CODEGEN
|
||||
context.updateModule(
|
||||
builtins.getModule,
|
||||
{ u =>
|
||||
u.compilationStage(CompilationStage.AFTER_CODEGEN)
|
||||
}
|
||||
)
|
||||
case _ =>
|
||||
builtins.initializeBuiltinsIr(freshNameSupply, passes)
|
||||
builtins.getModule.setHasCrossModuleLinks(true)
|
||||
|
||||
builtins.initializeBuiltinsIr(context, freshNameSupply, passes)
|
||||
context.updateModule(
|
||||
builtins.getModule,
|
||||
u => u.hasCrossModuleLinks(true)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
builtins.initializeBuiltinsIr(freshNameSupply, passes)
|
||||
builtins.getModule.setHasCrossModuleLinks(true)
|
||||
builtins.initializeBuiltinsIr(context, freshNameSupply, passes)
|
||||
context.updateModule(
|
||||
builtins.getModule,
|
||||
u => u.hasCrossModuleLinks(true)
|
||||
)
|
||||
}
|
||||
|
||||
if (irCachingEnabled && !builtins.getModule.wasLoadedFromCache()) {
|
||||
if (irCachingEnabled && !context.wasLoadedFromCache(builtins.getModule)) {
|
||||
serializationManager.serializeModule(
|
||||
builtins.getModule,
|
||||
useGlobalCacheLocations = true // Builtins can't have a local cache.
|
||||
@ -146,6 +153,10 @@ class Compiler(
|
||||
def getSerializationManager: SerializationManager =
|
||||
serializationManager
|
||||
|
||||
/** @return the package repository instance. */
|
||||
def getPackageRepository(): PackageRepository =
|
||||
context.getPackageRepository
|
||||
|
||||
/** Processes the provided language sources, registering any bindings in the
|
||||
* given scope.
|
||||
*
|
||||
@ -173,11 +184,9 @@ class Compiler(
|
||||
shouldCompileDependencies: Boolean,
|
||||
useGlobalCacheLocations: Boolean
|
||||
): Future[Boolean] = {
|
||||
val packageRepository = context.getPackageRepository
|
||||
|
||||
packageRepository.getMainProjectPackage match {
|
||||
getPackageRepository().getMainProjectPackage match {
|
||||
case None =>
|
||||
logger.log(
|
||||
context.log(
|
||||
Level.SEVERE,
|
||||
"No package found in the compiler environment. Aborting."
|
||||
)
|
||||
@ -188,14 +197,14 @@ class Compiler(
|
||||
)
|
||||
packageModule match {
|
||||
case None =>
|
||||
logger.log(
|
||||
context.log(
|
||||
Level.SEVERE,
|
||||
"Could not find entry point for compilation in package [{0}.{1}]",
|
||||
Array(pkg.namespace, pkg.name)
|
||||
)
|
||||
CompletableFuture.completedFuture(false)
|
||||
case Some(m) =>
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
s"Compiling the package [${pkg.namespace}.${pkg.name}] " +
|
||||
s"starting at the root [${m.getName}]."
|
||||
@ -273,25 +282,25 @@ class Compiler(
|
||||
var requiredModules = modules.flatMap { module =>
|
||||
val importedModules = runImportsAndExportsResolution(module, generateCode)
|
||||
val isLoadedFromSource =
|
||||
(m: Module) => !m.wasLoadedFromCache() && !m.isSynthetic
|
||||
(m: Module) => !context.wasLoadedFromCache(m) && !context.isSynthetic(m)
|
||||
if (
|
||||
shouldCompileDependencies &&
|
||||
module.wasLoadedFromCache() &&
|
||||
context.wasLoadedFromCache(module) &&
|
||||
importedModules.exists(isLoadedFromSource)
|
||||
) {
|
||||
val importedModulesLoadedFromSource = importedModules
|
||||
.filter(isLoadedFromSource)
|
||||
.map(_.getName)
|
||||
logger.log(
|
||||
.map(context.getModuleName(_))
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"{0} imported module caches were invalided, forcing invalidation of {1}. [{2}]",
|
||||
Array(
|
||||
importedModulesLoadedFromSource.length,
|
||||
module.getName.toString,
|
||||
context.getModuleName(module).toString,
|
||||
importedModulesLoadedFromSource.take(10).mkString("", ",", "...")
|
||||
)
|
||||
)
|
||||
module.getCache.invalidate(context)
|
||||
context.updateModule(module, _.invalidateCache)
|
||||
parseModule(module)
|
||||
runImportsAndExportsResolution(module, generateCode)
|
||||
} else {
|
||||
@ -302,22 +311,25 @@ class Compiler(
|
||||
var hasInvalidModuleRelink = false
|
||||
if (irCachingEnabled) {
|
||||
requiredModules.foreach { module =>
|
||||
if (!module.hasCrossModuleLinks) {
|
||||
if (!context.hasCrossModuleLinks(module)) {
|
||||
val flags =
|
||||
module.getIr.preorder.map(_.passData.restoreFromSerialization(this))
|
||||
context
|
||||
.getIr(module)
|
||||
.preorder
|
||||
.map(_.passData.restoreFromSerialization(this))
|
||||
|
||||
if (!flags.contains(false)) {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Restored links (late phase) for module [{0}].",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
} else {
|
||||
hasInvalidModuleRelink = true
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Failed to restore links (late phase) for module [{0}].",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
uncachedParseModule(module, isGenDocs = false)
|
||||
}
|
||||
@ -326,7 +338,7 @@ class Compiler(
|
||||
}
|
||||
|
||||
if (hasInvalidModuleRelink) {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
s"Some modules failed to relink. Re-running import and " +
|
||||
s"export resolution."
|
||||
@ -338,9 +350,11 @@ class Compiler(
|
||||
|
||||
requiredModules.foreach { module =>
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_GLOBAL_TYPES
|
||||
)
|
||||
!context
|
||||
.getCompilationStage(module)
|
||||
.isAtLeast(
|
||||
CompilationStage.AFTER_GLOBAL_TYPES
|
||||
)
|
||||
) {
|
||||
|
||||
val moduleContext = ModuleContext(
|
||||
@ -348,18 +362,25 @@ class Compiler(
|
||||
freshNameSupply = Some(freshNameSupply),
|
||||
compilerConfig = config
|
||||
)
|
||||
val compilerOutput = runGlobalTypingPasses(module.getIr, moduleContext)
|
||||
module.unsafeSetIr(compilerOutput)
|
||||
module.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_GLOBAL_TYPES
|
||||
val compilerOutput =
|
||||
runGlobalTypingPasses(context.getIr(module), moduleContext)
|
||||
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(compilerOutput)
|
||||
u.compilationStage(CompilationStage.AFTER_GLOBAL_TYPES)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
requiredModules.foreach { module =>
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_STATIC_PASSES
|
||||
)
|
||||
!context
|
||||
.getCompilationStage(module)
|
||||
.isAtLeast(
|
||||
CompilationStage.AFTER_STATIC_PASSES
|
||||
)
|
||||
) {
|
||||
|
||||
val moduleContext = ModuleContext(
|
||||
@ -368,10 +389,14 @@ class Compiler(
|
||||
compilerConfig = config,
|
||||
pkgRepo = Some(packageRepository)
|
||||
)
|
||||
val compilerOutput = runMethodBodyPasses(module.getIr, moduleContext)
|
||||
module.unsafeSetIr(compilerOutput)
|
||||
module.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_STATIC_PASSES
|
||||
val compilerOutput =
|
||||
runMethodBodyPasses(context.getIr(module), moduleContext)
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(compilerOutput)
|
||||
u.compilationStage(CompilationStage.AFTER_STATIC_PASSES)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -380,40 +405,52 @@ class Compiler(
|
||||
|
||||
requiredModules.foreach { module =>
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_RUNTIME_STUBS
|
||||
)
|
||||
!context
|
||||
.getCompilationStage(module)
|
||||
.isAtLeast(
|
||||
CompilationStage.AFTER_RUNTIME_STUBS
|
||||
)
|
||||
) {
|
||||
stubsGenerator.run(module)
|
||||
module.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_RUNTIME_STUBS
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.compilationStage(CompilationStage.AFTER_RUNTIME_STUBS)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
requiredModules.foreach { module =>
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_CODEGEN
|
||||
)
|
||||
!context
|
||||
.getCompilationStage(module)
|
||||
.isAtLeast(
|
||||
CompilationStage.AFTER_CODEGEN
|
||||
)
|
||||
) {
|
||||
|
||||
if (generateCode) {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Generating code for module [{0}].",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
|
||||
truffleCodegen(module.getIr, module.getSource, module.getScope)
|
||||
context.truffleRunCodegen(module, config)
|
||||
}
|
||||
module.unsafeSetCompilationStage(Module.CompilationStage.AFTER_CODEGEN)
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.compilationStage(CompilationStage.AFTER_CODEGEN)
|
||||
}
|
||||
)
|
||||
|
||||
if (shouldCompileDependencies || isModuleInRootPackage(module)) {
|
||||
val shouldStoreCache =
|
||||
irCachingEnabled && !module.wasLoadedFromCache()
|
||||
irCachingEnabled && !context.wasLoadedFromCache(module)
|
||||
if (shouldStoreCache && !hasErrors(module) && !module.isInteractive) {
|
||||
if (isInteractiveMode) {
|
||||
context.getNotificationHandler.serializeModule(module.getName)
|
||||
context.notifySerializeModule(context.getModuleName(module))
|
||||
} else {
|
||||
serializationManager.serializeModule(
|
||||
module,
|
||||
@ -422,10 +459,10 @@ class Compiler(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Skipping serialization for [{0}].",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -435,11 +472,11 @@ class Compiler(
|
||||
}
|
||||
|
||||
private def isModuleInRootPackage(module: Module): Boolean = {
|
||||
if (!module.isInteractive) {
|
||||
if (!context.isInteractive(module)) {
|
||||
val pkg = PackageRepositoryUtils
|
||||
.getPackageOf(context.getPackageRepository, module.getSourceFile)
|
||||
.getPackageOf(getPackageRepository(), module.getSourceFile)
|
||||
.toScala
|
||||
pkg.contains(context.getPackageRepository.getMainProjectPackage.get)
|
||||
pkg.contains(getPackageRepository().getMainProjectPackage.get)
|
||||
} else false
|
||||
}
|
||||
|
||||
@ -483,7 +520,7 @@ class Compiler(
|
||||
|
||||
private def ensureParsedAndAnalyzed(module: Module): Unit = {
|
||||
ensureParsed(module)
|
||||
if (module.isSynthetic) {
|
||||
if (context.isSynthetic(module)) {
|
||||
// Synthetic modules need to be import-analyzed
|
||||
// i.e. we need to fill in resolved{Imports/Exports} and exportedSymbols in bindings
|
||||
// because we do not generate (and deserialize) IR for them
|
||||
@ -495,7 +532,7 @@ class Compiler(
|
||||
.map { concreteBindings =>
|
||||
concreteBindings
|
||||
}
|
||||
val ir = module.getIr
|
||||
val ir = context.getIr(module)
|
||||
val currentLocal = ir.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Synthetic parsed module missing bindings"
|
||||
@ -524,7 +561,7 @@ class Compiler(
|
||||
*/
|
||||
def gatherImportStatements(module: Module): Array[String] = {
|
||||
ensureParsed(module)
|
||||
val importedModules = module.getIr.imports.flatMap {
|
||||
val importedModules = context.getIr(module).imports.flatMap {
|
||||
case imp: IR.Module.Scope.Import.Module =>
|
||||
imp.name.parts.take(2).map(_.name) match {
|
||||
case List(namespace, name) => List(LibraryName(namespace, name))
|
||||
@ -537,7 +574,8 @@ class Compiler(
|
||||
Nil
|
||||
case other =>
|
||||
throw new CompilerError(
|
||||
s"Unexpected import type after processing ${module.getName}: [$other]."
|
||||
s"Unexpected import type after processing ${context
|
||||
.getModuleName(module)}: [$other]."
|
||||
)
|
||||
}
|
||||
importedModules.distinct.map(_.qualifiedName).toArray
|
||||
@ -547,15 +585,14 @@ class Compiler(
|
||||
module: Module,
|
||||
isGenDocs: Boolean = false
|
||||
): Unit = {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Parsing module [{0}].",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
module.ensureScopeExists()
|
||||
module.getScope.reset()
|
||||
context.updateModule(module, _.resetScope)
|
||||
|
||||
if (irCachingEnabled && !module.isInteractive) {
|
||||
if (irCachingEnabled && !context.isInteractive(module)) {
|
||||
serializationManager.deserialize(module) match {
|
||||
case Some(_) => return
|
||||
case _ =>
|
||||
@ -571,7 +608,7 @@ class Compiler(
|
||||
* @return module's bindings, if available in libraries' bindings cache
|
||||
*/
|
||||
def importExportBindings(module: Module): Option[BindingsMap] = {
|
||||
if (irCachingEnabled && !module.isInteractive) {
|
||||
if (irCachingEnabled && !context.isInteractive(module)) {
|
||||
val libraryName = Option(module.getPackage).map(_.libraryName)
|
||||
libraryName
|
||||
.flatMap(packageRepository.getLibraryBindings(_, serializationManager))
|
||||
@ -580,13 +617,12 @@ class Compiler(
|
||||
}
|
||||
|
||||
private def uncachedParseModule(module: Module, isGenDocs: Boolean): Unit = {
|
||||
logger.log(
|
||||
context.log(
|
||||
Compiler.defaultLogLevel,
|
||||
"Loading module [{0}] from source.",
|
||||
module.getName
|
||||
context.getModuleName(module)
|
||||
)
|
||||
module.ensureScopeExists()
|
||||
module.getScope.reset()
|
||||
context.updateModule(module, _.resetScope)
|
||||
|
||||
val moduleContext = ModuleContext(
|
||||
module = module,
|
||||
@ -595,21 +631,26 @@ class Compiler(
|
||||
isGeneratingDocs = isGenDocs
|
||||
)
|
||||
|
||||
val src = module.getSource
|
||||
val tree = ensoCompiler.parse(src.getCharacters)
|
||||
val src = context.getCharacters(module)
|
||||
val tree = ensoCompiler.parse(src)
|
||||
val expr = ensoCompiler.generateIR(tree)
|
||||
|
||||
val exprWithModuleExports =
|
||||
if (module.isSynthetic)
|
||||
if (context.isSynthetic(module))
|
||||
expr
|
||||
else
|
||||
injectSyntheticModuleExports(expr, module.getDirectModulesRefs)
|
||||
val discoveredModule =
|
||||
recognizeBindings(exprWithModuleExports, moduleContext)
|
||||
module.unsafeSetIr(discoveredModule)
|
||||
module.unsafeSetCompilationStage(Module.CompilationStage.AFTER_PARSING)
|
||||
module.setLoadedFromCache(false)
|
||||
module.setHasCrossModuleLinks(true)
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(discoveredModule)
|
||||
u.compilationStage(CompilationStage.AFTER_PARSING)
|
||||
u.loadedFromCache(false)
|
||||
u.hasCrossModuleLinks(true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/* Note [Polyglot Imports In Dependency Gathering]
|
||||
@ -640,9 +681,11 @@ class Compiler(
|
||||
*/
|
||||
def ensureParsed(module: Module): Unit = {
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_PARSING
|
||||
)
|
||||
!context
|
||||
.getCompilationStage(module)
|
||||
.isAtLeast(
|
||||
CompilationStage.AFTER_PARSING
|
||||
)
|
||||
) {
|
||||
parseModule(module)
|
||||
}
|
||||
@ -703,7 +746,7 @@ class Compiler(
|
||||
}
|
||||
if (
|
||||
!module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_RUNTIME_STUBS
|
||||
CompilationStage.AFTER_RUNTIME_STUBS
|
||||
)
|
||||
) {
|
||||
throw new CompilerError(
|
||||
@ -903,7 +946,7 @@ class Compiler(
|
||||
def gatherDiagnostics(module: Module): List[IR.Diagnostic] = {
|
||||
GatherDiagnostics
|
||||
.runModule(
|
||||
module.getIr,
|
||||
context.getIr(module),
|
||||
ModuleContext(module, compilerConfig = config)
|
||||
)
|
||||
.unsafeGetMetadata(
|
||||
@ -1212,7 +1255,7 @@ class Compiler(
|
||||
source: Source,
|
||||
scope: ModuleScope
|
||||
): Unit = {
|
||||
new IrToTruffle(context, source, scope, config).run(ir)
|
||||
context.truffleRunCodegen(source, scope, config, ir)
|
||||
}
|
||||
|
||||
/** Generates code for the truffle interpreter in an inline context.
|
||||
@ -1228,16 +1271,7 @@ class Compiler(
|
||||
source: Source,
|
||||
inlineContext: InlineContext
|
||||
): RuntimeExpression = {
|
||||
new IrToTruffle(
|
||||
context,
|
||||
source,
|
||||
inlineContext.module.getScope,
|
||||
config
|
||||
).runInline(
|
||||
ir,
|
||||
inlineContext.localScope.getOrElse(LocalScope.root),
|
||||
"<inline_source>"
|
||||
)
|
||||
context.truffleRunInline(source, inlineContext, config, ir);
|
||||
}
|
||||
|
||||
/** Performs shutdown actions for the compiler.
|
||||
|
@ -29,6 +29,7 @@ import org.enso.pkg.{
|
||||
SourceFile
|
||||
}
|
||||
import org.enso.text.buffer.Rope
|
||||
import org.enso.polyglot.CompilationStage
|
||||
|
||||
import java.nio.file.Path
|
||||
import scala.collection.immutable.ListSet
|
||||
@ -292,7 +293,7 @@ object PackageRepository {
|
||||
module <- getComponentModules
|
||||
isCompiled =
|
||||
module.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_CODEGEN
|
||||
CompilationStage.AFTER_CODEGEN
|
||||
)
|
||||
if !isCompiled
|
||||
} yield module
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.enso.compiler
|
||||
|
||||
import com.oracle.truffle.api.TruffleLogger
|
||||
import com.oracle.truffle.api.source.Source
|
||||
import org.enso.compiler.context.{ExportsBuilder, ExportsMap, SuggestionBuilder}
|
||||
import org.enso.compiler.core.IR
|
||||
@ -9,6 +8,7 @@ import org.enso.editions.LibraryName
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.polyglot.Suggestion
|
||||
import org.enso.polyglot.CompilationStage
|
||||
|
||||
import java.io.NotSerializableException
|
||||
import java.util
|
||||
@ -35,10 +35,6 @@ final class SerializationManager(
|
||||
/** The debug logging level. */
|
||||
private val debugLogLevel = Level.FINE
|
||||
|
||||
/** A logger for messages regarding serialization. */
|
||||
private val logger: TruffleLogger =
|
||||
compiler.context.getLogger(classOf[SerializationManager])
|
||||
|
||||
/** A set of the modules that are currently being serialized.
|
||||
*
|
||||
* This set is accessed concurrently. This is safe as it is backed by a
|
||||
@ -54,9 +50,6 @@ final class SerializationManager(
|
||||
private val isWaitingForSerialization =
|
||||
collection.concurrent.TrieMap[QualifiedName, Future[Boolean]]()
|
||||
|
||||
/** The runtime's environment. */
|
||||
private val env = compiler.context.getEnvironment
|
||||
|
||||
/** The thread pool that handles serialization. */
|
||||
private val pool: ThreadPoolExecutor = new ThreadPoolExecutor(
|
||||
SerializationManager.startingThreadCount,
|
||||
@ -65,13 +58,13 @@ final class SerializationManager(
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingDeque[Runnable](),
|
||||
(runnable: Runnable) => {
|
||||
env.createSystemThread(runnable)
|
||||
compiler.context.createSystemThread(runnable)
|
||||
}
|
||||
)
|
||||
|
||||
// Make sure it is started to avoid races with language shutdown with low job
|
||||
// count.
|
||||
if (compiler.context.getEnvironment.isCreateThreadAllowed) {
|
||||
if (compiler.context.isCreateThreadAllowed) {
|
||||
pool.prestartAllCoreThreads()
|
||||
}
|
||||
|
||||
@ -103,7 +96,7 @@ final class SerializationManager(
|
||||
useGlobalCacheLocations: Boolean,
|
||||
useThreadPool: Boolean = true
|
||||
): Future[Boolean] = {
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Requesting serialization for module [{0}].",
|
||||
module.getName
|
||||
@ -133,7 +126,7 @@ final class SerializationManager(
|
||||
CompletableFuture.completedFuture(task.call())
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
s"Serialization task failed in module [${module.getName}].",
|
||||
e
|
||||
@ -147,7 +140,7 @@ final class SerializationManager(
|
||||
libraryName: LibraryName,
|
||||
useGlobalCacheLocations: Boolean
|
||||
): Future[Boolean] = {
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.INFO,
|
||||
"Requesting serialization for library [{0}].",
|
||||
libraryName
|
||||
@ -155,7 +148,7 @@ final class SerializationManager(
|
||||
|
||||
val task: Callable[Boolean] =
|
||||
doSerializeLibrary(libraryName, useGlobalCacheLocations)
|
||||
if (compiler.context.getEnvironment.isCreateThreadAllowed) {
|
||||
if (compiler.context.isCreateThreadAllowed) {
|
||||
isWaitingForSerialization.synchronized {
|
||||
val future = pool.submit(task)
|
||||
isWaitingForSerialization.put(libraryName.toQualifiedName, future)
|
||||
@ -166,7 +159,7 @@ final class SerializationManager(
|
||||
CompletableFuture.completedFuture(task.call())
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
s"Serialization task failed for library [$libraryName].",
|
||||
e
|
||||
@ -184,7 +177,7 @@ final class SerializationManager(
|
||||
Thread.sleep(100)
|
||||
}
|
||||
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Running serialization for bindings [{0}].",
|
||||
libraryName
|
||||
@ -213,19 +206,23 @@ final class SerializationManager(
|
||||
try {
|
||||
val result =
|
||||
try {
|
||||
new ImportExportCache(libraryName)
|
||||
.save(bindingsCache, compiler.context, useGlobalCacheLocations)
|
||||
.isPresent
|
||||
val cache = new ImportExportCache(libraryName)
|
||||
val file = compiler.context.saveCache(
|
||||
cache,
|
||||
bindingsCache,
|
||||
useGlobalCacheLocations
|
||||
)
|
||||
file.isPresent
|
||||
} catch {
|
||||
case e: NotSerializableException =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Could not serialize bindings [$libraryName].",
|
||||
e
|
||||
)
|
||||
throw e
|
||||
case e: Throwable =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Serialization of bindings `$libraryName` failed: ${e.getMessage}`",
|
||||
e
|
||||
@ -275,19 +272,23 @@ final class SerializationManager(
|
||||
.getPackageForLibraryJava(libraryName)
|
||||
.map(_.listSourcesJava())
|
||||
)
|
||||
new SuggestionsCache(libraryName)
|
||||
.save(cachedSuggestions, compiler.context, useGlobalCacheLocations)
|
||||
.isPresent
|
||||
val cache = new SuggestionsCache(libraryName)
|
||||
val file = compiler.context.saveCache(
|
||||
cache,
|
||||
cachedSuggestions,
|
||||
useGlobalCacheLocations
|
||||
)
|
||||
file.isPresent
|
||||
} catch {
|
||||
case e: NotSerializableException =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Could not serialize suggestions [$libraryName].",
|
||||
e
|
||||
)
|
||||
throw e
|
||||
case e: Throwable =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Serialization of suggestions `$libraryName` failed: ${e.getMessage}`",
|
||||
e
|
||||
@ -306,16 +307,17 @@ final class SerializationManager(
|
||||
while (isSerializingLibrary(libraryName)) {
|
||||
Thread.sleep(100)
|
||||
}
|
||||
new SuggestionsCache(libraryName).load(compiler.context).toScala match {
|
||||
val cache = new SuggestionsCache(libraryName)
|
||||
compiler.context.loadCache(cache).toScala match {
|
||||
case result @ Some(_: SuggestionsCache.CachedSuggestions) =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.FINE,
|
||||
"Restored suggestions for library [{0}].",
|
||||
libraryName
|
||||
)
|
||||
result
|
||||
case _ =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.FINEST,
|
||||
"Unable to load suggestions for library [{0}].",
|
||||
libraryName
|
||||
@ -335,16 +337,17 @@ final class SerializationManager(
|
||||
while (isSerializingLibrary(libraryName)) {
|
||||
Thread.sleep(100)
|
||||
}
|
||||
new ImportExportCache(libraryName).load(compiler.context).toScala match {
|
||||
val cache = new ImportExportCache(libraryName)
|
||||
compiler.context.loadCache(cache).toScala match {
|
||||
case result @ Some(_: ImportExportCache.CachedBindings) =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.FINE,
|
||||
"Restored bindings for library [{0}].",
|
||||
libraryName
|
||||
)
|
||||
result
|
||||
case _ =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.FINEST,
|
||||
"Unable to load bindings for library [{0}].",
|
||||
libraryName
|
||||
@ -376,41 +379,46 @@ final class SerializationManager(
|
||||
Thread.sleep(100)
|
||||
}
|
||||
|
||||
module.getCache.load(compiler.context).toScala match {
|
||||
compiler.context.loadCache(module.getCache).toScala match {
|
||||
case Some(loadedCache) =>
|
||||
val relinkedIrChecks =
|
||||
loadedCache
|
||||
.moduleIR()
|
||||
.preorder
|
||||
.map(_.passData.restoreFromSerialization(this.compiler))
|
||||
module.unsafeSetIr(loadedCache.moduleIR())
|
||||
module.unsafeSetCompilationStage(loadedCache.compilationStage())
|
||||
module.setLoadedFromCache(true)
|
||||
logger.log(
|
||||
compiler.context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(loadedCache.moduleIR())
|
||||
u.compilationStage(loadedCache.compilationStage())
|
||||
u.loadedFromCache(true)
|
||||
}
|
||||
)
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Restored IR from cache for module [{0}] at stage [{1}].",
|
||||
Array[Object](module.getName, loadedCache.compilationStage())
|
||||
)
|
||||
|
||||
if (!relinkedIrChecks.contains(false)) {
|
||||
module.setHasCrossModuleLinks(true)
|
||||
logger.log(
|
||||
compiler.context.updateModule(module, _.hasCrossModuleLinks(true))
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Restored links (early phase) in module [{0}].",
|
||||
module.getName
|
||||
)
|
||||
Some(true)
|
||||
} else {
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Could not restore links (early phase) in module [{0}].",
|
||||
module.getName
|
||||
)
|
||||
module.setHasCrossModuleLinks(false)
|
||||
compiler.context.updateModule(module, _.hasCrossModuleLinks(false))
|
||||
Some(false)
|
||||
}
|
||||
case None =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Unable to load a cache for module [{0}].",
|
||||
module.getName
|
||||
@ -507,7 +515,7 @@ final class SerializationManager(
|
||||
isWaitingForSerialization.size
|
||||
}
|
||||
val jobCount = waitingCount + isSerializing.size
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Waiting for #{0} serialization jobs to complete.",
|
||||
jobCount
|
||||
@ -534,7 +542,10 @@ final class SerializationManager(
|
||||
|
||||
pool.shutdownNow()
|
||||
Thread.sleep(100)
|
||||
logger.log(debugLogLevel, "Serialization manager has been shut down.")
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Serialization manager has been shut down."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -562,7 +573,7 @@ final class SerializationManager(
|
||||
private def doSerializeModule(
|
||||
cache: ModuleCache,
|
||||
ir: IR.Module,
|
||||
stage: Module.CompilationStage,
|
||||
stage: CompilationStage,
|
||||
name: QualifiedName,
|
||||
source: Source,
|
||||
useGlobalCacheLocations: Boolean
|
||||
@ -571,7 +582,7 @@ final class SerializationManager(
|
||||
Thread.sleep(100)
|
||||
}
|
||||
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
debugLogLevel,
|
||||
"Running serialization for module [{0}].",
|
||||
name
|
||||
@ -579,27 +590,27 @@ final class SerializationManager(
|
||||
startSerializing(name)
|
||||
try {
|
||||
val fixedStage =
|
||||
if (stage.isAtLeast(Module.CompilationStage.AFTER_STATIC_PASSES)) {
|
||||
Module.CompilationStage.AFTER_STATIC_PASSES
|
||||
if (stage.isAtLeast(CompilationStage.AFTER_STATIC_PASSES)) {
|
||||
CompilationStage.AFTER_STATIC_PASSES
|
||||
} else stage
|
||||
cache
|
||||
.save(
|
||||
compiler.context
|
||||
.saveCache(
|
||||
cache,
|
||||
new ModuleCache.CachedModule(ir, fixedStage, source),
|
||||
compiler.context,
|
||||
useGlobalCacheLocations
|
||||
)
|
||||
.map(_ => true)
|
||||
.orElse(false)
|
||||
} catch {
|
||||
case e: NotSerializableException =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Could not serialize module [$name].",
|
||||
e
|
||||
)
|
||||
throw e
|
||||
case e: Throwable =>
|
||||
logger.log(
|
||||
compiler.context.logSerializationManager(
|
||||
Level.SEVERE,
|
||||
s"Serialization of module `$name` failed: ${e.getMessage}`",
|
||||
e
|
||||
|
@ -56,7 +56,7 @@ case class BindingsMap(
|
||||
override def restoreFromSerialization(
|
||||
compiler: Compiler
|
||||
): Option[BindingsMap] = {
|
||||
val packageRepository = compiler.context.getPackageRepository
|
||||
val packageRepository = compiler.getPackageRepository()
|
||||
this.toConcrete(packageRepository.getModuleMap)
|
||||
}
|
||||
|
||||
@ -992,7 +992,7 @@ object BindingsMap {
|
||||
override def restoreFromSerialization(
|
||||
compiler: Compiler
|
||||
): Option[Resolution] = {
|
||||
val moduleMap = compiler.context.getPackageRepository.getModuleMap
|
||||
val moduleMap = compiler.getPackageRepository().getModuleMap
|
||||
this.target.toConcrete(moduleMap).map(t => this.copy(target = t))
|
||||
}
|
||||
|
||||
|
@ -427,7 +427,7 @@ case object FullyQualifiedNames extends IRPass {
|
||||
override def restoreFromSerialization(
|
||||
compiler: Compiler
|
||||
): Option[PartiallyResolvedFQN] = {
|
||||
val packageRepository = compiler.context.getPackageRepository
|
||||
val packageRepository = compiler.getPackageRepository()
|
||||
moduleRef
|
||||
.toConcrete(packageRepository.getModuleMap)
|
||||
.map(ResolvedModule(_))
|
||||
|
@ -2,10 +2,14 @@ package org.enso.compiler.phase
|
||||
|
||||
import org.enso.compiler.core.EnsoParser
|
||||
import org.enso.compiler.Passes
|
||||
import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.context.{
|
||||
CompilerContext,
|
||||
FreshNameSupply,
|
||||
ModuleContext
|
||||
}
|
||||
import org.enso.compiler.data.CompilerConfig
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.interpreter.runtime.Module.CompilationStage
|
||||
import org.enso.polyglot.CompilationStage
|
||||
import scala.util.Using
|
||||
|
||||
/** A phase responsible for initializing the builtins' IR from the provided
|
||||
@ -28,6 +32,7 @@ object BuiltinsIrBuilder {
|
||||
* @param passes the compiler's pass manager
|
||||
*/
|
||||
def build(
|
||||
context: CompilerContext,
|
||||
module: Module,
|
||||
freshNameSupply: FreshNameSupply,
|
||||
passes: Passes
|
||||
@ -46,8 +51,13 @@ object BuiltinsIrBuilder {
|
||||
moduleContext,
|
||||
passes.moduleDiscoveryPasses
|
||||
)
|
||||
module.unsafeSetIr(irAfterModDiscovery)
|
||||
module.unsafeSetCompilationStage(Module.CompilationStage.AFTER_PARSING)
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(irAfterModDiscovery)
|
||||
u.compilationStage(CompilationStage.AFTER_PARSING)
|
||||
}
|
||||
)
|
||||
|
||||
new ExportsResolution().run(List(module))
|
||||
val irAfterTypes = passManager.runPassesOnModule(
|
||||
@ -60,7 +70,12 @@ object BuiltinsIrBuilder {
|
||||
moduleContext,
|
||||
passes.functionBodyPasses
|
||||
)
|
||||
module.unsafeSetIr(irAfterCompilation)
|
||||
module.unsafeSetCompilationStage(CompilationStage.AFTER_CODEGEN)
|
||||
context.updateModule(
|
||||
module,
|
||||
{ u =>
|
||||
u.ir(irAfterCompilation)
|
||||
u.compilationStage(CompilationStage.AFTER_CODEGEN)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import org.enso.compiler.core.CompilerError
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.editions.LibraryName
|
||||
import org.enso.interpreter.runtime.Module
|
||||
|
||||
import org.enso.polyglot.CompilationStage
|
||||
import scala.collection.mutable
|
||||
|
||||
/** Runs imports resolution. Starts from a given module and then recursively
|
||||
@ -23,7 +23,7 @@ import scala.collection.mutable
|
||||
* Each of the reachable modules will be parsed and will have imported modules
|
||||
* injected into its metadata. In effect, running this will bring every module
|
||||
* that could ever be necessary for the entry point compilation to at least
|
||||
* the [[Module.CompilationStage.AFTER_IMPORT_RESOLUTION]] stage.
|
||||
* the [[CompilationStage.AFTER_IMPORT_RESOLUTION]] stage.
|
||||
*
|
||||
* @param compiler the compiler instance for the compiling context.
|
||||
*/
|
||||
@ -42,16 +42,18 @@ class ImportResolver(compiler: Compiler) {
|
||||
): (List[Module], List[Module]) = {
|
||||
|
||||
def analyzeModule(current: Module): List[Module] = {
|
||||
val ir = current.getIr
|
||||
val context = compiler.context
|
||||
val ir = context.getIr(current)
|
||||
val currentLocal = ir.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Non-parsed module used in ImportResolver"
|
||||
)
|
||||
// put the list of resolved imports in the module metadata
|
||||
if (
|
||||
current.getCompilationStage
|
||||
context
|
||||
.getCompilationStage(current)
|
||||
.isBefore(
|
||||
Module.CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
) || !current.hasCrossModuleLinks
|
||||
) {
|
||||
val importedModules: List[
|
||||
@ -64,12 +66,17 @@ class ImportResolver(compiler: Compiler) {
|
||||
}
|
||||
currentLocal.resolvedImports = importedModules.flatMap(_._2)
|
||||
val newIr = ir.copy(imports = importedModules.map(_._1))
|
||||
current.unsafeSetIr(newIr)
|
||||
if (!current.wasLoadedFromCache()) {
|
||||
current.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
)
|
||||
}
|
||||
context.updateModule(
|
||||
current,
|
||||
{ u =>
|
||||
u.ir(newIr)
|
||||
if (!context.wasLoadedFromCache(current)) {
|
||||
u.compilationStage(
|
||||
CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
currentLocal.resolvedImports
|
||||
.map(_.target.module.unsafeAsModule())
|
||||
|
@ -55,7 +55,7 @@ public class SerializerTest {
|
||||
var result = compiler.run(module);
|
||||
assertEquals(result.compiledModules().exists(m -> m == module), true);
|
||||
var serializationManager = new SerializationManager(ensoContext.getCompiler());
|
||||
var useThreadPool = compiler.context().getEnvironment().isCreateThreadAllowed();
|
||||
var useThreadPool = compiler.context().isCreateThreadAllowed();
|
||||
var future = serializationManager.serializeModule(module, true, useThreadPool);
|
||||
var serialized = future.get(5, TimeUnit.SECONDS);
|
||||
assertEquals(serialized, true);
|
||||
|
@ -0,0 +1,16 @@
|
||||
package org.enso.interpreter.runtime;
|
||||
|
||||
import org.enso.compiler.core.IR;
|
||||
import org.enso.polyglot.CompilationStage;
|
||||
|
||||
public final class ModuleTestUtils {
|
||||
private ModuleTestUtils() {}
|
||||
|
||||
public static void unsafeSetIr(Module m, IR.Module ir) {
|
||||
m.unsafeSetIr(ir);
|
||||
}
|
||||
|
||||
public static void unsafeSetCompilationStage(Module m, CompilationStage s) {
|
||||
m.unsafeSetCompilationStage(s);
|
||||
}
|
||||
}
|
@ -11,8 +11,10 @@ import org.enso.compiler.pass.{PassConfiguration, PassManager}
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpecLike
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.interpreter.runtime.ModuleTestUtils
|
||||
import org.enso.interpreter.runtime.scope.LocalScope
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.polyglot.CompilationStage
|
||||
|
||||
trait CompilerTest extends AnyWordSpecLike with Matchers with CompilerRunner
|
||||
trait CompilerRunner {
|
||||
@ -227,7 +229,8 @@ trait CompilerRunner {
|
||||
compilerConfig: CompilerConfig = defaultConfig
|
||||
): InlineContext = {
|
||||
val mod = Module.empty(QualifiedName.simpleName("Test_Module"), null)
|
||||
mod.unsafeSetIr(
|
||||
ModuleTestUtils.unsafeSetIr(
|
||||
mod,
|
||||
IR.Module(List(), List(), List(), None)
|
||||
.updateMetadata(
|
||||
BindingAnalysis -->> BindingsMap(
|
||||
@ -236,7 +239,10 @@ trait CompilerRunner {
|
||||
)
|
||||
)
|
||||
)
|
||||
mod.unsafeSetCompilationStage(Module.CompilationStage.AFTER_CODEGEN)
|
||||
ModuleTestUtils.unsafeSetCompilationStage(
|
||||
mod,
|
||||
CompilationStage.AFTER_CODEGEN
|
||||
)
|
||||
InlineContext(
|
||||
module = mod,
|
||||
freshNameSupply = freshNameSupply,
|
||||
|
@ -14,6 +14,7 @@ import org.enso.compiler.pass.resolve.GlobalNames
|
||||
import org.enso.compiler.pass.{PassConfiguration, PassGroup, PassManager}
|
||||
import org.enso.compiler.phase.ExportsResolution
|
||||
import org.enso.compiler.test.CompilerTest
|
||||
import org.enso.interpreter.runtime.ModuleTestUtils
|
||||
|
||||
class GlobalNamesTest extends CompilerTest {
|
||||
|
||||
@ -81,7 +82,7 @@ class GlobalNamesTest extends CompilerTest {
|
||||
|""".stripMargin
|
||||
val parsed = code.toIrModule
|
||||
val moduleMapped = passManager.runPassesOnModule(parsed, ctx, group1)
|
||||
ctx.module.unsafeSetIr(moduleMapped)
|
||||
ModuleTestUtils.unsafeSetIr(ctx.module, moduleMapped)
|
||||
|
||||
new ExportsResolution().run(List(ctx.module))
|
||||
val allPrecursors = passManager.runPassesOnModule(moduleMapped, ctx, group2)
|
||||
|
Loading…
Reference in New Issue
Block a user