# HG changeset patch # User Jaroslav Tulach # Date 1442230383 -7200 # Node ID 5857f5ee948648a4e67e8a472ad9ec5d0f2853ad # Parent d5f809827bf12efc3741d1b138c6beb6c0c0f63e More precise description of inter-operability messages and examples of their usage. Step #1 - e.g. the trivial messages. diff -r d5f809827bf1 -r 5857f5ee9486 truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java Mon Sep 14 12:23:58 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java Mon Sep 14 13:33:03 2015 +0200 @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.interop; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.interop.ForeignAccess.Factory; @@ -36,26 +37,67 @@ /** * Message to read an object field. The * {@link Factory#access(com.oracle.truffle.api.interop.Message) target} created for this - * message accepts single {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) - * argument} identifying a field to read - e.g. either {@link String} or an {@link Integer} - if - * access to an array at particular index is requested. + * message accepts (in addition to a + * {@link ForeignAccess#getReceiver(com.oracle.truffle.api.frame.Frame) receiver}) a single + * {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) argument} identifying a + * field to read - e.g. either {@link String} or an {@link Integer} - if access to an array at + * particular index is requested. The code that wants to send this message should use: + * + *
+     * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#READ}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver, nameOfTheField
+     * );
+     * 
+ * + * Where receiver is the {@link TruffleObject foreign object} to access and + * nameOfTheField is the name (or index) of its field. + *

+ * To achieve good performance it is essential to cache/keep reference to the + * {@link Message#createNode() created node}. */ public static final Message READ = Read.INSTANCE; /** * Converts {@link TruffleObject truffle value} to Java primitive type. Primitive types are - * subclasses of {@link Number}, {@link Boolean}, {@link Character} and {@link String}. Related - * to {@link #IS_BOXED} message. + * subclasses of {@link Number}, {@link Boolean}, {@link Character} and {@link String}. Before + * sending the {@link #UNBOX} message, it is desirable to send the {@link #IS_BOXED} one and + * verify that the object can really be unboxed. To unbox an object, use: + * + *

+     * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#UNBOX}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToUnbox
+     * );
+     * 
+ * + * The returned value should be subclass of {@link Number}, {@link Boolean}, {@link Character} + * or {@link String}. + *

+ * To achieve good performance it is essential to cache/keep reference to the + * {@link Message#createNode() created node}. */ public static final Message UNBOX = Unbox.INSTANCE; /** * Message to write a field. The {@link Factory#access(com.oracle.truffle.api.interop.Message) - * target} created for this message accepts two + * target} created for this message accepts the object to modify as a + * {@link ForeignAccess#getReceiver(com.oracle.truffle.api.frame.Frame) receiver} and two * {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) arguments}. The first * one identifies a field to read - e.g. either {@link String} or an {@link Integer} - if access * to an array at particular index is requested. The second one is the value to assign to such - * field. + * field. Use following style to construct field modification message: + * + *

+     * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#WRITE}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver, nameOfTheField, newValue
+     * );
+     * 
+ * + * Where receiver is the {@link TruffleObject foreign object} to access, + * nameOfTheField is the name (or index) of its field and newValue is + * the value to assign to the receiver's field. + *

+ * To achieve good performance it is essential to cache/keep reference to the + * {@link Message#createNode() created node}. */ public static Message WRITE = Write.INSTANCE; @@ -72,10 +114,25 @@ } /** - * Message to check for executability. + * Message to check executability of a + * {@link ForeignAccess#getReceiver(com.oracle.truffle.api.frame.Frame) foreign object}. *

* Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for - * this message should yield value of {@link Boolean}. + * this message accepts {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) no + * arguments} and a single non-null + * {@link ForeignAccess#getReceiver(com.oracle.truffle.api.frame.Frame) receiver}. The call + * should yield value of {@link Boolean}. Either {@link Boolean#TRUE} if the receiver can be + * executed (e.g. accepts {@link #createExecute(int)} message, or {@link Boolean#FALSE} + * otherwise. This is the way to send the IS_EXECUTABLE message: + * + *

+     * {@link Boolean} canBeExecuted = ({@link Boolean}) {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#IS_EXECUTABLE}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver
+     * );
+     * 
+ *

+ * To achieve good performance it is essential to cache/keep reference to the + * {@link Message#createNode() created node}. */ public static final Message IS_EXECUTABLE = IsExecutable.INSTANCE; @@ -110,10 +167,20 @@ * Check for null message. The Truffle languages are suggested to have their own * object representing null like values in their languages. For purposes of * inter-operability it is essential to canonicalize such values from time to time - sending - * this message is a way to recognize such null representing values. + * this message is a way to recognize such null representing values: + * + *

+     * {@link Boolean} isNull = ({@link Boolean}) {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#IS_NULL}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToCheckForNull
+     * );
+     * 
+ * *

* Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for * this message should yield value of {@link Boolean}. + *

+ * To achieve good performance it is essential to cache/keep reference to the + * {@link Message#createNode() created node}. */ public static final Message IS_NULL = IsNull.INSTANCE; @@ -135,13 +202,21 @@ public static final Message GET_SIZE = GetSize.INSTANCE; /** - * Check for value being boxed. Can you value be converted to one of the basic Java types? Many - * languages have a special representation for types like number, string, etc. To ensure - * inter-operability, these types should support unboxing - if they do, they should handle this - * message. - *

+ * Check for value being boxed. Can the {@link TruffleObject foreign object} be converted to one + * of the basic Java types? Many languages have a special representation for types like number, + * string, etc. To ensure inter-operability, these types should support unboxing - if they do, + * they should handle this message and return {@link Boolean#TRUE}. The way to check whether an + * object is boxed is: + * + *

+     * {@link Boolean} isBoxed = ({@link Boolean}) {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
+     *   {@link Message#IS_BOXED}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToCheck
+     * );
+     * 
+ * * Calling {@link Factory#accessMessage(com.oracle.truffle.api.interop.Message) the target} - * created for this message should yield value of {@link Boolean}. + * created for this message should yield value of {@link Boolean}. If the object responds with + * {@link Boolean#TRUE}, it is safe to continue by sending it {@link #UNBOX} message. */ public static final Message IS_BOXED = IsBoxed.INSTANCE; diff -r d5f809827bf1 -r 5857f5ee9486 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Mon Sep 14 12:23:58 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Mon Sep 14 13:33:03 2015 +0200 @@ -197,8 +197,8 @@ /** * Helper method to create a root node that always returns the same value. Certain operations - * (expecially {@link com.oracle.truffle.api.interop inter-operability} API) require return - * of stable {@link RootNode root nodes}. To simplify creation of such nodes, here is a factory + * (expecially {@link com.oracle.truffle.api.interop inter-operability} API) require return of + * stable {@link RootNode root nodes}. To simplify creation of such nodes, here is a factory * method that can create {@link RootNode} that returns always the same value. * * @param constant the constant to return