Skip to content

Commit

Permalink
[GR-19119] ContextReference does not work after unsuccessful patch of…
Browse files Browse the repository at this point in the history
… pre-initialized context.
  • Loading branch information
tzezula committed Oct 23, 2019
1 parent c85575f commit f17692a
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ public Object execute(VirtualFrame frame) {
if (msg != null) {
write(lookupContextReference(languageClass).get().environment().err(), msg);
}
assertEquals(0, lookupContextReference(languageClass).get().disposeContextCount);
return result;
}
});
Expand All @@ -1258,7 +1259,7 @@ private static void write(final OutputStream out, final String content) {
}
}

@TruffleLanguage.Registration(id = FIRST, name = FIRST, version = "1.0", dependentLanguages = INTERNAL)
@TruffleLanguage.Registration(id = FIRST, name = FIRST, version = "1.0", dependentLanguages = INTERNAL, contextPolicy = TruffleLanguage.ContextPolicy.SHARED)
public static final class ContextPreInitializationTestFirstLanguage extends BaseLanguage {
@Option(category = OptionCategory.USER, stability = OptionStability.STABLE, help = "Option 1") //
public static final OptionKey<Boolean> Option1 = new OptionKey<>(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ OptionValuesImpl copy() {
return new OptionValuesImpl(this);
}

void copyInto(OptionValuesImpl target) {
if (!target.values.isEmpty()) {
throw new IllegalStateException("Values must be empty.");
}
target.values.putAll(values);
}

public OptionDescriptors getDescriptors() {
return descriptors;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ final class PolyglotEngineImpl extends AbstractPolyglotImpl.AbstractEngineImpl i
final int contextLength;
private volatile EngineLimits limits;
final boolean conservativeContextReferences;
private final MessageTransport messageInterceptor;

PolyglotEngineImpl(PolyglotImpl impl, DispatchOutputStream out, DispatchOutputStream err, InputStream in, Map<String, String> options,
boolean allowExperimentalOptions, boolean useSystemProperties, ClassLoader contextClassLoader, boolean boundEngine,
Expand All @@ -188,6 +189,7 @@ private PolyglotEngineImpl(PolyglotImpl impl, DispatchOutputStream out, Dispatch
boolean allowExperimentalOptions, boolean useSystemProperties, ClassLoader contextClassLoader, boolean boundEngine, boolean preInitialization,
MessageTransport messageInterceptor, Handler logHandler) {
super(impl);
this.messageInterceptor = messageInterceptor;
this.instrumentationHandler = INSTRUMENT.createInstrumentationHandler(this, out, err, in, messageInterceptor);
this.impl = impl;
this.out = out;
Expand Down Expand Up @@ -262,6 +264,88 @@ private PolyglotEngineImpl(PolyglotImpl impl, DispatchOutputStream out, Dispatch
}
}

private PolyglotEngineImpl(PolyglotEngineImpl prototype) {
super(prototype.impl);
this.messageInterceptor = prototype.messageInterceptor;
this.instrumentationHandler = INSTRUMENT.createInstrumentationHandler(this, prototype.out, prototype.err, prototype.in, prototype.messageInterceptor);
this.impl = prototype.impl;
this.out = prototype.out;
this.err = prototype.err;
this.in = prototype.in;
this.contextClassLoader = prototype.contextClassLoader;
this.boundEngine = prototype.boundEngine;
this.logHandler = prototype.logHandler;
this.castUnsafe = EngineAccessor.ACCESSOR.getCastUnsafe();

Map<String, LanguageInfo> languageInfos = new LinkedHashMap<>();
this.idToLanguage = Collections.unmodifiableMap(initializeLanguages(languageInfos));
this.idToInternalLanguageInfo = Collections.unmodifiableMap(languageInfos);
this.contextLength = idToLanguage.size() + 1 /* +1 for host language */;

Map<String, InstrumentInfo> instrumentInfos = new LinkedHashMap<>();
this.idToInstrument = Collections.unmodifiableMap(initializeInstruments(instrumentInfos));
this.idToInternalInstrumentInfo = Collections.unmodifiableMap(instrumentInfos);

this.classToLanguage = new HashMap<>();
for (PolyglotLanguage language : idToLanguage.values()) {
classToLanguage.put(language.cache.getClassName(), language);
}

for (String id : idToLanguage.keySet()) {
if (idToInstrument.containsKey(id)) {
throw failDuplicateId(id,
idToLanguage.get(id).cache.getClassName(),
idToInstrument.get(id).cache.getClassName());
}
}

this.engineOptions = createEngineOptionDescriptors();
this.engineOptionValues = new OptionValuesImpl(this, engineOptions);

Map<String, Language> publicLanguages = new LinkedHashMap<>();
for (String key : this.idToLanguage.keySet()) {
PolyglotLanguage languageImpl = idToLanguage.get(key);
if (!languageImpl.cache.isInternal()) {
publicLanguages.put(key, languageImpl.api);
}
}
idToPublicLanguage = Collections.unmodifiableMap(publicLanguages);

Map<String, Instrument> publicInstruments = new LinkedHashMap<>();
for (String key : this.idToInstrument.keySet()) {
PolyglotInstrument instrumentImpl = idToInstrument.get(key);
if (!instrumentImpl.cache.isInternal()) {
publicInstruments.put(key, instrumentImpl.api);
}
}
idToPublicInstrument = Collections.unmodifiableMap(publicInstruments);

logLevels = prototype.logLevels;

prototype.engineOptionValues.copyInto(this.engineOptionValues);
this.conservativeContextReferences = engineOptionValues.get(PolyglotEngineOptions.UseConservativeContextReferences);

for (String languageId : idToLanguage.keySet()) {
OptionValuesImpl prototypeOptions = prototype.idToLanguage.get(languageId).getOptionValuesIfExists();
if (prototypeOptions != null) {
prototypeOptions.copyInto(idToLanguage.get(languageId).getOptionValues());
}
}

ENGINES.put(this, null);
Collection<PolyglotInstrument> instrumentsToCreate = new ArrayList<>();
for (String instrumentId : idToInstrument.keySet()) {
OptionValuesImpl prototypeOptions = prototype.idToInstrument.get(instrumentId).getOptionValuesIfExists();
if (prototypeOptions != null) {
PolyglotInstrument instrument = idToInstrument.get(instrumentId);
prototypeOptions.copyInto(instrument.getOptionValues());
instrumentsToCreate.add(instrument);
}
}
ensureInstrumentsCreated(instrumentsToCreate);
registerShutDownHook();
}

private static OptionDescriptors createEngineOptionDescriptors() {
OptionDescriptors engineOptionDescriptors = new PolyglotEngineOptionsOptionDescriptors();
OptionDescriptors compilerOptionDescriptors = EngineAccessor.ACCESSOR.getCompilerOptions();
Expand Down Expand Up @@ -315,9 +399,12 @@ private void createInstruments(Map<PolyglotInstrument, Map<String, String>> inst
for (PolyglotInstrument instrument : instrumentsOptions.keySet()) {
instrument.getOptionValues().putAll(instrumentsOptions.get(instrument), allowExperimentalOptions);
}
ensureInstrumentsCreated(instrumentsOptions.keySet());
}

private void ensureInstrumentsCreated(Collection<? extends PolyglotInstrument> instruments) {
try {
for (PolyglotInstrument instrument : instrumentsOptions.keySet()) {
for (PolyglotInstrument instrument : instruments) {
// we got options for this instrument -> create it.
instrument.ensureCreated();
}
Expand Down Expand Up @@ -1259,10 +1346,6 @@ public synchronized Context createContext(OutputStream configOut, OutputStream c
throw new IllegalArgumentException("Cannot allow EnvironmentAccess because the privilege is removed at image build time");
}
PolyglotLimits polyglotLimits = (PolyglotLimits) limitsImpl;
if (limits != null) {
limits.validate(polyglotLimits);
}

PolyglotContextConfig config = new PolyglotContextConfig(this, useOut, useErr, useIn,
allowHostLookup, polyglotAccess, allowNativeAccess, allowCreateThread, allowHostClassLoading,
allowExperimentalOptions, classFilter, arguments, allowedLanguages, options, fs, internalFs, useHandler, allowCreateProcess, useProcessHandler,
Expand All @@ -1272,20 +1355,26 @@ public synchronized Context createContext(OutputStream configOut, OutputStream c
if (context == null) {
context = new PolyglotContextImpl(this, config);
}
addContext(context);
PolyglotEngineImpl engine = context.getEngine();
synchronized (engine) {
if (engine.limits != null) {
engine.limits.validate(polyglotLimits);
}
engine.addContext(context);

if (polyglotLimits != null) {
EngineLimits l = this.limits;
if (l == null) {
this.limits = l = new EngineLimits(this);
if (polyglotLimits != null) {
EngineLimits l = engine.limits;
if (l == null) {
engine.limits = l = new EngineLimits(engine);
}
l.initialize(polyglotLimits, context);
}
l.initialize(polyglotLimits, context);
}

Context api = impl.getAPIAccess().newContext(context);
context.creatorApi = api;
context.currentApi = impl.getAPIAccess().newContext(context);
return api;
Context api = engine.impl.getAPIAccess().newContext(context);
context.creatorApi = api;
context.currentApi = engine.impl.getAPIAccess().newContext(context);
return api;
}
}

private PolyglotContextImpl loadPreinitializedContext(PolyglotContextConfig config) {
Expand All @@ -1308,10 +1397,12 @@ private PolyglotContextImpl loadPreinitializedContext(PolyglotContextConfig conf
} finally {
if (!patchResult) {
context.closeImpl(false, false, false);
context = null;
PolyglotContextImpl.disposeStaticContext(context);
PolyglotContextImpl.disposeStaticContext(null);
config.fileSystem = oldFileSystem;
config.internalFileSystem = oldInternalFileSystem;
ensureClosed(true, false);
PolyglotEngineImpl engine = new PolyglotEngineImpl(this);
context = new PolyglotContextImpl(engine, config);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ OptionValuesImpl getOptionValues() {
return optionValues;
}

OptionValuesImpl getOptionValuesIfExists() {
return optionValues;
}

@Override
public PolyglotEngineImpl getEngine() {
return engine;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ OptionValuesImpl getOptionValues() {
return optionValues;
}

OptionValuesImpl getOptionValuesIfExists() {
return optionValues;
}

@Override
public String getDefaultMimeType() {
return cache.getDefaultMimeType();
Expand Down

0 comments on commit f17692a

Please sign in to comment.