# HG changeset patch # User Jaroslav Tulach # Date 1438842709 -7200 # Node ID 78c3d3d8d86e6fff4d2380923972a2e13fd73858 # Parent 503529c6545661279fb7e4adaeb2516b15cf17c3 Clearly separating the TruffleLanguage definition from context used during its execution. TruffleLanguage now has to have public static field INSTANCE and override createContext method. diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java Thu Aug 06 08:31:49 2015 +0200 @@ -30,11 +30,11 @@ import com.oracle.truffle.api.source.Source; import java.io.IOException; -public final class TestingLanguage extends TruffleLanguage { - public static final TruffleLanguage INSTANCE = new TestingLanguage(); +public final class TestingLanguage extends TruffleLanguage { + public static final TestingLanguage INSTANCE = new TestingLanguage(); private TestingLanguage() { - super(null); + super(); } @Override @@ -43,12 +43,12 @@ } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -67,4 +67,8 @@ return null; } + @Override + protected Object createContext(Env env) { + return null; + } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java Thu Aug 06 08:31:49 2015 +0200 @@ -48,11 +48,11 @@ public static final class MyLangNoSubclass { } - @ExpectError("Language must have a public constructor accepting TruffleLanguage.Env as parameter") + @ExpectError("Language class must have public static final singleton field called INSTANCE") @TruffleLanguage.Registration(name = "myLangNoCnstr", version = "0", mimeType = "text/x-my") - public static final class MyLangWrongConstr extends TruffleLanguage { + public static final class MyLangWrongConstr extends TruffleLanguage { private MyLangWrongConstr() { - super(null); + super(); } @Override @@ -61,12 +61,12 @@ } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -85,13 +85,18 @@ return null; } + @Override + protected Object createContext(Env env) { + throw new UnsupportedOperationException(); + } + } - @ExpectError("Language must have a public constructor accepting TruffleLanguage.Env as parameter") - @TruffleLanguage.Registration(name = "myLangNoCnstr", version = "0", mimeType = "text/x-my") - public static final class MyLangNoConstr extends TruffleLanguage { - public MyLangNoConstr() { - super(null); + @ExpectError("Language class must have public static final singleton field called INSTANCE") + @TruffleLanguage.Registration(name = "myLangNoField", version = "0", mimeType = "text/x-my") + public static final class MyLangNoField extends TruffleLanguage { + public MyLangNoField() { + super(); } @Override @@ -100,12 +105,12 @@ } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -124,21 +129,28 @@ return null; } + @Override + protected Object createContext(Env env) { + throw new UnsupportedOperationException(); + } + } @TruffleLanguage.Registration(name = "myLangGood", version = "0", mimeType = "text/x-my") - public static final class MyLangGood extends TruffleLanguage { - public MyLangGood(TruffleLanguage.Env env) { - super(env); + public static final class MyLangGood extends TruffleLanguage { + private MyLangGood() { + super(); } + public static final MyLangGood INSTANCE = new MyLangGood(); + @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -162,5 +174,10 @@ throw new IOException(); } + @Override + protected Object createContext(Env env) { + return env; + } + } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java Thu Aug 06 08:31:49 2015 +0200 @@ -37,8 +37,9 @@ public final class SymbolInvokerImpl extends SymbolInvoker { static final FrameDescriptor UNUSED_FRAMEDESCRIPTOR = new FrameDescriptor(); + @SuppressWarnings("unchecked") @Override - protected Object invoke(TruffleLanguage lang, Object symbol, Object... arr) throws IOException { + protected Object invoke(TruffleLanguage lang, Object symbol, Object... arr) throws IOException { if (symbol instanceof String) { return symbol; } @@ -48,8 +49,9 @@ if (symbol instanceof Boolean) { return symbol; } + Class> type = (Class>) lang.getClass(); Node executeMain = Message.createExecute(arr.length).createNode(); - CallTarget callTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(lang, executeMain, (TruffleObject) symbol, arr)); + CallTarget callTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(type, executeMain, (TruffleObject) symbol, arr)); VirtualFrame frame = Truffle.getRuntime().createVirtualFrame(arr, UNUSED_FRAMEDESCRIPTOR); Object ret = callTarget.call(frame); if (ret instanceof TruffleObject) { @@ -57,20 +59,20 @@ Object isBoxedResult; try { Node isBoxed = Message.IS_BOXED.createNode(); - CallTarget isBoxedTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(lang, isBoxed, tret)); + CallTarget isBoxedTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(type, isBoxed, tret)); isBoxedResult = isBoxedTarget.call(frame); } catch (IllegalArgumentException ex) { isBoxedResult = false; } if (Boolean.TRUE.equals(isBoxedResult)) { Node unbox = Message.UNBOX.createNode(); - CallTarget unboxTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(lang, unbox, tret)); + CallTarget unboxTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(type, unbox, tret)); Object unboxResult = unboxTarget.call(frame); return unboxResult; } else { try { Node isNull = Message.IS_NULL.createNode(); - CallTarget isNullTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(lang, isNull, tret)); + CallTarget isNullTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(type, isNull, tret)); Object isNullResult = isNullTarget.call(frame); if (Boolean.TRUE.equals(isNullResult)) { return null; @@ -88,8 +90,8 @@ private final TruffleObject function; private final Object[] args; - public TemporaryRoot(TruffleLanguage lang, Node foreignAccess, TruffleObject function, Object... args) { - super(lang.getClass(), null, null); + public TemporaryRoot(Class> lang, Node foreignAccess, TruffleObject function, Object... args) { + super(lang, null, null); this.foreignAccess = foreignAccess; this.function = function; this.args = args; diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java Thu Aug 06 08:31:49 2015 +0200 @@ -30,11 +30,10 @@ import com.oracle.truffle.api.source.Source; import java.io.IOException; -public final class TestingLanguage extends TruffleLanguage { - public static final TruffleLanguage INSTANCE = new TestingLanguage(); +public final class TestingLanguage extends TruffleLanguage { + public static final TestingLanguage INSTANCE = new TestingLanguage(); private TestingLanguage() { - super(null); } @Override @@ -43,12 +42,12 @@ } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -67,4 +66,9 @@ return null; } + @Override + protected Object createContext(Env env) { + return null; + } + } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java Thu Aug 06 08:31:49 2015 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.truffle.api.test.vm; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.impl.Accessor; import com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.ExportImportLanguage1; import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L1; @@ -54,13 +55,18 @@ Object afterInitialization = findLanguageByClass(vm); assertNotNull("Language found", afterInitialization); - assertTrue("Right instance", afterInitialization instanceof ExportImportLanguage1); + assertTrue("Right instance: " + afterInitialization, afterInitialization instanceof ExportImportLanguage1); } - Object findLanguageByClass(TruffleVM vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { + Object findLanguageByClass(TruffleVM vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { Method find = Accessor.class.getDeclaredMethod("findLanguage", TruffleVM.class, Class.class); find.setAccessible(true); - Object language1 = find.invoke(API, vm, ExportImportLanguage1.class); - return language1; + TruffleLanguage.Env env = (TruffleLanguage.Env) find.invoke(API, vm, ExportImportLanguage1.class); + Field f = env.getClass().getDeclaredField("langCtx"); + f.setAccessible(true); + Object langCtx = f.get(env); + f = langCtx.getClass().getDeclaredField("lang"); + f.setAccessible(true); + return f.get(langCtx); } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Thu Aug 06 08:31:49 2015 +0200 @@ -30,6 +30,7 @@ import org.junit.*; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.debug.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.Node; @@ -108,36 +109,41 @@ assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").invoke(null)); } - private abstract static class AbstractExportImportLanguage extends TruffleLanguage { - protected AbstractExportImportLanguage(Env env) { - super(env); + private static final class Ctx { + final Map explicit = new HashMap<>(); + final Map implicit = new HashMap<>(); + final Env env; + + public Ctx(Env env) { + this.env = env; } + } - private final Map explicit = new HashMap<>(); - private final Map implicit = new HashMap<>(); + private abstract static class AbstractExportImportLanguage extends TruffleLanguage { + + @Override + protected Ctx createContext(Env env) { + return new Ctx(env); + } @Override protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - return new ValueCallTarget(code, getClass()); + return new ValueCallTarget(code, this); } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - if (explicit.containsKey(globalName)) { - return explicit.get(globalName); + protected Object findExportedSymbol(Ctx context, String globalName, boolean onlyExplicit) { + if (context.explicit.containsKey(globalName)) { + return context.explicit.get(globalName); } - if (!onlyExplicit && implicit.containsKey(globalName)) { - return implicit.get(globalName); + if (!onlyExplicit && context.implicit.containsKey(globalName)) { + return context.implicit.get(globalName); } return null; } - public static Language findContext(Class type) { - return TruffleLanguage.findContext(type); - } - @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Ctx context) { return null; } @@ -157,6 +163,7 @@ } private Object importExport(Source code) { + Ctx ctx = findContext(); Properties p = new Properties(); try (Reader r = code.getReader()) { p.load(r); @@ -169,13 +176,13 @@ if (n instanceof String) { String k = (String) n; if (k.startsWith("explicit.")) { - explicit.put(k.substring(9), p.getProperty(k)); + ctx.explicit.put(k.substring(9), p.getProperty(k)); } if (k.startsWith("implicit.")) { - implicit.put(k.substring(9), p.getProperty(k)); + ctx.implicit.put(k.substring(9), p.getProperty(k)); } if (k.equals("return")) { - return env().importSymbol(p.getProperty(k)); + return ctx.env.importSymbol(p.getProperty(k)); } } } @@ -185,9 +192,9 @@ private static final class ValueCallTarget implements RootCallTarget { private final Source code; - private final Class language; + private final AbstractExportImportLanguage language; - private ValueCallTarget(Source code, Class language) { + private ValueCallTarget(Source code, AbstractExportImportLanguage language) { this.code = code; this.language = language; } @@ -199,8 +206,7 @@ @Override public Object call(Object... arguments) { - AbstractExportImportLanguage context = AbstractExportImportLanguage.findContext(language); - return context.importExport(code); + return language.importExport(code); } } @@ -210,22 +216,25 @@ @TruffleLanguage.Registration(mimeType = L1, name = "ImportExport1", version = "0") public static final class ExportImportLanguage1 extends AbstractExportImportLanguage { - public ExportImportLanguage1(Env env) { - super(env); + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage1(); + + public ExportImportLanguage1() { } } @TruffleLanguage.Registration(mimeType = L2, name = "ImportExport2", version = "0") public static final class ExportImportLanguage2 extends AbstractExportImportLanguage { - public ExportImportLanguage2(Env env) { - super(env); + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage2(); + + public ExportImportLanguage2() { } } @TruffleLanguage.Registration(mimeType = L3, name = "ImportExport3", version = "0") public static final class ExportImportLanguage3 extends AbstractExportImportLanguage { - public ExportImportLanguage3(Env env) { - super(env); + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage3(); + + private ExportImportLanguage3() { } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Thu Aug 06 08:31:49 2015 +0200 @@ -26,7 +26,6 @@ import java.io.*; import java.lang.annotation.*; -import java.lang.reflect.*; import com.oracle.truffle.api.debug.*; import com.oracle.truffle.api.impl.*; @@ -45,18 +44,16 @@ * language becomes accessible to users of the {@link TruffleVM Truffle virtual machine} - all they * will need to do is to include your JAR into their application and all the Truffle goodies (multi * language support, multitenant hosting, debugging, etc.) will be made available to them. + * + * @param internal state of the language associated with every thread that is executing program + * {@link #parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...) + * parsed} by the language */ -public abstract class TruffleLanguage { - private final Env env; - +public abstract class TruffleLanguage { /** * Constructor to be called by subclasses. - * - * @param env language environment that will be available via {@link #env()} method to - * subclasses. */ - protected TruffleLanguage(Env env) { - this.env = env; + protected TruffleLanguage() { } /** @@ -95,12 +92,18 @@ String[] mimeType(); } - protected final Env env() { - if (this.env == null) { - throw new NullPointerException("Accessing env before initialization is finished"); - } - return this.env; - } + /** + * Creates internal representation of the executing context suitable for given environment. Each + * time the {@link TruffleLanguage language} is used by a new {@link TruffleVM} or in a new + * thread, the system calls this method to let the {@link TruffleLanguage language} prepare for + * execution. The returned execution context is completely language specific; it is + * however expected it will contain reference to here-in provided env and adjust + * itself according to parameters provided by the env object. + * + * @param env the environment the language is supposed to operate in + * @return internal data of the language in given environment + */ + protected abstract C createContext(Env env); /** * Parses the provided source and generates appropriate AST. The parsing should execute no user @@ -145,7 +148,7 @@ * @return an exported object or null, if the symbol does not represent anything * meaningful in this language */ - protected abstract Object findExportedSymbol(String globalName, boolean onlyExplicit); + protected abstract Object findExportedSymbol(C context, String globalName, boolean onlyExplicit); /** * Returns global object for the language. @@ -156,7 +159,7 @@ * * @return the global object or null if the language does not support such concept */ - protected abstract Object getLanguageGlobal(); + protected abstract Object getLanguageGlobal(C context); /** * Checks whether the object is provided by this language. @@ -171,15 +174,37 @@ protected abstract DebugSupportProvider getDebugSupport(); /** - * Finds the currently executing context for current thread. + * Finds the currently executing context for this language and current thread. Obtains data + * previously created by {@link #createContext(com.oracle.truffle.api.TruffleLanguage.Env)} + * method. * - * @param type of language making the query - * @param language the language class * @return the context associated with current execution * @throws IllegalStateException if no context is associated with the execution */ - protected static Lang findContext(Class language) { - return language.cast(API.findLanguage(null, language)); + @SuppressWarnings({"rawtypes", "unchecked"}) + protected final C findContext() { + final Class c = getClass(); + final Env env = API.findLanguage(null, c); + assert env.langCtx.lang == this; + return (C) env.langCtx.ctx; + } + + private static final class LangCtx { + final TruffleLanguage lang; + final C ctx; + + public LangCtx(TruffleLanguage lang, Env env) { + this.lang = lang; + this.ctx = lang.createContext(env); + } + + Object findExportedSymbol(String globalName, boolean onlyExplicit) { + return lang.findExportedSymbol(ctx, globalName, onlyExplicit); + } + + Object getLanguageGlobal() { + return lang.getLanguageGlobal(ctx); + } } /** @@ -190,21 +215,17 @@ */ public static final class Env { private final TruffleVM vm; - private final TruffleLanguage lang; + private final LangCtx langCtx; private final Reader in; private final Writer err; private final Writer out; - Env(TruffleVM vm, Constructor langConstructor, Writer out, Writer err, Reader in) { + Env(TruffleVM vm, TruffleLanguage lang, Writer out, Writer err, Reader in) { this.vm = vm; this.in = in; this.err = err; this.out = out; - try { - this.lang = (TruffleLanguage) langConstructor.newInstance(this); - } catch (Exception ex) { - throw new IllegalStateException("Cannot construct language " + langConstructor.getDeclaringClass().getName(), ex); - } + this.langCtx = new LangCtx<>(lang, this); } /** @@ -217,7 +238,7 @@ * @return object representing the symbol or null */ public Object importSymbol(String globalName) { - return API.importSymbol(vm, lang, globalName); + return API.importSymbol(vm, langCtx.lang, globalName); } /** @@ -250,22 +271,23 @@ private static final AccessAPI API = new AccessAPI(); + @SuppressWarnings("rawtypes") private static final class AccessAPI extends Accessor { @Override - protected TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - Env env = new Env(vm, langClazz, stdOut, stdErr, stdIn); - return env.lang; + protected Env attachEnv(TruffleVM vm, TruffleLanguage language, Writer stdOut, Writer stdErr, Reader stdIn) { + Env env = new Env(vm, language, stdOut, stdErr, stdIn); + return env; } @Override - public Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { + public Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { return super.importSymbol(vm, queryingLang, globalName); } private static final Map COMPILED = Collections.synchronizedMap(new WeakHashMap()); @Override - protected Object eval(TruffleLanguage language, Source source) throws IOException { + protected Object eval(TruffleLanguage language, Source source) throws IOException { CallTarget target = COMPILED.get(source); if (target == null) { target = language.parse(source, null); @@ -282,27 +304,27 @@ } @Override - protected Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return l.findExportedSymbol(globalName, onlyExplicit); + protected Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) { + return env.langCtx.findExportedSymbol(globalName, onlyExplicit); } @Override - protected TruffleLanguage findLanguage(TruffleVM vm, Class languageClass) { + protected Env findLanguage(TruffleVM vm, Class languageClass) { return super.findLanguage(vm, languageClass); } @Override - protected Object languageGlobal(TruffleLanguage l) { - return l.getLanguageGlobal(); + protected Object languageGlobal(TruffleLanguage.Env env) { + return env.langCtx.getLanguageGlobal(); } @Override - protected ToolSupportProvider getToolSupport(TruffleLanguage l) { + protected ToolSupportProvider getToolSupport(TruffleLanguage l) { return l.getToolSupport(); } @Override - protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { + protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { return l.getDebugSupport(); } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Thu Aug 06 08:31:49 2015 +0200 @@ -117,8 +117,8 @@ } }; - this.lineBreaks = new LineBreakpointFactory(this, breakpointCallback, warningLog); - this.tagBreaks = new TagBreakpointFactory(this, breakpointCallback, warningLog); + this.lineBreaks = new LineBreakpointFactory(breakpointCallback, warningLog); + this.tagBreaks = new TagBreakpointFactory(breakpointCallback, warningLog); } TruffleVM vm() { @@ -266,10 +266,18 @@ * @throws IOException if the factory cannot be created, for example if the expression is badly * formed. */ - AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Probe probe, String expr, AdvancedInstrumentResultListener resultListener) throws IOException { + @SuppressWarnings("rawtypes") + static AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Probe probe, String expr, AdvancedInstrumentResultListener resultListener) throws IOException { try { Class langugageClass = ACCESSOR.findLanguage(probe); - TruffleLanguage l = ACCESSOR.findLanguage(vm, langugageClass); + TruffleLanguage l; + try { + l = langugageClass.newInstance(); + } catch (InstantiationException ex) { + throw new IllegalStateException(ex); + } catch (IllegalAccessException ex) { + throw new IllegalStateException(ex); + } DebugSupportProvider dsp = ACCESSOR.getDebugSupport(l); return dsp.createAdvancedInstrumentRootFactory(expr, resultListener); } catch (DebugSupportException ex) { @@ -789,6 +797,7 @@ debugContext = debugContext.predecessor; } + @SuppressWarnings("rawtypes") private static final class AccessorDebug extends Accessor { @Override protected Closeable executionStart(TruffleVM vm, Debugger[] fillIn, Source s) { @@ -813,12 +822,12 @@ } @Override - protected TruffleLanguage findLanguage(TruffleVM vm, Class languageClass) { + protected TruffleLanguage.Env findLanguage(TruffleVM vm, Class languageClass) { return super.findLanguage(vm, languageClass); } @Override - protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { + protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { return super.getDebugSupport(l); } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Thu Aug 06 08:31:49 2015 +0200 @@ -90,7 +90,6 @@ } }; - private final Debugger executionSupport; private final BreakpointCallback breakpointCallback; private final WarningLog warningLog; @@ -113,8 +112,7 @@ @CompilationFinal private boolean breakpointsActive = true; private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active"); - LineBreakpointFactory(Debugger executionSupport, BreakpointCallback breakpointCallback, final WarningLog warningLog) { - this.executionSupport = executionSupport; + LineBreakpointFactory(BreakpointCallback breakpointCallback, final WarningLog warningLog) { this.breakpointCallback = breakpointCallback; this.warningLog = warningLog; @@ -365,7 +363,7 @@ if (conditionExpr == null) { newInstrument = Instrument.create(new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME); } else { - newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + newInstrument = Instrument.create(this, Debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); } newProbe.attach(newInstrument); instruments.add(newInstrument); diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Thu Aug 06 08:31:49 2015 +0200 @@ -88,7 +88,6 @@ } }; - private final Debugger executionSupport; private final BreakpointCallback breakpointCallback; private final WarningLog warningLog; @@ -104,8 +103,7 @@ @CompilationFinal private boolean breakpointsActive = true; private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active"); - TagBreakpointFactory(Debugger executionSupport, BreakpointCallback breakpointCallback, final WarningLog warningLog) { - this.executionSupport = executionSupport; + TagBreakpointFactory(BreakpointCallback breakpointCallback, final WarningLog warningLog) { this.breakpointCallback = breakpointCallback; this.warningLog = warningLog; @@ -329,7 +327,7 @@ if (conditionExpr == null) { newInstrument = Instrument.create(new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME); } else { - newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + newInstrument = Instrument.create(this, Debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); } newProbe.attach(newInstrument); instruments.add(newInstrument); diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Thu Aug 06 08:31:49 2015 +0200 @@ -25,10 +25,10 @@ package com.oracle.truffle.api.impl; import java.io.*; -import java.lang.reflect.*; import java.util.*; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.debug.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.Node; @@ -39,6 +39,7 @@ /** * Communication between TruffleVM and TruffleLanguage API/SPI. */ +@SuppressWarnings("rawtypes") public abstract class Accessor { private static Accessor API; private static Accessor SPI; @@ -48,14 +49,14 @@ private static final ThreadLocal CURRENT_VM = new ThreadLocal<>(); static { - TruffleLanguage lng = new TruffleLanguage(null) { + TruffleLanguage lng = new TruffleLanguage() { @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { return null; } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(Object context) { return null; } @@ -78,6 +79,11 @@ protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { throw new IOException(); } + + @Override + protected Object createContext(TruffleLanguage.Env env) { + return null; + } }; lng.hashCode(); new Node(null) { @@ -119,35 +125,35 @@ } } - protected TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - return API.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); + protected Env attachEnv(TruffleVM vm, TruffleLanguage language, Writer stdOut, Writer stdErr, Reader stdIn) { + return API.attachEnv(vm, language, stdOut, stdErr, stdIn); } - protected Object eval(TruffleLanguage l, Source s) throws IOException { + protected Object eval(TruffleLanguage l, Source s) throws IOException { return API.eval(l, s); } - protected Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { + protected Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { return SPI.importSymbol(vm, queryingLang, globalName); } - protected Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return API.findExportedSymbol(l, globalName, onlyExplicit); + protected Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) { + return API.findExportedSymbol(env, globalName, onlyExplicit); } - protected Object languageGlobal(TruffleLanguage l) { - return API.languageGlobal(l); + protected Object languageGlobal(TruffleLanguage.Env env) { + return API.languageGlobal(env); } - protected ToolSupportProvider getToolSupport(TruffleLanguage l) { + protected ToolSupportProvider getToolSupport(TruffleLanguage l) { return API.getToolSupport(l); } - protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { + protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { return API.getDebugSupport(l); } - protected Object invoke(TruffleLanguage lang, Object obj, Object[] args) throws IOException { + protected Object invoke(TruffleLanguage lang, Object obj, Object[] args) throws IOException { for (SymbolInvoker si : ServiceLoader.load(SymbolInvoker.class)) { return si.invoke(lang, obj, args); } @@ -162,7 +168,7 @@ return INSTRUMENT.findLanguage(probe); } - protected TruffleLanguage findLanguage(TruffleVM known, Class languageClass) { + protected Env findLanguage(TruffleVM known, Class languageClass) { TruffleVM vm; if (known == null) { vm = CURRENT_VM.get(); diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java Thu Aug 06 08:31:49 2015 +0200 @@ -32,5 +32,5 @@ * associated nodes too much. */ public abstract class SymbolInvoker { - protected abstract Object invoke(TruffleLanguage lang, Object symbol, Object... args) throws IOException; + protected abstract Object invoke(TruffleLanguage lang, Object symbol, Object... args) throws IOException; } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Thu Aug 06 08:31:49 2015 +0200 @@ -100,6 +100,7 @@ * @see ProbeListener * @see SyntaxTag */ +@SuppressWarnings("rawtypes") public final class Probe { private final Class language; diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Thu Aug 06 08:31:49 2015 +0200 @@ -118,6 +118,7 @@ * Create a new {@link Probe} associated with, and attached to, a Guest Language specific * instance of {@link WrapperNode}. */ + @SuppressWarnings("rawtypes") public static Probe insertProbe(WrapperNode wrapper) { final SourceSection sourceSection = wrapper.getChild().getSourceSection(); final ProbeNode probeNode = new ProbeNode(); // private constructor diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Thu Aug 06 08:31:49 2015 +0200 @@ -589,6 +589,7 @@ } private static final class AccessorNodes extends Accessor { + @SuppressWarnings("rawtypes") @Override protected Class findLanguage(RootNode n) { return n.language; diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Thu Aug 06 08:31:49 2015 +0200 @@ -36,6 +36,7 @@ * root node can be used to create a call target using * {@link TruffleRuntime#createCallTarget(RootNode)}. */ +@SuppressWarnings("rawtypes") public abstract class RootNode extends Node { final Class language; private RootCallTarget callTarget; diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Thu Aug 06 08:31:49 2015 +0200 @@ -25,7 +25,6 @@ package com.oracle.truffle.api.vm; import java.io.*; -import java.lang.reflect.*; import java.net.*; import java.nio.file.*; import java.util.*; @@ -55,6 +54,7 @@ * has been {@link Builder#build() created} by and checks that all subsequent calls are coming from * the same thread. */ +@SuppressWarnings("rawtypes") public final class TruffleVM { private static final Logger LOG = Logger.getLogger(TruffleVM.class.getName()); private static final SPIAccessor SPI = new SPIAccessor(); @@ -289,7 +289,7 @@ URLConnection conn = url.openConnection(); mimeType = conn.getContentType(); } - TruffleLanguage l = getTruffleLang(mimeType); + TruffleLanguage l = getTruffleLang(mimeType); if (l == null) { throw new IOException("No language for " + location + " with MIME type " + mimeType + " found. Supported types: " + langs.keySet()); } @@ -307,7 +307,7 @@ */ public Object eval(String mimeType, Reader reader) throws IOException { checkThread(); - TruffleLanguage l = getTruffleLang(mimeType); + TruffleLanguage l = getTruffleLang(mimeType); if (l == null) { throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet()); } @@ -325,14 +325,14 @@ */ public Object eval(String mimeType, String code) throws IOException { checkThread(); - TruffleLanguage l = getTruffleLang(mimeType); + TruffleLanguage l = getTruffleLang(mimeType); if (l == null) { throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet()); } return eval(l, Source.fromText(code, mimeType)); } - private Object eval(TruffleLanguage l, Source s) throws IOException { + private Object eval(TruffleLanguage l, Source s) throws IOException { TruffleVM.findDebuggerSupport(l); Debugger[] fillIn = {debugger}; try (Closeable d = SPI.executionStart(this, fillIn, s)) { @@ -362,25 +362,25 @@ */ public Symbol findGlobalSymbol(String globalName) { checkThread(); - TruffleLanguage lang = null; + TruffleLanguage lang = null; Object obj = null; Object global = null; for (Language dl : langs.values()) { - TruffleLanguage l = dl.getImpl(); - obj = SPI.findExportedSymbol(l, globalName, true); + TruffleLanguage l = dl.getImpl(); + obj = SPI.findExportedSymbol(dl.env, globalName, true); if (obj != null) { lang = l; - global = SPI.languageGlobal(l); + global = SPI.languageGlobal(dl.env); break; } } if (obj == null) { for (Language dl : langs.values()) { - TruffleLanguage l = dl.getImpl(); - obj = SPI.findExportedSymbol(l, globalName, false); + TruffleLanguage l = dl.getImpl(); + obj = SPI.findExportedSymbol(dl.env, globalName, false); if (obj != null) { lang = l; - global = SPI.languageGlobal(l); + global = SPI.languageGlobal(dl.env); break; } } @@ -394,7 +394,7 @@ } } - private TruffleLanguage getTruffleLang(String mimeType) { + private TruffleLanguage getTruffleLang(String mimeType) { checkThread(); Language l = langs.get(mimeType); return l == null ? null : l.getImpl(); @@ -434,11 +434,11 @@ * of the initialized languages in {@link TruffleVM Truffle virtual machine}. */ public class Symbol { - private final TruffleLanguage language; + private final TruffleLanguage language; private final Object obj; private final Object global; - Symbol(TruffleLanguage language, Object obj, Object global) { + Symbol(TruffleLanguage language, Object obj, Object global) { this.language = language; this.obj = obj; this.global = global; @@ -487,7 +487,8 @@ */ public final class Language { private final Properties props; - private TruffleLanguage impl; + private TruffleLanguage impl; + private TruffleLanguage.Env env; private final String prefix; private String shortName; @@ -543,13 +544,14 @@ return shortName; } - TruffleLanguage getImpl() { + TruffleLanguage getImpl() { if (impl == null) { String n = props.getProperty(prefix + "className"); try { Class langClazz = Class.forName(n, true, loader()); - Constructor constructor = langClazz.getConstructor(Env.class); - impl = SPI.attachEnv(TruffleVM.this, constructor, out, err, in); + TruffleLanguage language = (TruffleLanguage) langClazz.getField("INSTANCE").get(null); + env = SPI.attachEnv(TruffleVM.this, language, out, err, in); + impl = language; } catch (Exception ex) { throw new IllegalStateException("Cannot initialize " + getShortName() + " language with implementation " + n, ex); } @@ -567,12 +569,8 @@ // Accessor helper methods // - TruffleLanguage findLanguage(Probe probe) { + TruffleLanguage findLanguage(Probe probe) { Class languageClazz = SPI.findLanguage(probe); - return findLanguage(languageClazz); - } - - TruffleLanguage findLanguage(Class languageClazz) { for (Map.Entry entrySet : langs.entrySet()) { Language languageDescription = entrySet.getValue(); if (languageClazz.isInstance(languageDescription.impl)) { @@ -582,30 +580,40 @@ throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs); } - static DebugSupportProvider findDebuggerSupport(TruffleLanguage l) { + Env findEnv(Class languageClazz) { + for (Map.Entry entrySet : langs.entrySet()) { + Language languageDescription = entrySet.getValue(); + if (languageClazz.isInstance(languageDescription.impl)) { + return languageDescription.env; + } + } + throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs); + } + + static DebugSupportProvider findDebuggerSupport(TruffleLanguage l) { return SPI.getDebugSupport(l); } private static class SPIAccessor extends Accessor { @Override - public Object importSymbol(TruffleVM vm, TruffleLanguage ownLang, String globalName) { + public Object importSymbol(TruffleVM vm, TruffleLanguage ownLang, String globalName) { Set uniqueLang = new LinkedHashSet<>(vm.langs.values()); for (Language dl : uniqueLang) { - TruffleLanguage l = dl.getImpl(); + TruffleLanguage l = dl.getImpl(); if (l == ownLang) { continue; } - Object obj = SPI.findExportedSymbol(l, globalName, true); + Object obj = SPI.findExportedSymbol(dl.env, globalName, true); if (obj != null) { return obj; } } for (Language dl : uniqueLang) { - TruffleLanguage l = dl.getImpl(); + TruffleLanguage l = dl.getImpl(); if (l == ownLang) { continue; } - Object obj = SPI.findExportedSymbol(l, globalName, false); + Object obj = SPI.findExportedSymbol(dl.env, globalName, false); if (obj != null) { return obj; } @@ -614,37 +622,37 @@ } @Override - public TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - return super.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); + public Env attachEnv(TruffleVM vm, TruffleLanguage language, Writer stdOut, Writer stdErr, Reader stdIn) { + return super.attachEnv(vm, language, stdOut, stdErr, stdIn); } @Override - public Object eval(TruffleLanguage l, Source s) throws IOException { + public Object eval(TruffleLanguage l, Source s) throws IOException { return super.eval(l, s); } @Override - public Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return super.findExportedSymbol(l, globalName, onlyExplicit); + public Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) { + return super.findExportedSymbol(env, globalName, onlyExplicit); } @Override - public Object languageGlobal(TruffleLanguage l) { - return super.languageGlobal(l); + protected Object languageGlobal(TruffleLanguage.Env env) { + return super.languageGlobal(env); } @Override - protected Object invoke(TruffleLanguage lang, Object obj, Object[] args) throws IOException { + protected Object invoke(TruffleLanguage lang, Object obj, Object[] args) throws IOException { return super.invoke(lang, obj, args); } @Override - public ToolSupportProvider getToolSupport(TruffleLanguage l) { + public ToolSupportProvider getToolSupport(TruffleLanguage l) { return super.getToolSupport(l); } @Override - public DebugSupportProvider getDebugSupport(TruffleLanguage l) { + public DebugSupportProvider getDebugSupport(TruffleLanguage l) { return super.getDebugSupport(l); } @@ -654,8 +662,8 @@ } @Override - protected TruffleLanguage findLanguage(TruffleVM vm, Class languageClass) { - return vm.findLanguage(languageClass); + protected Env findLanguage(TruffleVM vm, Class languageClass) { + return vm.findEnv(languageClass); } @Override diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/LanguageRegistrationProcessor.java --- a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/LanguageRegistrationProcessor.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/LanguageRegistrationProcessor.java Thu Aug 06 08:31:49 2015 +0200 @@ -93,31 +93,32 @@ emitError("Registered language inner-class must be static", e); continue; } - TypeMirror truffleLang = processingEnv.getElementUtils().getTypeElement(TruffleLanguage.class.getName()).asType(); + TypeMirror truffleLang = processingEnv.getTypeUtils().erasure(processingEnv.getElementUtils().getTypeElement(TruffleLanguage.class.getName()).asType()); if (!processingEnv.getTypeUtils().isAssignable(e.asType(), truffleLang)) { emitError("Registered language class must subclass TruffleLanguage", e); continue; } boolean found = false; for (Element mem : e.getEnclosedElements()) { - if (mem.getKind() != ElementKind.CONSTRUCTOR) { + if (!mem.getModifiers().contains(Modifier.PUBLIC)) { + continue; + } + if (mem.getKind() != ElementKind.FIELD) { continue; } - ExecutableElement ee = (ExecutableElement) mem; - if (ee.getParameters().size() != 1) { + if (!mem.getModifiers().contains(Modifier.FINAL)) { continue; } - if (!ee.getModifiers().contains(Modifier.PUBLIC)) { + if (!"INSTANCE".equals(mem.getSimpleName().toString())) { continue; } - TypeMirror env = processingEnv.getElementUtils().getTypeElement(TruffleLanguage.Env.class.getCanonicalName()).asType(); - if (processingEnv.getTypeUtils().isSameType(ee.getParameters().get(0).asType(), env)) { + if (processingEnv.getTypeUtils().isAssignable(mem.asType(), truffleLang)) { found = true; break; } } if (!found) { - emitError("Language must have a public constructor accepting TruffleLanguage.Env as parameter", e); + emitError("Language class must have public static final singleton field called INSTANCE", e); continue; } assertNoErrorExpected(e); diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java Thu Aug 06 08:31:49 2015 +0200 @@ -153,19 +153,24 @@ * */ @TruffleLanguage.Registration(name = "SL", version = "0.5", mimeType = "application/x-sl") -public class SLLanguage extends TruffleLanguage { +public class SLLanguage extends TruffleLanguage { private static List> builtins = Collections.emptyList(); private static Visualizer visualizer = new SLDefaultVisualizer(); private static ASTProber registeredASTProber; // non-null if prober already registered - private final SLContext context; private DebugSupportProvider debugSupport; - public SLLanguage(Env env) { - super(env); - context = new SLContext(this, new BufferedReader(env().stdIn()), new PrintWriter(env().stdOut(), true)); + private SLLanguage() { + } + + public static final SLLanguage INSTANCE = new SLLanguage(); + + @Override + protected SLContext createContext(Env env) { + SLContext context = new SLContext(this, new BufferedReader(env.stdIn()), new PrintWriter(env.stdOut(), true)); for (NodeFactory builtin : builtins) { context.installBuiltin(builtin, true); } + return context; } // TODO (mlvdv) command line options @@ -378,10 +383,6 @@ return result.toString(); } - public static SLLanguage find() { - return SLLanguage.findContext(SLLanguage.class); - } - @Override protected CallTarget parse(Source code, Node node, String... argumentNames) throws IOException { final SLContext c = new SLContext(this); @@ -401,8 +402,7 @@ if (failed[0] != null) { throw new IllegalStateException(failed[0]); } - SLLanguage current = SLLanguage.find(); - SLContext fillIn = current.context; + SLContext fillIn = getContext(); final SLFunctionRegistry functionRegistry = fillIn.getFunctionRegistry(); for (SLFunction f : c.getFunctionRegistry().getFunctions()) { RootCallTarget callTarget = f.getCallTarget(); @@ -418,7 +418,7 @@ } @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { + protected Object findExportedSymbol(SLContext context, String globalName, boolean onlyExplicit) { for (SLFunction f : context.getFunctionRegistry().getFunctions()) { if (globalName.equals(f.getName())) { return f; @@ -428,7 +428,7 @@ } @Override - protected Object getLanguageGlobal() { + protected Object getLanguageGlobal(SLContext context) { return context; } @@ -492,7 +492,7 @@ } public SLContext getContext() { - return context; + return findContext(); } private final class SLDebugProvider implements DebugSupportProvider { diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java Thu Aug 06 08:31:49 2015 +0200 @@ -56,7 +56,6 @@ */ @NodeInfo(shortName = "func") public final class SLFunctionLiteralNode extends SLExpressionNode { - private final String value; public SLFunctionLiteralNode(SourceSection src, String value) { @@ -66,7 +65,6 @@ @Override public SLFunction executeGeneric(VirtualFrame frame) { - SLLanguage language = SLLanguage.find(); - return language.getContext().getFunctionRegistry().lookup(value); + return SLLanguage.INSTANCE.getContext().getFunctionRegistry().lookup(value); } } diff -r 503529c65456 -r 78c3d3d8d86e truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/MaxMinObject.java --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/MaxMinObject.java Wed Aug 05 10:19:41 2015 -0700 +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/MaxMinObject.java Thu Aug 06 08:31:49 2015 +0200 @@ -194,9 +194,6 @@ } } - private abstract class MMLanguage extends TruffleLanguage { - public MMLanguage(Env env) { - super(env); - } + private abstract class MMLanguage extends TruffleLanguage { } }