Mercurial > hg > truffle
changeset 22163:7a6719b66a74
Send Message.INVOKE first and only if it yields IllegalArgumentException consider going back to Message.READ, Message.IS_EXECUTABLE and Message.EXECUTE.
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Mon, 21 Sep 2015 09:46:12 +0200 |
parents | b5b0f3621f05 |
children | 567d324c306c dcb70d90c11d |
files | truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaFunctionNode.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 | 4 files changed, 82 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java Mon Sep 21 09:46:12 2015 +0200 @@ -0,0 +1,63 @@ +/* + * 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; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.nodes.RootNode; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.List; + +final class InvokeMemberNode extends RootNode { + InvokeMemberNode() { + super(JavaInteropLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + JavaInterop.JavaObject receiver = (JavaInterop.JavaObject) ForeignAccess.getReceiver(frame); + final List<Object> args = ForeignAccess.getArguments(frame); + final Object nameOrIndex = args.get(0); + final int argsLength = args.size() - 1; + if (nameOrIndex instanceof Integer) { + throw new IllegalStateException(); + } else { + String name = (String) nameOrIndex; + for (Method m : receiver.clazz.getMethods()) { + final boolean isStatic = (m.getModifiers() & Modifier.STATIC) != 0; + if (isStatic) { + continue; + } + if (m.getName().equals(name) && m.getParameterCount() == argsLength) { + Object[] arr = args.subList(1, args.size()).toArray(); + return JavaFunctionNode.execute(m, receiver.obj, arr); + } + } + throw new IllegalArgumentException(name); + } + } + +}
--- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaFunctionNode.java Thu Sep 17 11:12:45 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaFunctionNode.java Mon Sep 21 09:46:12 2015 +0200 @@ -28,6 +28,7 @@ import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.nodes.RootNode; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.List; final class JavaFunctionNode extends RootNode { @@ -42,15 +43,19 @@ return execute(receiver, args.toArray()); } + static Object execute(JavaInterop.JavaFunctionObject receiver, Object[] args) { + return execute(receiver.method, receiver.obj, args); + } + @SuppressWarnings("paramAssign") - static Object execute(JavaInterop.JavaFunctionObject receiver, Object[] args) { + static Object execute(Method method, Object obj, Object[] args) { for (int i = 0; i < args.length; i++) { if (args[i] instanceof JavaInterop.JavaObject) { args[i] = ((JavaInterop.JavaObject) args[i]).obj; } } try { - Object ret = receiver.method.invoke(receiver.obj, args); + Object ret = method.invoke(obj, args); if (JavaInterop.isPrimitive(ret)) { return ret; }
--- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java Thu Sep 17 11:12:45 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java Mon Sep 21 09:46:12 2015 +0200 @@ -335,17 +335,6 @@ } if (message == null) { - val = message(Message.READ, obj, name); - if (isPrimitive(val)) { - return val; - } - TruffleObject attr = (TruffleObject) val; - if (Boolean.FALSE.equals(message(Message.IS_EXECUTABLE, attr))) { - if (args.length == 0) { - return toJava(attr, method); - } - throw new IllegalStateException(attr + " cannot be invoked with " + args.length + " parameters"); - } Object ret; try { List<Object> callArgs = new ArrayList<>(args.length); @@ -353,6 +342,17 @@ callArgs.addAll(Arrays.asList(args)); ret = message(Message.createInvoke(callArgs.size()), obj, callArgs.toArray()); } catch (IllegalArgumentException ex) { + val = message(Message.READ, obj, name); + if (isPrimitive(val)) { + return val; + } + TruffleObject attr = (TruffleObject) val; + if (Boolean.FALSE.equals(message(Message.IS_EXECUTABLE, attr))) { + if (args.length == 0) { + return toJava(attr, method); + } + throw new IllegalStateException(attr + " cannot be invoked with " + args.length + " parameters"); + } List<Object> callArgs = new ArrayList<>(args.length + 1); // callArgs.add(attr); callArgs.addAll(Arrays.asList(args));
--- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaObjectForeignAccess.java Thu Sep 17 11:12:45 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaObjectForeignAccess.java Mon Sep 21 09:46:12 2015 +0200 @@ -78,7 +78,7 @@ @Override public CallTarget accessInvoke(int argumentsLength) { - return Truffle.getRuntime().createCallTarget(new JavaObjectMethodNode()); + return Truffle.getRuntime().createCallTarget(new InvokeMemberNode()); } @Override