# HG changeset patch # User Jaroslav Tulach # Date 1439907003 -7200 # Node ID 1e78795e7e6a1a0c6a931ddae794a97470b2610e # Parent 0058a946186563a5dccb7e425b910156ee1fe131# Parent 643d53cb3147a5e6d07360d179c123103388bef5 Allow to specify globalSymbols when defining TruffleVM diff -r 0058a9461865 -r 1e78795e7e6a 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 Mon Aug 17 15:24:22 2015 -0700 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java Tue Aug 18 16:10:03 2015 +0200 @@ -37,10 +37,15 @@ public final class SymbolInvokerImpl extends SymbolInvoker { static final FrameDescriptor UNUSED_FRAMEDESCRIPTOR = new FrameDescriptor(); - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override protected CallTarget createCallTarget(TruffleLanguage lang, Object symbol, Object... arr) throws IOException { - Class> type = (Class>) lang.getClass(); + Class> type; + if (lang != null) { + type = (Class) lang.getClass(); + } else { + type = (Class) TruffleLanguage.class; + } RootNode symbolNode; if ((symbol instanceof String) || (symbol instanceof Number) || (symbol instanceof Boolean) || (symbol instanceof Character)) { symbolNode = new ConstantRootNode(type, symbol); diff -r 0058a9461865 -r 1e78795e7e6a truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java Tue Aug 18 16:10:03 2015 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.test.vm; + +import static org.junit.Assert.*; + +import java.io.*; + +import org.junit.*; + +import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L3; +import com.oracle.truffle.api.vm.*; + +public class GlobalSymbolTest { + @Test + public void globalSymbolFoundByLanguage() throws IOException { + TruffleVM vm = TruffleVM.newVM().globalSymbol("ahoj", "42").build(); + // @formatter:off + Object ret = vm.eval(L3, + "return=ahoj" + ); + // @formatter:on + assertEquals("42", ret); + } + + @Test + public void globalSymbolFoundByVMUser() throws IOException { + TruffleVM vm = TruffleVM.newVM().globalSymbol("ahoj", "42").build(); + TruffleVM.Symbol ret = vm.findGlobalSymbol("ahoj"); + assertNotNull("Symbol found", ret); + assertEquals("42", ret.invoke(null)); + } +} diff -r 0058a9461865 -r 1e78795e7e6a 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 Mon Aug 17 15:24:22 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Tue Aug 18 16:10:03 2015 +0200 @@ -215,8 +215,8 @@ } static final String L1 = "application/x-test-import-export-1"; - private static final String L2 = "application/x-test-import-export-2"; - private static final String L3 = "application/x-test-import-export-3"; + static final String L2 = "application/x-test-import-export-2"; + static final String L3 = "application/x-test-import-export-3"; @TruffleLanguage.Registration(mimeType = L1, name = "ImportExport1", version = "0") public static final class ExportImportLanguage1 extends AbstractExportImportLanguage { diff -r 0058a9461865 -r 1e78795e7e6a 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 Mon Aug 17 15:24:22 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Tue Aug 18 16:10:03 2015 +0200 @@ -80,6 +80,7 @@ private final Writer err; private final Writer out; private final EventConsumer[] handlers; + private final Map globals; private Debugger debugger; /** @@ -92,6 +93,7 @@ this.out = null; this.langs = null; this.handlers = null; + this.globals = null; } /** @@ -101,12 +103,13 @@ * @param err stderr * @param in stdin */ - private TruffleVM(Writer out, Writer err, Reader in, EventConsumer[] handlers) { + private TruffleVM(Map globals, Writer out, Writer err, Reader in, EventConsumer[] handlers) { this.out = out; this.err = err; this.in = in; this.handlers = handlers; this.initThread = Thread.currentThread(); + this.globals = new HashMap<>(globals); this.langs = new HashMap<>(); Enumeration en; try { @@ -189,7 +192,8 @@ private Writer out; private Writer err; private Reader in; - private List> handlers = new ArrayList<>(); + private final List> handlers = new ArrayList<>(); + private final Map globals = new HashMap<>(); Builder() { } @@ -244,6 +248,24 @@ } /** + * Adds global named symbol into the configuration of to-be-built {@link TruffleVM}. This + * symbol will be accessible to all languages via {@link Env#importSymbol(java.lang.String)} + * and will take precedence over {@link TruffleLanguage#findExportedSymbol symbols exported + * by languages itself}. Repeated use of globalSymbol is possible; later + * definition of the same name overrides the previous one. + * + * @param name name of the symbol to register + * @param obj value of the object - expected to be primitive wrapper, {@link String} or + * TruffleObject for mutual inter-operability + * @return instance of this builder + * @see TruffleVM#findGlobalSymbol(java.lang.String) + */ + public Builder globalSymbol(String name, Object obj) { + globals.put(name, obj); + return this; + } + + /** * Creates the {@link TruffleVM Truffle virtual machine}. The configuration is taken from * values passed into configuration methods in this class. * @@ -259,7 +281,7 @@ if (in == null) { in = new InputStreamReader(System.in); } - return new TruffleVM(out, err, in, handlers.toArray(new EventConsumer[0])); + return new TruffleVM(globals, out, err, in, handlers.toArray(new EventConsumer[0])); } } @@ -379,15 +401,17 @@ public Symbol findGlobalSymbol(String globalName) { checkThread(); TruffleLanguage lang = null; - Object obj = null; + Object obj = globals.get(globalName); Object global = null; - for (Language dl : langs.values()) { - TruffleLanguage l = dl.getImpl(); - obj = SPI.findExportedSymbol(dl.env, globalName, true); - if (obj != null) { - lang = l; - global = SPI.languageGlobal(dl.env); - break; + if (obj == null) { + for (Language dl : langs.values()) { + TruffleLanguage l = dl.getImpl(); + obj = SPI.findExportedSymbol(dl.env, globalName, true); + if (obj != null) { + lang = l; + global = SPI.languageGlobal(dl.env); + break; + } } } if (obj == null) { @@ -624,6 +648,10 @@ private static class SPIAccessor extends Accessor { @Override public Object importSymbol(TruffleVM vm, TruffleLanguage ownLang, String globalName) { + Object g = vm.globals.get(globalName); + if (g != null) { + return g; + } Set uniqueLang = new LinkedHashSet<>(vm.langs.values()); for (Language dl : uniqueLang) { TruffleLanguage l = dl.getImpl();