changeset 22529:2643b968c0c6

Send UNBOX message when a primitive type is requested for a TruffleObject value
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 06 Jan 2016 10:59:58 +0100
parents d725323deb6c
children 4ba1aa33fda4 f8fb609939a7
files truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/BoxedStringTest.java truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaObjectForeignAccess.java
diffstat 3 files changed, 141 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/BoxedStringTest.java	Wed Jan 06 10:59:58 2016 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.interop.java.test;
+
+import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.Truffle;
+import com.oracle.truffle.api.interop.ForeignAccess;
+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.nodes.RootNode;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BoxedStringTest implements TruffleObject, ForeignAccess.Factory10 {
+    public interface ExactMatchInterop {
+        String stringValue();
+
+        char charValue();
+    }
+
+    private String value;
+    private ExactMatchInterop interop;
+
+    @Before
+    public void initObjects() {
+        interop = JavaInterop.asJavaObject(ExactMatchInterop.class, this);
+    }
+
+    @Test
+    public void convertToString() {
+        value = "Hello";
+        assertEquals("Hello", interop.stringValue());
+    }
+
+    @Test
+    public void convertToChar() {
+        value = "W";
+        assertEquals('W', interop.charValue());
+    }
+
+    @Override
+    public ForeignAccess getForeignAccess() {
+        return ForeignAccess.create(BoxedStringTest.class, this);
+    }
+
+    @Override
+    public CallTarget accessIsNull() {
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
+    }
+
+    @Override
+    public CallTarget accessIsExecutable() {
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
+    }
+
+    @Override
+    public CallTarget accessIsBoxed() {
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true));
+    }
+
+    @Override
+    public CallTarget accessHasSize() {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessGetSize() {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessUnbox() {
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(value));
+    }
+
+    @Override
+    public CallTarget accessRead() {
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(this));
+    }
+
+    @Override
+    public CallTarget accessWrite() {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessExecute(int argumentsLength) {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessInvoke(int argumentsLength) {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessNew(int argumentsLength) {
+        return null;
+    }
+
+    @Override
+    public CallTarget accessMessage(Message unknown) {
+        return null;
+    }
+
+}
--- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java	Wed Dec 30 18:07:19 2015 +0100
+++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java	Wed Jan 06 10:59:58 2016 +0100
@@ -424,9 +424,15 @@
         return toPrimitive(attr, null) != null;
     }
 
-    static Object toPrimitive(Object attr, Class<?> requestedType) {
-        if (attr instanceof TruffleObject) {
-            return null;
+    static Object toPrimitive(Object value, Class<?> requestedType) {
+        Object attr;
+        if (value instanceof TruffleObject) {
+            if (!Boolean.TRUE.equals(message(Message.IS_BOXED, value))) {
+                return null;
+            }
+            attr = message(Message.UNBOX, value);
+        } else {
+            attr = value;
         }
         if (attr instanceof Number) {
             if (requestedType == null) {
--- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaObjectForeignAccess.java	Wed Dec 30 18:07:19 2015 +0100
+++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaObjectForeignAccess.java	Wed Jan 06 10:59:58 2016 +0100
@@ -43,7 +43,7 @@
 
     @Override
     public CallTarget accessIsBoxed() {
-        return null;
+        return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(Boolean.FALSE));
     }
 
     @Override