Mercurial > hg > truffle
changeset 22196:364e3f024643
Java objects passed into globalSymbol should be converted into something that Truffle languages can understand - e.g. TruffleObject instances.
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Fri, 25 Sep 2015 14:06:44 +0200 |
parents | 09d91119929f |
children | c8f4168061ea |
files | truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/MethodMessageTest.java truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java |
diffstat | 5 files changed, 59 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- 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());
--- 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 @@ * <code>foreignObject</code> */ public static <T> T asJavaObject(Class<T> type, TruffleObject foreignObject) { - if (type.isInstance(foreignObject)) { - return type.cast(foreignObject); + return asJavaObject(type, null, foreignObject); + } + + private static <T> T asJavaObject(Class<T> 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;
--- 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)); + } }
--- 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> T create(Class<T> 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
--- 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; }