From ed532677250b1acc008ba86948d2e14e966455ba Mon Sep 17 00:00:00 2001 From: Matthias Grimmer Date: Fri, 15 Apr 2016 14:34:06 +0200 Subject: [PATCH 1/5] Extend Interop DSL and provide an @LanguageCheck annotation, which allows expressing the language check as a node --- .../dsl/test/interop/AcceptMessageTest.java | 35 ---- .../api/dsl/test/interop/Snippets.java | 9 + .../test/interop/ValidTruffleObject10.java | 38 ---- .../api/interop/CachedObjectAccessNode.java | 26 ++- .../truffle/api/interop/ForeignAccess.java | 34 ++- .../truffle/api/interop/LanguageCheck.java | 49 +++++ .../api/interop/MessageResolution.java | 2 + .../oracle/truffle/api/interop/Resolve.java | 10 +- .../interop/UnresolvedObjectAccessNode.java | 5 +- .../ForeignAccessFactoryGenerator.java | 74 ++++--- .../interop/InteropDSLProcessor.java | 103 +++++++-- .../interop/LanguageCheckGenerator.java | 198 ++++++++++++++++++ 12 files changed, 449 insertions(+), 134 deletions(-) delete mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/AcceptMessageTest.java delete mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject10.java create mode 100644 truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java create mode 100644 truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/LanguageCheckGenerator.java diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/AcceptMessageTest.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/AcceptMessageTest.java deleted file mode 100644 index 06d47b5bc597..000000000000 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/AcceptMessageTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, 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.dsl.test.interop; - -import com.oracle.truffle.api.frame.VirtualFrame; - -@SuppressWarnings("deprecation") -@com.oracle.truffle.api.interop.AcceptMessage(value = "WRITE", receiverType = ValidTruffleObject10.class, language = TestTruffleLanguage.class) -public final class AcceptMessageTest extends AcceptMessageTestBase { - - @Override - protected int access(VirtualFrame frame, Object receiver, Object name, Object value) { - return 0; - } -} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java index 67d81006a1c9..e4a297ce4b6e 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java @@ -23,6 +23,7 @@ package com.oracle.truffle.api.dsl.test.interop; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.LanguageCheck; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -89,6 +90,14 @@ protected static int access(ExampleTruffleObject receiver, } } + @LanguageCheck + public abstract static class Check extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof ExampleTruffleObject; + } + } + } // END: com.oracle.truffle.api.dsl.test.interop.Snippets.ExampleTruffleObjectMR //@formatter:on diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject10.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject10.java deleted file mode 100644 index 5607c53b7619..000000000000 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject10.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016, 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.dsl.test.interop; - -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.TruffleObject; - -public class ValidTruffleObject10 implements TruffleObject { - - public ForeignAccess getForeignAccess() { - return ValidTruffleObject10Foreign.ACCESS; - } - - public static boolean isInstance(TruffleObject obj) { - return obj instanceof ValidTruffleObject10; - } - -} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java index 445ca85822b2..b1a110ba5b4d 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java @@ -28,27 +28,33 @@ import com.oracle.truffle.api.nodes.DirectCallNode; final class CachedObjectAccessNode extends ObjectAccessNode { - @Child private DirectCallNode callNode; + @Child private DirectCallNode callTarget; @Child private ObjectAccessNode next; + + @Child private DirectCallNode languageCheckAsNode; private final ForeignAccess languageCheck; @Child private ForeignAccessArguments accessArguments = new ForeignAccessArguments(); - protected CachedObjectAccessNode(DirectCallNode callNode, ObjectAccessNode next, ForeignAccess languageCheck) { - this.callNode = callNode; + protected CachedObjectAccessNode(DirectCallNode callTarget, ObjectAccessNode next, ForeignAccess languageCheck, DirectCallNode languageCheckAsNode) { + this.callTarget = callTarget; this.next = next; this.languageCheck = languageCheck; - this.callNode.forceInlining(); - } - - protected CachedObjectAccessNode(CachedObjectAccessNode prev) { - this(prev.callNode, prev.next, prev.languageCheck); + this.languageCheckAsNode = languageCheckAsNode; + if (this.languageCheckAsNode != null) { + this.languageCheckAsNode.forceInlining(); + } + this.callTarget.forceInlining(); } @Override public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - if (languageCheck.canHandle(receiver)) { - return callNode.call(frame, accessArguments.executeCreate(receiver, arguments)); + return doAccess(frame, receiver, arguments); + } + + private Object doAccess(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { + if ((languageCheckAsNode != null && (boolean) languageCheckAsNode.call(frame, new Object[]{receiver})) || languageCheck.canHandle(receiver)) { + return callTarget.call(frame, accessArguments.executeCreate(receiver, arguments)); } else { return next.executeWith(frame, receiver, arguments); } diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java index 0fa7776363d6..43395688efe6 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java @@ -29,10 +29,12 @@ import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.impl.ReadOnlyArrayList; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; /** * Encapsulates types of access to {@link TruffleObject}. If you want to expose your own objects to @@ -45,10 +47,16 @@ public final class ForeignAccess { private final Factory factory; private final Thread initThread; + private final RootNode languageCheck; private ForeignAccess(Factory faf) { + this(null, faf); + } + + private ForeignAccess(RootNode languageCheck, Factory faf) { this.factory = faf; this.initThread = Thread.currentThread(); + this.languageCheck = languageCheck; CompilerAsserts.neverPartOfCompilation("do not create a ForeignAccess object from compiled code"); } @@ -71,6 +79,19 @@ public static ForeignAccess create(final Class baseClas return new ForeignAccess(new DelegatingFactory(baseClass, factory)); } + /** + * Creates new instance of {@link ForeignAccess} that delegates to provided factory. + * + * @param factory the factory that handles access requests to {@link Message}s known as of + * version 1.0 + * @param languageCheck a {@link RootNode} that performs the language check on receiver objects + * @return new instance wrapping factory + * @since 0.13 or earlier + */ + public static ForeignAccess create(final Factory10 factory, final RootNode languageCheck) { + return new ForeignAccess(languageCheck, new DelegatingFactory(null, factory)); + } + /** * Creates new instance of {@link ForeignAccess} that delegates to provided factory. * @@ -480,6 +501,14 @@ CallTarget access(Message message) { return factory.accessMessage(message); } + CallTarget checkLanguage() { + if (languageCheck != null) { + return Truffle.getRuntime().createCallTarget((RootNode) languageCheck.copy()); + } else { + return null; + } + } + boolean canHandle(TruffleObject receiver) { checkThread(); return factory.canHandle(receiver); @@ -658,6 +687,10 @@ public boolean canHandle(TruffleObject obj) { @Override public CallTarget accessMessage(Message msg) { + return accessMessage(factory, msg); + } + + private static CallTarget accessMessage(Factory10 factory, Message msg) { if (msg instanceof KnownMessage) { switch (msg.hashCode()) { case Execute.EXECUTE: @@ -687,5 +720,4 @@ public CallTarget accessMessage(Message msg) { return factory.accessMessage(msg); } } - } diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java new file mode 100644 index 000000000000..4442f4ede208 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to put on your node to provide a language check for the receiver object. + * + * There must be only one element with this annotation on it. + * + * This node needs to be an abstract class. Sub-classes will be automatically generated, which is + * similar to Truffle's DSL for node specialization. The node needs to define one test + * method, which implement the receiver language check. + * + * {@link com.oracle.truffle.api.dsl.test.interop.Snippets.ExampleTruffleObjectMR} + * + * @since 0.13 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface LanguageCheck { + +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java index f7ee57478dd3..cf650a3937f0 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java @@ -47,6 +47,8 @@ * * {@link com.oracle.truffle.api.dsl.test.interop.Snippets.ExampleTruffleObject#isInstanceCheck} * + * Alternatively, one can also define a language check node (see {@link LanguageCheck}. + * * From this class a {@link ForeignAccess} will be generated. The receiver object can then return a * singleton instance of this access. For example:
* diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Resolve.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Resolve.java index 0c5fd0728e06..a8d2e71e68f8 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Resolve.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Resolve.java @@ -36,11 +36,11 @@ * messages}. * * This node needs to be an abstract class. Sub-classes will be automatically generated, which is - * similar to Truffle's DSL for node specialization. The node needs to define abstract - * accept methods, which implement the node's behaviour. The first argument of - * accept can be a {@link VirtualFrame} (optional). The second argument of - * accept needs to be the receiver object, i.e., a {@link TruffleObject}. Afterwards, - * the arguments of the message follow. For example: + * similar to Truffle's DSL for node specialization. The node needs to define accept + * methods, which implement the node's behaviour. The first argument of accept can be a + * {@link VirtualFrame} (optional). The second argument of accept needs to be the + * receiver object, i.e., a {@link TruffleObject}. Afterwards, the arguments of the message follow. + * For example: * * {@link com.oracle.truffle.api.dsl.test.interop.Snippets.ExampleTruffleObjectMR} * diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java index 181669897961..ab7bffa6798f 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.NodeUtil; final class UnresolvedObjectAccessNode extends ObjectAccessNode { @@ -54,7 +55,9 @@ private static CachedObjectAccessNode createCachedAccess(TruffleObject receiver, if (ct == null) { throw UnsupportedMessageException.raise(accessTree); } - return new CachedObjectAccessNode(Truffle.getRuntime().createDirectCallNode(ct), next, fa); + DirectCallNode access = Truffle.getRuntime().createDirectCallNode(ct); + DirectCallNode languageCheck = fa.checkLanguage() == null ? null : Truffle.getRuntime().createDirectCallNode(fa.checkLanguage()); + return new CachedObjectAccessNode(access, next, fa, languageCheck); } private static GenericObjectAccessNode createGenericAccess(Message access) { diff --git a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/ForeignAccessFactoryGenerator.java b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/ForeignAccessFactoryGenerator.java index 47a3a481e19b..3046fd107b45 100644 --- a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/ForeignAccessFactoryGenerator.java +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/ForeignAccessFactoryGenerator.java @@ -45,6 +45,8 @@ public final class ForeignAccessFactoryGenerator { private final Map messageHandlers; + private String languageCheckFactoryInvokation; + public ForeignAccessFactoryGenerator(ProcessingEnvironment processingEnv, MessageResolution messageResolutionAnnotation, TypeElement element) { this.processingEnv = processingEnv; this.element = element; @@ -52,40 +54,50 @@ public ForeignAccessFactoryGenerator(ProcessingEnvironment processingEnv, Messag this.simpleClassName = ElementUtils.getSimpleName(element) + "Foreign"; this.receiverTypeClass = Utils.getReceiverTypeFullClassName(messageResolutionAnnotation); this.messageHandlers = new HashMap<>(); + this.languageCheckFactoryInvokation = null; } public void addMessageHandler(Object message, String factoryMethodInvocation) { messageHandlers.put(message, factoryMethodInvocation); } + public void addLanguageCheckHandler(String invocation) { + this.languageCheckFactoryInvokation = invocation; + } + public void generate() throws IOException { JavaFileObject factoryFile = processingEnv.getFiler().createSourceFile(packageName + "." + simpleClassName, element); Writer w = factoryFile.openWriter(); w.append("package ").append(packageName).append(";\n"); appendImports(w); - w.append("final class ").append(simpleClassName).append(" implements Factory10, Factory {\n"); + w.append("final class ").append(simpleClassName); + w.append(" implements Factory10, Factory {\n"); appendSingletonAndGetter(w); appendPrivateConstructor(w); appendFactoryCanHandle(w); - appendFactory10accessIsNull(w); - appendFactory10accessIsExecutable(w); - appendFactory10accessIsBoxed(w); - appendFactory10accessHasSize(w); - appendFactory10accessGetSize(w); - appendFactory10accessUnbox(w); - appendFactory10accessRead(w); - appendFactory10accessWrite(w); - appendFactory10accessExecute(w); - appendFactory10accessInvoke(w); - appendFactory10accessNew(w); + appendFactoryAccessIsNull(w); + appendFactoryAccessIsExecutable(w); + appendFactoryAccessIsBoxed(w); + appendFactoryAccessHasSize(w); + appendFactoryAccessGetSize(w); + appendFactoryAccessUnbox(w); + appendFactoryAccessRead(w); + appendFactoryAccessWrite(w); + appendFactoryAccessExecute(w); + appendFactoryAccessInvoke(w); + appendFactoryAccessNew(w); appendFactoryAccessMessage(w); w.append("}\n"); w.close(); } + private boolean hasLanguageCheckNode() { + return languageCheckFactoryInvokation != null; + } + private static void appendImports(Writer w) throws IOException { w.append("import com.oracle.truffle.api.interop.UnsupportedMessageException;").append("\n"); w.append("import com.oracle.truffle.api.interop.ForeignAccess.Factory10;").append("\n"); @@ -99,8 +111,14 @@ private static void appendImports(Writer w) throws IOException { } private void appendSingletonAndGetter(Writer w) throws IOException { - w.append(" public static final ForeignAccess ACCESS = ForeignAccess.create(null, new ").append(simpleClassName).append("());").append("\n"); - w.append(" public static ForeignAccess createAccess() { return ForeignAccess.create(null, new ").append(simpleClassName).append("());}").append("\n"); + String allocation; + if (hasLanguageCheckNode()) { + allocation = "ForeignAccess.create(new " + simpleClassName + "(), " + languageCheckFactoryInvokation + ");"; + } else { + allocation = "ForeignAccess.create(null, new " + simpleClassName + "());"; + } + w.append(" public static final ForeignAccess ACCESS = ").append(allocation).append("\n"); + w.append(" public static ForeignAccess createAccess() { return ").append(allocation).append("}\n"); w.append("\n"); } @@ -111,30 +129,34 @@ private void appendPrivateConstructor(Writer w) throws IOException { private void appendFactoryCanHandle(Writer w) throws IOException { w.append(" public boolean canHandle(TruffleObject obj) {").append("\n"); - w.append(" return ").append(receiverTypeClass).append(".isInstance(obj);").append("\n"); + if (hasLanguageCheckNode()) { + w.append(" return (boolean) Truffle.getRuntime().createCallTarget(").append(languageCheckFactoryInvokation).append(").call(obj);\n"); + } else { + w.append(" return ").append(receiverTypeClass).append(".isInstance(obj);").append("\n"); + } w.append(" }").append("\n"); w.append("\n"); } - private void appendFactory10accessIsNull(Writer w) throws IOException { + private void appendFactoryAccessIsNull(Writer w) throws IOException { w.append(" public CallTarget accessIsNull() {").append("\n"); appendOptionalDefaultHandlerBody(w, Message.IS_NULL); w.append(" }").append("\n"); } - private void appendFactory10accessIsExecutable(Writer w) throws IOException { + private void appendFactoryAccessIsExecutable(Writer w) throws IOException { w.append(" public CallTarget accessIsExecutable() {").append("\n"); appendOptionalDefaultHandlerBody(w, Message.IS_EXECUTABLE); w.append(" }").append("\n"); } - private void appendFactory10accessIsBoxed(Writer w) throws IOException { + private void appendFactoryAccessIsBoxed(Writer w) throws IOException { w.append(" public CallTarget accessIsBoxed() {").append("\n"); appendOptionalDefaultHandlerBody(w, Message.IS_BOXED); w.append(" }").append("\n"); } - private void appendFactory10accessHasSize(Writer w) throws IOException { + private void appendFactoryAccessHasSize(Writer w) throws IOException { w.append(" public CallTarget accessHasSize() {").append("\n"); appendOptionalDefaultHandlerBody(w, Message.HAS_SIZE); w.append(" }").append("\n"); @@ -148,43 +170,43 @@ private void appendOptionalDefaultHandlerBody(Writer w, Message message) throws } } - private void appendFactory10accessGetSize(Writer w) throws IOException { + private void appendFactoryAccessGetSize(Writer w) throws IOException { w.append(" public CallTarget accessGetSize() {").append("\n"); appendOptionalHandlerBody(w, Message.GET_SIZE, "Message.GET_SIZE"); w.append(" }").append("\n"); } - private void appendFactory10accessUnbox(Writer w) throws IOException { + private void appendFactoryAccessUnbox(Writer w) throws IOException { w.append(" public CallTarget accessUnbox() {").append("\n"); appendOptionalHandlerBody(w, Message.UNBOX, "Message.UNBOX"); w.append(" }").append("\n"); } - private void appendFactory10accessRead(Writer w) throws IOException { + private void appendFactoryAccessRead(Writer w) throws IOException { w.append(" public CallTarget accessRead() {").append("\n"); appendOptionalHandlerBody(w, Message.READ, "Message.READ"); w.append(" }").append("\n"); } - private void appendFactory10accessWrite(Writer w) throws IOException { + private void appendFactoryAccessWrite(Writer w) throws IOException { w.append(" public CallTarget accessWrite() {").append("\n"); appendOptionalHandlerBody(w, Message.WRITE, "Message.WRITE"); w.append(" }").append("\n"); } - private void appendFactory10accessExecute(Writer w) throws IOException { + private void appendFactoryAccessExecute(Writer w) throws IOException { w.append(" public CallTarget accessExecute(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createExecute(0), "Message.createExecute(argumentsLength)"); w.append(" }").append("\n"); } - private void appendFactory10accessInvoke(Writer w) throws IOException { + private void appendFactoryAccessInvoke(Writer w) throws IOException { w.append(" public CallTarget accessInvoke(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createInvoke(0), "Message.createInvoke(argumentsLength)"); w.append(" }").append("\n"); } - private void appendFactory10accessNew(Writer w) throws IOException { + private void appendFactoryAccessNew(Writer w) throws IOException { w.append(" public CallTarget accessNew(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createNew(0), "Message.createNew(argumentsLength)"); w.append(" }").append("\n"); diff --git a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java index 3a98f5b28bca..025bec9c5711 100644 --- a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java @@ -44,6 +44,7 @@ import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.LanguageCheck; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; @@ -109,63 +110,128 @@ private void processElement(Element e) throws IOException { return; } - if (isInstanceMissing(receiverTypeFullClassName)) { + // check if there is a @LanguageCheck class + + Element curr = e; + List receiverChecks = new ArrayList<>(); + for (Element innerClass : curr.getEnclosedElements()) { + if (innerClass.getKind() != ElementKind.CLASS) { + continue; + } + if (innerClass.getAnnotation(LanguageCheck.class) != null) { + receiverChecks.add((TypeElement) innerClass); + } + } + + if (receiverChecks.size() == 0 && isInstanceMissing(receiverTypeFullClassName)) { emitError("Missing isInstance method in class " + receiverTypeFullClassName, e); return; } + if (receiverChecks.size() > 1) { + emitError("Only one @LanguageCheck element allowed", e); + return; + } + // Collect all inner classes with an @Resolve annotation - Element curr = e; + curr = e; List elements = new ArrayList<>(); - innerElements: for (Element innerClass : curr.getEnclosedElements()) { + for (Element innerClass : curr.getEnclosedElements()) { if (innerClass.getKind() != ElementKind.CLASS) { - continue innerElements; + continue; } - if (innerClass.getAnnotation(Resolve.class) == null) { - continue innerElements; + if (innerClass.getAnnotation(Resolve.class) != null) { + elements.add((TypeElement) innerClass); } - elements.add((TypeElement) innerClass); } - ForeignAccessFactoryGenerator factoryGenerator; - factoryGenerator = new ForeignAccessFactoryGenerator(processingEnv, messageImplementations, (TypeElement) e); + ForeignAccessFactoryGenerator factoryGenerator = new ForeignAccessFactoryGenerator(processingEnv, messageImplementations, (TypeElement) e); // Process inner classes with an @Resolve annotation + boolean generationSuccessfull = true; for (TypeElement elem : elements) { - processInnerClasses(elem.getAnnotation(Resolve.class), messageImplementations, elem, factoryGenerator); + generationSuccessfull &= processResolveClass(elem.getAnnotation(Resolve.class), messageImplementations, elem, factoryGenerator); + } + if (!generationSuccessfull) { + return; + } + + if (!receiverChecks.isEmpty()) { + generationSuccessfull &= processLanguageCheck(messageImplementations, receiverChecks.get(0), factoryGenerator); + } + if (!generationSuccessfull) { + return; } factoryGenerator.generate(); } - private void processInnerClasses(Resolve resolveAnnotation, MessageResolution messageResolutionAnnotation, TypeElement element, ForeignAccessFactoryGenerator factoryGenerator) throws IOException { + private boolean processLanguageCheck(MessageResolution messageResolutionAnnotation, TypeElement element, ForeignAccessFactoryGenerator factoryGenerator) + throws IOException { + LanguageCheckGenerator generator = new LanguageCheckGenerator(processingEnv, messageResolutionAnnotation, element); + + if (!ElementUtils.typeEquals(element.getSuperclass(), Utils.getTypeMirror(processingEnv, com.oracle.truffle.api.nodes.Node.class))) { + emitError(ElementUtils.getQualifiedName(element) + " must extend com.oracle.truffle.api.nodes.Node.", element); + return false; + } + + if (!element.getModifiers().contains(Modifier.ABSTRACT)) { + emitError("Class must be abstract", element); + return false; + } + + if (!element.getModifiers().contains(Modifier.STATIC)) { + emitError("Class must be static", element); + return false; + } + + List methods = generator.getTestMethods(); + if (methods.isEmpty() || methods.size() > 1) { + emitError("There needs to be exactly one test method.", element); + return false; + } + + ExecutableElement m = methods.get(0); + String errorMessage = generator.checkSignature(m); + if (errorMessage != null) { + emitError(errorMessage, m); + return false; + } + + generator.generate(); + factoryGenerator.addLanguageCheckHandler(generator.getRootNodeFactoryInvokation()); + return true; + } + + private boolean processResolveClass(Resolve resolveAnnotation, MessageResolution messageResolutionAnnotation, TypeElement element, ForeignAccessFactoryGenerator factoryGenerator) + throws IOException { MessageGenerator currentGenerator = MessageGenerator.getGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element); if (currentGenerator == null) { emitError("Unknown message type: " + resolveAnnotation.message(), element); - return; + return false; } if (!ElementUtils.typeEquals(element.getSuperclass(), Utils.getTypeMirror(processingEnv, com.oracle.truffle.api.nodes.Node.class))) { emitError(ElementUtils.getQualifiedName(element) + " must extend com.oracle.truffle.api.nodes.Node.", element); - return; + return false; } if (!element.getModifiers().contains(Modifier.ABSTRACT)) { emitError("Class must be abstract", element); - return; + return false; } if (!element.getModifiers().contains(Modifier.STATIC)) { emitError("Class must be static", element); - return; + return false; } List methods = currentGenerator.getAccessMethods(); if (methods.isEmpty()) { emitError("There needs to be at least one access method.", element); - return; + return false; } List params = methods.get(0).getParameters(); @@ -184,7 +250,7 @@ private void processInnerClasses(Resolve resolveAnnotation, MessageResolution me if (argumentSize != paramsSize) { emitError("Inconsistent argument length.", element); - return; + return false; } } @@ -192,13 +258,14 @@ private void processInnerClasses(Resolve resolveAnnotation, MessageResolution me String errorMessage = currentGenerator.checkSignature(m); if (errorMessage != null) { emitError(errorMessage, m); - return; + return false; } } currentGenerator.generate(); Object currentMessage = Utils.getMessage(processingEnv, resolveAnnotation.message()); factoryGenerator.addMessageHandler(currentMessage, currentGenerator.getRootNodeFactoryInvokation()); + return true; } private static boolean isReceiverNonStaticInner(MessageResolution message) { diff --git a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/LanguageCheckGenerator.java b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/LanguageCheckGenerator.java new file mode 100644 index 000000000000..63af9d18b5a4 --- /dev/null +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/LanguageCheckGenerator.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, 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.dsl.processor.interop; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeKind; +import javax.tools.JavaFileObject; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.dsl.processor.java.ElementUtils; + +/** + * THIS IS NOT PUBLIC API. + */ +public final class LanguageCheckGenerator { + protected static final String TEST_METHOD_NAME = "test"; + + protected final TypeElement element; + protected final String packageName; + protected final String clazzName; + protected final String userClassName; + protected final String truffleLanguageFullClazzName; + protected final ProcessingEnvironment processingEnv; + + LanguageCheckGenerator(ProcessingEnvironment processingEnv, MessageResolution messageResolutionAnnotation, TypeElement element) { + this.processingEnv = processingEnv; + this.element = element; + this.packageName = ElementUtils.getPackageName(element); + this.userClassName = ElementUtils.getQualifiedName(element); + this.truffleLanguageFullClazzName = Utils.getTruffleLanguageFullClassName(messageResolutionAnnotation); + this.clazzName = ElementUtils.getSimpleName(element) + "Sub"; + } + + public void generate() throws IOException { + JavaFileObject file = processingEnv.getFiler().createSourceFile(packageName + "." + clazzName, element); + Writer w = file.openWriter(); + w.append("package ").append(packageName).append(";\n"); + appendImports(w); + + w.append("abstract class ").append(clazzName).append(" extends ").append(userClassName).append(" {\n"); + appendExecuteWithTarget(w); + appendSpecializations(w); + + appendRootNode(w); + appendRootNodeFactory(w); + + w.append("}\n"); + w.close(); + } + + public List getTestMethods() { + List methods = new ArrayList<>(); + for (Element m : element.getEnclosedElements()) { + if (m.getKind() != ElementKind.METHOD) { + continue; + } + if (!m.getSimpleName().contentEquals(TEST_METHOD_NAME)) { + continue; + } + ExecutableElement method = (ExecutableElement) m; + methods.add(method); + } + return methods; + } + + static void appendImports(Writer w) throws IOException { + w.append("import com.oracle.truffle.api.frame.VirtualFrame;").append("\n"); + w.append("import com.oracle.truffle.api.dsl.Specialization;").append("\n"); + w.append("import com.oracle.truffle.api.nodes.RootNode;").append("\n"); + w.append("import com.oracle.truffle.api.TruffleLanguage;").append("\n"); + w.append("import com.oracle.truffle.api.interop.ForeignAccess;").append("\n"); + w.append("import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;").append("\n"); + w.append("import com.oracle.truffle.api.interop.UnsupportedTypeException;").append("\n"); + } + + public String checkSignature(ExecutableElement method) { + final List params = method.getParameters(); + boolean hasFrameArgument = false; + if (params.size() >= 1) { + hasFrameArgument = ElementUtils.typeEquals(params.get(0).asType(), Utils.getTypeMirror(processingEnv, VirtualFrame.class)); + } + int expectedNumberOfArguments = hasFrameArgument ? 2 : 1; + + if (!ElementUtils.typeEquals(params.get(hasFrameArgument ? 1 : 0).asType(), Utils.getTypeMirror(processingEnv, TruffleObject.class))) { + return "The receiver type must be TruffleObject"; + } + + if (!ElementUtils.isPrimitive(method.getReturnType()) || method.getReturnType().getKind() != TypeKind.BOOLEAN) { + return "Method must return a boolean value"; + } + + if (params.size() != expectedNumberOfArguments) { + return "Wrong number of arguments."; + } + return null; + } + + static void appendExecuteWithTarget(Writer w) throws IOException { + w.append(" public abstract Object executeWithTarget(VirtualFrame frame, ").append("Object ").append("o").append(");\n"); + } + + void appendSpecializations(Writer w) throws IOException { + String sep = ""; + List testMethods = getTestMethods(); + assert testMethods.size() == 1; + + final List params = testMethods.get(0).getParameters(); + + w.append(" @Specialization\n"); + w.append(" protected Object ").append(TEST_METHOD_NAME).append("WithTarget"); + w.append("("); + + sep = ""; + for (VariableElement p : params) { + w.append(sep).append(ElementUtils.getUniqueIdentifier(p.asType())).append(" ").append(p.getSimpleName()); + sep = ", "; + } + w.append(") {\n"); + w.append(" return ").append(TEST_METHOD_NAME).append("("); + sep = ""; + for (VariableElement p : params) { + w.append(sep).append(p.getSimpleName()); + sep = ", "; + } + w.append(");\n"); + w.append(" }\n"); + } + + void appendRootNode(Writer w) throws IOException { + w.append(" private final static class LanguageCheckRootNode extends RootNode {\n"); + w.append(" protected LanguageCheckRootNode(Class> language) {\n"); + w.append(" super(language, null, null);\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" @Child private ").append(clazzName).append(" node = ").append(packageName).append(".").append(clazzName).append("NodeGen.create();"); + w.append("\n"); + w.append(" @Override\n"); + w.append(" public Object execute(VirtualFrame frame) {\n"); + w.append(" try {\n"); + w.append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); + w.append(" return node.executeWithTarget(frame, receiver);\n"); + w.append(" } catch (UnsupportedSpecializationException e) {\n"); + w.append(" throw UnsupportedTypeException.raise(e.getSuppliedValues());\n"); + w.append(" }\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" }\n"); + } + + static void appendRootNodeFactory(Writer w) throws IOException { + w.append(" public static RootNode createRoot(Class> language) {\n"); + w.append(" return new LanguageCheckRootNode(language);\n"); + w.append(" }\n"); + + } + + public String getRootNodeFactoryInvokation() { + return packageName + "." + clazzName + ".createRoot(" + truffleLanguageFullClazzName + ".class)"; + } + + @Override + public String toString() { + return clazzName; + } +} From f2f51a277bd1cb395f7172126b4343eb574be644 Mon Sep 17 00:00:00 2001 From: Matthias Grimmer Date: Fri, 15 Apr 2016 14:35:24 +0200 Subject: [PATCH 2/5] Add tests for @LanguageCheck annotation --- .../dsl/test/interop/ValidTruffleObject1.java | 2 +- .../test/interop/ValidTruffleObject11.java | 33 ++++++++++ .../test/interop/ValidTruffleObject11MR.java | 52 ++++++++++++++++ .../test/interop/ValidTruffleObject12.java | 33 ++++++++++ .../test/interop/ValidTruffleObject12MR.java | 62 +++++++++++++++++++ .../test/interop/ValidTruffleObject13MR.java | 54 ++++++++++++++++ .../test/interop/ValidTruffleObject14MR.java | 54 ++++++++++++++++ .../dsl/test/interop/ValidTruffleObject6.java | 2 +- .../dsl/test/interop/ValidTruffleObject7.java | 2 +- .../dsl/test/interop/ValidTruffleObject8.java | 2 +- 10 files changed, 292 insertions(+), 4 deletions(-) create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11.java create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12.java create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java create mode 100644 truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject1.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject1.java index bd77b054c851..a3f5096e5b37 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject1.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject1.java @@ -32,6 +32,6 @@ public static boolean isInstance(TruffleObject obj) { @Override public ForeignAccess getForeignAccess() { - return ValidTruffleObject1MRForeign.ACCESS; + return null; } } diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11.java new file mode 100644 index 000000000000..d44407548b0d --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +public class ValidTruffleObject11 implements TruffleObject { + + public ForeignAccess getForeignAccess() { + return ValidTruffleObject11MRForeign.ACCESS; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java new file mode 100644 index 000000000000..3f664952d47f --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; + +@SuppressWarnings("unused") +@MessageResolution(receiverType = ValidTruffleObject11.class, language = TestTruffleLanguage.class) +public class ValidTruffleObject11MR { + + @Resolve(message = "READ") + public abstract static class ReadNode11 extends Node { + + protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object name) { + return 0; + } + } + + @LanguageCheck + public abstract static class LanguageCheck1 extends Node { + + protected boolean test(VirtualFrame frame, TruffleObject receiver) { + return receiver instanceof ValidTruffleObject11; + } + } + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12.java new file mode 100644 index 000000000000..1ddfff004936 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +public class ValidTruffleObject12 implements TruffleObject { + + public ForeignAccess getForeignAccess() { + return null; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java new file mode 100644 index 000000000000..ad98abc6dd8b --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; + +@SuppressWarnings("unused") +@MessageResolution(receiverType = ValidTruffleObject12.class, language = TestTruffleLanguage.class) +@ExpectError("Only one @LanguageCheck element allowed") +public class ValidTruffleObject12MR { + + @Resolve(message = "READ") + public abstract static class ReadNode12 extends Node { + + protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object name) { + return 0; + } + } + + @LanguageCheck + public abstract static class LanguageCheck1 extends Node { + + protected boolean test(VirtualFrame frame, TruffleObject receiver) { + return receiver instanceof ValidTruffleObject11; + } + } + + @LanguageCheck + public abstract static class LanguageCheck2 extends Node { + + protected boolean test(VirtualFrame frame, TruffleObject receiver) { + return receiver instanceof ValidTruffleObject11; + } + } + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java new file mode 100644 index 000000000000..fab9e3981b2f --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; + +@SuppressWarnings("unused") +@MessageResolution(receiverType = ValidTruffleObject12.class, language = TestTruffleLanguage.class) +public class ValidTruffleObject13MR { + + @Resolve(message = "READ") + public abstract static class ReadNode13 extends Node { + + protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object name) { + return 0; + } + } + + @LanguageCheck + public abstract static class LanguageCheck1 extends Node { + + @ExpectError("Method must return a boolean value") + protected Object test(VirtualFrame frame, TruffleObject receiver) { + return receiver instanceof ValidTruffleObject11; + } + } + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java new file mode 100644 index 000000000000..d144562c7d14 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, 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.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; + +@SuppressWarnings("unused") +@MessageResolution(receiverType = ValidTruffleObject12.class, language = TestTruffleLanguage.class) +public class ValidTruffleObject14MR { + + @Resolve(message = "READ") + public abstract static class ReadNode14 extends Node { + + protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object name) { + return 0; + } + } + + @LanguageCheck + public abstract static class LanguageCheck1 extends Node { + + @ExpectError("The receiver type must be TruffleObject") + protected boolean test(VirtualFrame frame, ValidTruffleObject12 receiver) { + return false; + } + } + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject6.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject6.java index 51c0c80f1a74..394f25cc7e6d 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject6.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject6.java @@ -28,7 +28,7 @@ public class ValidTruffleObject6 implements TruffleObject { public ForeignAccess getForeignAccess() { - return ValidTruffleObject6MRForeign.ACCESS; + return null; } public static boolean isInstance(TruffleObject obj) { diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject7.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject7.java index a45b9b9935d3..4a8819d9d6e2 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject7.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject7.java @@ -28,7 +28,7 @@ public class ValidTruffleObject7 implements TruffleObject { public ForeignAccess getForeignAccess() { - return ValidTruffleObject8MRForeign.ACCESS; + return null; } public static boolean isInstance(TruffleObject obj) { diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject8.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject8.java index 9f375af7a4c0..110bc6763cf1 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject8.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject8.java @@ -28,7 +28,7 @@ public class ValidTruffleObject8 implements TruffleObject { public ForeignAccess getForeignAccess() { - return ValidTruffleObject8MRForeign.ACCESS; + return null; } public static boolean isInstance(TruffleObject obj) { From fe1bb23fff6c1b8e681ad401714e7ffa3a3b0736 Mon Sep 17 00:00:00 2001 From: Matthias Grimmer Date: Tue, 19 Apr 2016 15:47:44 +0200 Subject: [PATCH 3/5] Use deep copy of can-resolve node of interop DSL --- .../src/com/oracle/truffle/api/interop/ForeignAccess.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java index 43395688efe6..39ec877d9a64 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java @@ -86,7 +86,7 @@ public static ForeignAccess create(final Class baseClas * version 1.0 * @param languageCheck a {@link RootNode} that performs the language check on receiver objects * @return new instance wrapping factory - * @since 0.13 or earlier + * @since 0.13 */ public static ForeignAccess create(final Factory10 factory, final RootNode languageCheck) { return new ForeignAccess(languageCheck, new DelegatingFactory(null, factory)); @@ -503,7 +503,7 @@ CallTarget access(Message message) { CallTarget checkLanguage() { if (languageCheck != null) { - return Truffle.getRuntime().createCallTarget((RootNode) languageCheck.copy()); + return Truffle.getRuntime().createCallTarget((RootNode) languageCheck.deepCopy()); } else { return null; } From 706194f9fe91b072cf80e78be988cdaefda43131 Mon Sep 17 00:00:00 2001 From: Matthias Grimmer Date: Tue, 19 Apr 2016 15:48:15 +0200 Subject: [PATCH 4/5] Rename LanguageCheck annotation to CanResolve --- .../com/oracle/truffle/api/dsl/test/interop/Snippets.java | 4 ++-- .../api/dsl/test/interop/ValidTruffleObject11MR.java | 4 ++-- .../api/dsl/test/interop/ValidTruffleObject12MR.java | 6 +++--- .../api/dsl/test/interop/ValidTruffleObject13MR.java | 4 ++-- .../api/dsl/test/interop/ValidTruffleObject14MR.java | 4 ++-- .../api/interop/{LanguageCheck.java => CanResolve.java} | 2 +- .../com/oracle/truffle/api/interop/MessageResolution.java | 2 +- .../truffle/dsl/processor/interop/InteropDSLProcessor.java | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) rename truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/{LanguageCheck.java => CanResolve.java} (98%) diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java index e4a297ce4b6e..2d6fcfcc634b 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Snippets.java @@ -23,7 +23,7 @@ package com.oracle.truffle.api.dsl.test.interop; import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -90,7 +90,7 @@ protected static int access(ExampleTruffleObject receiver, } } - @LanguageCheck + @CanResolve public abstract static class Check extends Node { protected static boolean test(TruffleObject receiver) { diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java index 3f664952d47f..897eedb233bd 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject11MR.java @@ -23,7 +23,7 @@ package com.oracle.truffle.api.dsl.test.interop; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -41,7 +41,7 @@ protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object } } - @LanguageCheck + @CanResolve public abstract static class LanguageCheck1 extends Node { protected boolean test(VirtualFrame frame, TruffleObject receiver) { diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java index ad98abc6dd8b..55acf2c15288 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject12MR.java @@ -24,7 +24,7 @@ import com.oracle.truffle.api.dsl.test.ExpectError; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -43,7 +43,7 @@ protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object } } - @LanguageCheck + @CanResolve public abstract static class LanguageCheck1 extends Node { protected boolean test(VirtualFrame frame, TruffleObject receiver) { @@ -51,7 +51,7 @@ protected boolean test(VirtualFrame frame, TruffleObject receiver) { } } - @LanguageCheck + @CanResolve public abstract static class LanguageCheck2 extends Node { protected boolean test(VirtualFrame frame, TruffleObject receiver) { diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java index fab9e3981b2f..8655768c82dd 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject13MR.java @@ -24,7 +24,7 @@ import com.oracle.truffle.api.dsl.test.ExpectError; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -42,7 +42,7 @@ protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object } } - @LanguageCheck + @CanResolve public abstract static class LanguageCheck1 extends Node { @ExpectError("Method must return a boolean value") diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java index d144562c7d14..042d3c5032bc 100644 --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject14MR.java @@ -24,7 +24,7 @@ import com.oracle.truffle.api.dsl.test.ExpectError; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; @@ -42,7 +42,7 @@ protected Object access(VirtualFrame frame, ValidTruffleObject1 receiver, Object } } - @LanguageCheck + @CanResolve public abstract static class LanguageCheck1 extends Node { @ExpectError("The receiver type must be TruffleObject") diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CanResolve.java similarity index 98% rename from truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java rename to truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CanResolve.java index 4442f4ede208..e72328b99d71 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/LanguageCheck.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CanResolve.java @@ -44,6 +44,6 @@ */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) -public @interface LanguageCheck { +public @interface CanResolve { } diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java index cf650a3937f0..07e042537545 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/MessageResolution.java @@ -47,7 +47,7 @@ * * {@link com.oracle.truffle.api.dsl.test.interop.Snippets.ExampleTruffleObject#isInstanceCheck} * - * Alternatively, one can also define a language check node (see {@link LanguageCheck}. + * Alternatively, one can also define a language check node (see {@link CanResolve}. * * From this class a {@link ForeignAccess} will be generated. The receiver object can then return a * singleton instance of this access. For example:
diff --git a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java index 025bec9c5711..7f6d82bdc0dc 100644 --- a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/interop/InteropDSLProcessor.java @@ -44,7 +44,7 @@ import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.LanguageCheck; +import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; @@ -118,7 +118,7 @@ private void processElement(Element e) throws IOException { if (innerClass.getKind() != ElementKind.CLASS) { continue; } - if (innerClass.getAnnotation(LanguageCheck.class) != null) { + if (innerClass.getAnnotation(CanResolve.class) != null) { receiverChecks.add((TypeElement) innerClass); } } From feec4a84e5157b24c01329c341c69b389ecdd065 Mon Sep 17 00:00:00 2001 From: Matthias Grimmer Date: Thu, 21 Apr 2016 09:06:28 +0200 Subject: [PATCH 5/5] Factor language check into guard helper method in CachedObjectAccessNode --- .../api/interop/CachedObjectAccessNode.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java index b1a110ba5b4d..a27e3a1d64ab 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java @@ -53,11 +53,25 @@ public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] a } private Object doAccess(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - if ((languageCheckAsNode != null && (boolean) languageCheckAsNode.call(frame, new Object[]{receiver})) || languageCheck.canHandle(receiver)) { + if (accept(frame, receiver)) { return callTarget.call(frame, accessArguments.executeCreate(receiver, arguments)); } else { - return next.executeWith(frame, receiver, arguments); + return doNext(frame, receiver, arguments); } } + private boolean accept(VirtualFrame frame, TruffleObject receiver) { + if ((languageCheckAsNode != null && (boolean) languageCheckAsNode.call(frame, new Object[]{receiver}))) { + return true; + } else if (languageCheckAsNode == null && languageCheck.canHandle(receiver)) { + return true; + } else { + return false; + } + } + + private Object doNext(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { + return next.executeWith(frame, receiver, arguments); + } + }