# HG changeset patch # User Jaroslav Tulach # Date 1443182804 -7200 # Node ID 364e3f0246430aa094556c0f422662120a2a89cf # Parent 09d91119929f4246837ddbe911ddcb18d744efd0 Java objects passed into globalSymbol should be converted into something that Truffle languages can understand - e.g. TruffleObject instances. diff -r 09d91119929f -r 364e3f024643 truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/MethodMessageTest.java --- a/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/MethodMessageTest.java Thu Sep 24 15:50:38 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/MethodMessageTest.java Fri Sep 25 14:06:44 2015 +0200 @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.interop.java.test; +import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.interop.java.MethodMessage; @@ -71,6 +72,9 @@ public void workWithAnArray() throws Exception { TruffleObject arr = JavaInterop.asTruffleObject(new Object[]{1, 2, 3}); + Boolean itIsAnArray = (Boolean) JavaInteropTest.message(Message.HAS_SIZE, arr); + assertTrue("Yes, array", itIsAnArray); + MaxFunction wrap = JavaInterop.asJavaObject(MaxFunction.class, arr); assertTrue("It is an array", wrap.isArray()); diff -r 09d91119929f -r 364e3f024643 truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java --- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java Thu Sep 24 15:50:38 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java Fri Sep 25 14:06:44 2015 +0200 @@ -140,15 +140,32 @@ * foreignObject */ public static T asJavaObject(Class type, TruffleObject foreignObject) { - if (type.isInstance(foreignObject)) { - return type.cast(foreignObject); + return asJavaObject(type, null, foreignObject); + } + + private static T asJavaObject(Class clazz, Type type, TruffleObject foreignObject) { + Object obj; + if (clazz.isInstance(foreignObject)) { + obj = foreignObject; } else { - if (!type.isInterface()) { + if (!clazz.isInterface()) { throw new IllegalArgumentException(); } - Object obj = Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, new TruffleHandler(foreignObject)); - return type.cast(obj); + if (clazz == List.class && Boolean.TRUE.equals(message(Message.HAS_SIZE, foreignObject))) { + Class elementType = Object.class; + if (type instanceof ParameterizedType) { + ParameterizedType parametrizedType = (ParameterizedType) type; + final Type[] arr = parametrizedType.getActualTypeArguments(); + if (arr.length == 1 && arr[0] instanceof Class) { + elementType = (Class) arr[0]; + } + } + obj = TruffleList.create(elementType, foreignObject); + } else { + obj = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new TruffleHandler(foreignObject)); + } } + return clazz.cast(obj); } /** @@ -265,19 +282,7 @@ if (ret instanceof TruffleObject) { final TruffleObject truffleObject = (TruffleObject) ret; if (retType.isInterface()) { - if (method.getReturnType() == List.class && Boolean.TRUE.equals(message(Message.HAS_SIZE, truffleObject))) { - Class elementType = Object.class; - Type type = method.getGenericReturnType(); - if (type instanceof ParameterizedType) { - ParameterizedType parametrizedType = (ParameterizedType) type; - final Type[] arr = parametrizedType.getActualTypeArguments(); - if (arr.length == 1 && arr[0] instanceof Class) { - elementType = (Class) arr[0]; - } - } - return TruffleList.create(elementType, truffleObject); - } - return asJavaObject(retType, truffleObject); + return asJavaObject(retType, method.getGenericReturnType(), truffleObject); } } return ret; diff -r 09d91119929f -r 364e3f024643 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java Thu Sep 24 15:50:38 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java Fri Sep 25 14:06:44 2015 +0200 @@ -22,13 +22,17 @@ */ package com.oracle.truffle.api.test.vm; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.source.Source; import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L3; import com.oracle.truffle.api.vm.PolyglotEngine; import java.io.IOException; +import java.util.List; import java.util.concurrent.Executors; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; public class GlobalSymbolTest { @@ -50,4 +54,18 @@ assertNotNull("Symbol found", ret); assertEquals("42", ret.get()); } + + @Test + public void passingArray() throws IOException { + PolyglotEngine vm = PolyglotEngine.buildNew().globalSymbol("arguments", new Object[]{"one", "two", "three"}).build(); + PolyglotEngine.Value value = vm.findGlobalSymbol("arguments"); + assertFalse("Not instance of array", value.get() instanceof Object[]); + assertTrue("Instance of TruffleObject", value.get() instanceof TruffleObject); + List args = value.as(List.class); + assertNotNull("Can be converted to List", args); + assertEquals("Three items", 3, args.size()); + assertEquals("one", args.get(0)); + assertEquals("two", args.get(1)); + assertEquals("three", args.get(2)); + } } diff -r 09d91119929f -r 364e3f024643 truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java Thu Sep 24 15:50:38 2015 +0200 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java Fri Sep 25 14:06:44 2015 +0200 @@ -40,9 +40,13 @@ } static T create(Class representation, Object wrapper, PolyglotEngine.Value value) { - InvocationHandler chain = Proxy.getInvocationHandler(wrapper); - Object instance = Proxy.newProxyInstance(representation.getClassLoader(), new Class[]{representation}, new JavaWrapper(value, wrapper, chain)); - return representation.cast(instance); + try { + InvocationHandler chain = Proxy.getInvocationHandler(wrapper); + Object instance = Proxy.newProxyInstance(representation.getClassLoader(), new Class[]{representation}, new JavaWrapper(value, wrapper, chain)); + return representation.cast(instance); + } catch (IllegalArgumentException ex) { + return representation.cast(wrapper); + } } @Override diff -r 09d91119929f -r 364e3f024643 truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Thu Sep 24 15:50:38 2015 +0200 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Fri Sep 25 14:06:44 2015 +0200 @@ -293,7 +293,13 @@ * @see PolyglotEngine#findGlobalSymbol(java.lang.String) */ public Builder globalSymbol(String name, Object obj) { - globals.put(name, obj); + final Object truffleReady; + if (obj instanceof Number || obj instanceof String || obj instanceof Character || obj instanceof Boolean) { + truffleReady = obj; + } else { + truffleReady = JavaInterop.asTruffleObject(obj); + } + globals.put(name, truffleReady); return this; }