changeset 22415:c1f804ce6cad

Extend interop functionality for SL
author Matthias Grimmer <grimmer@ssw.jku.at>
date Mon, 23 Nov 2015 16:30:16 +0100
parents 37fabf84537a
children b272920e26b2
files truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTargetableNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java
diffstat 12 files changed, 524 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java	Mon Nov 23 16:30:16 2015 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.oracle.truffle.sl.builtins;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.nodes.NodeInfo;
+import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.sl.SLLanguage;
+
+/**
+ * Built-in function to import a foreign object.
+ */
+@NodeInfo(shortName = "import")
+public abstract class SLImportBuiltin extends SLBuiltinNode {
+
+    public SLImportBuiltin() {
+        super(SourceSection.createUnavailable(SLLanguage.builtinKind, "import"));
+    }
+
+    @Specialization
+    public Object importSymbol(String name) {
+        return getContext().importSymbol(name);
+    }
+}
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -44,7 +44,9 @@
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.nodes.UnexpectedResultException;
+import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.sl.runtime.SLContext;
 import com.oracle.truffle.sl.runtime.SLFunction;
 
 /**
@@ -92,4 +94,8 @@
     public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
         return SLTypesGen.expectBoolean(executeGeneric(frame));
     }
+
+    protected static boolean isSLObject(DynamicObject object) {
+        return SLContext.isSLObject(object);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTargetableNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.oracle.truffle.sl.nodes;
+
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.source.SourceSection;
+
+public abstract class SLTargetableNode extends SLExpressionNode {
+    public SLTargetableNode(SourceSection src) {
+        super(src);
+    }
+
+    public abstract Object executeWithTarget(VirtualFrame frame, Object target);
+}
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -41,12 +41,21 @@
 package com.oracle.truffle.sl.nodes.access;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
+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.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeInfo;
+import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.api.utilities.ConditionProfile;
 import com.oracle.truffle.sl.SLException;
 import com.oracle.truffle.sl.nodes.SLExpressionNode;
+import com.oracle.truffle.sl.nodes.interop.SLForeignToSLTypeNode;
+import com.oracle.truffle.sl.nodes.interop.SLForeignToSLTypeNodeGen;
 import com.oracle.truffle.sl.runtime.SLContext;
 
 /**
@@ -54,25 +63,21 @@
  * object expression on the left side of the dot operator and then reads the named property.
  */
 @NodeInfo(shortName = ".")
-public final class SLReadPropertyNode extends SLExpressionNode {
+@NodeChild(value = "receiver", type = SLExpressionNode.class)
+public abstract class SLReadPropertyNode extends SLExpressionNode {
 
-    public static SLReadPropertyNode create(SourceSection src, SLExpressionNode receiverNode, String propertyName) {
-        return new SLReadPropertyNode(src, receiverNode, propertyName);
-    }
-
-    @Child private SLExpressionNode receiverNode;
     @Child private SLReadPropertyCacheNode cacheNode;
+    private final String propertyName;
     private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile();
 
-    private SLReadPropertyNode(SourceSection src, SLExpressionNode receiverNode, String propertyName) {
+    public SLReadPropertyNode(SourceSection src, String propertyName) {
         super(src);
-        this.receiverNode = receiverNode;
-        this.cacheNode = SLReadPropertyCacheNodeGen.create(propertyName);
+        this.propertyName = propertyName;
+        this.cacheNode = SLReadPropertyCacheNode.create(propertyName);
     }
 
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        Object object = receiverNode.executeGeneric(frame);
+    @Specialization(guards = "isSLObject(object)")
+    public Object doSLObject(DynamicObject object) {
         if (receiverTypeCondition.profile(SLContext.isSLObject(object))) {
             return cacheNode.executeObject(SLContext.castSLObject(object));
         } else {
@@ -80,4 +85,19 @@
             throw new SLException("unexpected receiver type");
         }
     }
+
+    @Child private Node foreignRead;
+    @Child private SLForeignToSLTypeNode toSLType;
+
+    @Specialization
+    public Object doForeignObject(VirtualFrame frame, TruffleObject object) {
+        if (foreignRead == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            this.foreignRead = insert(Message.READ.createNode());
+            this.toSLType = insert(SLForeignToSLTypeNodeGen.create(getSourceSection(), null));
+        }
+        Object result = ForeignAccess.execute(foreignRead, frame, object, new Object[]{propertyName});
+        Object slValue = toSLType.executeWithTarget(frame, result);
+        return slValue;
+    }
 }
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -41,8 +41,16 @@
 package com.oracle.truffle.sl.nodes.access;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.NodeChildren;
+import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
+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.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeInfo;
+import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.api.utilities.ConditionProfile;
 import com.oracle.truffle.sl.SLException;
@@ -56,11 +64,8 @@
  * value if the property already exists or adds a new property. Finally, it returns the new value.
  */
 @NodeInfo(shortName = ".=")
-public final class SLWritePropertyNode extends SLExpressionNode {
-
-    public static SLWritePropertyNode create(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) {
-        return new SLWritePropertyNode(src, receiverNode, propertyName, valueNode);
-    }
+@NodeChildren({@NodeChild(value = "receiver", type = SLExpressionNode.class), @NodeChild(value = "value", type = SLExpressionNode.class)})
+public abstract class SLWritePropertyNode extends SLExpressionNode {
 
     @Child protected SLExpressionNode receiverNode;
     protected final String propertyName;
@@ -68,18 +73,14 @@
     @Child protected SLWritePropertyCacheNode cacheNode;
     private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile();
 
-    private SLWritePropertyNode(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) {
+    SLWritePropertyNode(SourceSection src, String propertyName) {
         super(src);
-        this.receiverNode = receiverNode;
         this.propertyName = propertyName;
-        this.valueNode = valueNode;
         this.cacheNode = SLWritePropertyCacheNodeGen.create(propertyName);
     }
 
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        Object value = valueNode.executeGeneric(frame);
-        Object object = receiverNode.executeGeneric(frame);
+    @Specialization(guards = "isSLObject(object)")
+    public Object doSLObject(DynamicObject object, Object value) {
         if (receiverTypeCondition.profile(SLContext.isSLObject(object))) {
             cacheNode.executeObject(SLContext.castSLObject(object), value);
         } else {
@@ -88,4 +89,15 @@
         }
         return value;
     }
+
+    @Child private Node foreignWrite;
+
+    @Specialization
+    public Object doForeignObject(VirtualFrame frame, TruffleObject object, Object value) {
+        if (foreignWrite == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            this.foreignWrite = insert(Message.WRITE.createNode());
+        }
+        return ForeignAccess.execute(foreignWrite, frame, object, new Object[]{propertyName, value});
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.oracle.truffle.sl.nodes.interop;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.RootNode;
+import com.oracle.truffle.api.object.DynamicObject;
+import com.oracle.truffle.api.object.Property;
+import com.oracle.truffle.sl.SLLanguage;
+import com.oracle.truffle.sl.nodes.access.SLReadPropertyCacheNode;
+import com.oracle.truffle.sl.nodes.access.SLReadPropertyCacheNodeGen;
+
+public class SLForeignReadNode extends RootNode {
+
+    @Child private SLMonomorphicNameReadNode read;
+
+    public SLForeignReadNode() {
+        super(SLLanguage.class, null, null);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        if (read == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            String name = (String) ForeignAccess.getArguments(frame).get(0);
+            read = insert(new SLMonomorphicNameReadNode(name));
+        }
+        return read.execute(frame);
+    }
+
+    private static abstract class SLReadNode extends Node {
+        abstract Object execute(VirtualFrame frame);
+    }
+
+    private static final class SLMonomorphicNameReadNode extends SLReadNode {
+
+        private final String name;
+        @Child private SLReadPropertyCacheNode readPropertyCacheNode;
+
+        SLMonomorphicNameReadNode(String name) {
+            this.name = name;
+            this.readPropertyCacheNode = SLReadPropertyCacheNodeGen.create(name);
+        }
+
+        @Override
+        Object execute(VirtualFrame frame) {
+            if (name.equals(ForeignAccess.getArguments(frame).get(0))) {
+                return readPropertyCacheNode.executeObject((DynamicObject) ForeignAccess.getReceiver(frame));
+            } else {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                return this.replace(new SLPolymorphicNameReadNode()).execute(frame);
+            }
+        }
+    }
+
+    private static final class SLPolymorphicNameReadNode extends SLReadNode {
+
+        @Override
+        Object execute(VirtualFrame frame) {
+            String name = (String) ForeignAccess.getArguments(frame).get(0);
+            DynamicObject obj = (DynamicObject) ForeignAccess.getReceiver(frame);
+            Property property = obj.getShape().getProperty(name);
+            return obj.get(property.getKey());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.oracle.truffle.sl.nodes.interop;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+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.nodes.Node;
+import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.sl.nodes.SLExpressionNode;
+import com.oracle.truffle.sl.nodes.SLTargetableNode;
+import com.oracle.truffle.sl.runtime.SLContext;
+
+@NodeChild(type = SLExpressionNode.class)
+public abstract class SLForeignToSLTypeNode extends SLTargetableNode {
+
+    public SLForeignToSLTypeNode(SourceSection src) {
+        super(src);
+    }
+
+    @Specialization(guards = "isBoxedPrimitive(frame, value)")
+    public Object unbox(VirtualFrame frame, TruffleObject value) {
+        Object unboxed = doUnbox(frame, value);
+        return SLContext.fromForeignValue(unboxed);
+    }
+
+    @Specialization
+    public Object fromTruffleObject(TruffleObject value) {
+        return value;
+    }
+
+    @Specialization
+    public Object fromObject(Object value) {
+        return SLContext.fromForeignValue(value);
+    }
+
+    @Child private Node isBoxed;
+
+    protected final boolean isBoxedPrimitive(VirtualFrame frame, TruffleObject object) {
+        if (isBoxed == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            isBoxed = insert(Message.IS_BOXED.createNode());
+        }
+        return (boolean) ForeignAccess.execute(isBoxed, frame, object);
+    }
+
+    protected final Object doUnbox(VirtualFrame frame, TruffleObject value) {
+        initializeUnbox();
+        Object object = ForeignAccess.execute(unbox, frame, value);
+        return object;
+    }
+
+    @Child private Node unbox;
+
+    private void initializeUnbox() {
+        if (unbox == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            unbox = insert(Message.UNBOX.createNode());
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java	Mon Nov 23 16:30:16 2015 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or
+ * data (collectively the "Software"), free of charge and under any and all
+ * copyright rights in the Software, and any and all patent rights owned or
+ * freely licensable by each licensor hereunder covering either (i) the
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
+ * the Larger Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ *
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ *
+ * The above copyright notice and either this complete permission notice or at a
+ * minimum a reference to the UPL must be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.oracle.truffle.sl.nodes.interop;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.RootNode;
+import com.oracle.truffle.api.object.DynamicObject;
+import com.oracle.truffle.api.object.Property;
+import com.oracle.truffle.sl.SLLanguage;
+import com.oracle.truffle.sl.nodes.access.SLWritePropertyCacheNode;
+import com.oracle.truffle.sl.nodes.access.SLWritePropertyCacheNodeGen;
+
+public class SLForeignWriteNode extends RootNode {
+
+    @Child private SLMonomorphicNameWriteNode write;
+
+    public SLForeignWriteNode() {
+        super(SLLanguage.class, null, null);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        if (write == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            String name = (String) ForeignAccess.getArguments(frame).get(0);
+            write = insert(new SLMonomorphicNameWriteNode(name));
+        }
+        return write.execute(frame);
+    }
+
+    private static abstract class SLWriteNode extends Node {
+        @Child protected SLForeignToSLTypeNode toSLType = SLForeignToSLTypeNodeGen.create(getSourceSection(), null);
+
+        abstract Object execute(VirtualFrame frame);
+    }
+
+    private static final class SLMonomorphicNameWriteNode extends SLWriteNode {
+
+        private final String name;
+        @Child private SLWritePropertyCacheNode writePropertyCacheNode;
+
+        SLMonomorphicNameWriteNode(String name) {
+            this.name = name;
+            this.writePropertyCacheNode = SLWritePropertyCacheNodeGen.create(name);
+        }
+
+        @Override
+        Object execute(VirtualFrame frame) {
+            if (name.equals(ForeignAccess.getArguments(frame).get(0))) {
+                Object value = toSLType.executeWithTarget(frame, ForeignAccess.getArguments(frame).get(1));
+                DynamicObject receiver = (DynamicObject) ForeignAccess.getReceiver(frame);
+                writePropertyCacheNode.executeObject(receiver, value);
+                return receiver;
+            } else {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                return this.replace(new SLPolymorphicNameWriteNode()).execute(frame);
+            }
+        }
+    }
+
+    private static final class SLPolymorphicNameWriteNode extends SLWriteNode {
+
+        @Override
+        Object execute(VirtualFrame frame) {
+            String name = (String) ForeignAccess.getArguments(frame).get(0);
+            DynamicObject obj = (DynamicObject) ForeignAccess.getReceiver(frame);
+            Property property = obj.getShape().getProperty(name);
+            Object value = toSLType.executeWithTarget(frame, ForeignAccess.getArguments(frame).get(0));
+            return obj.set(property.getKey(), value);
+        }
+    }
+}
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java	Mon Nov 23 16:30:16 2015 +0100
@@ -56,7 +56,9 @@
 import com.oracle.truffle.sl.nodes.SLRootNode;
 import com.oracle.truffle.sl.nodes.SLStatementNode;
 import com.oracle.truffle.sl.nodes.access.SLReadPropertyNode;
+import com.oracle.truffle.sl.nodes.access.SLReadPropertyNodeGen;
 import com.oracle.truffle.sl.nodes.access.SLWritePropertyNode;
+import com.oracle.truffle.sl.nodes.access.SLWritePropertyNodeGen;
 import com.oracle.truffle.sl.nodes.call.SLInvokeNode;
 import com.oracle.truffle.sl.nodes.call.SLInvokeNodeGen;
 import com.oracle.truffle.sl.nodes.controlflow.SLBlockNode;
@@ -406,7 +408,7 @@
         final int startPos = receiverNode.getSourceSection().getCharIndex();
         final int endPos = nameToken.charPos + nameToken.val.length();
         final SourceSection src = source.createSection(".", startPos, endPos - startPos);
-        return SLReadPropertyNode.create(src, receiverNode, nameToken.val);
+        return SLReadPropertyNodeGen.create(src, nameToken.val, receiverNode);
     }
 
     /**
@@ -421,7 +423,7 @@
         final int start = receiverNode.getSourceSection().getCharIndex();
         final int length = valueNode.getSourceSection().getCharEndIndex() - start;
         SourceSection src = source.createSection("=", start, length);
-        return SLWritePropertyNode.create(src, receiverNode, nameToken.val, valueNode);
+        return SLWritePropertyNodeGen.create(src, nameToken.val, receiverNode, valueNode);
     }
 
     /**
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Mon Nov 23 16:30:16 2015 +0100
@@ -44,6 +44,7 @@
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.dsl.NodeFactory;
 import com.oracle.truffle.api.frame.FrameDescriptor;
+import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Layout;
@@ -57,6 +58,7 @@
 import com.oracle.truffle.sl.builtins.SLDefineFunctionBuiltinFactory;
 import com.oracle.truffle.sl.builtins.SLEvalBuiltinFactory;
 import com.oracle.truffle.sl.builtins.SLHelloEqualsWorldBuiltinFactory;
+import com.oracle.truffle.sl.builtins.SLImportBuiltinFactory;
 import com.oracle.truffle.sl.builtins.SLNanoTimeBuiltinFactory;
 import com.oracle.truffle.sl.builtins.SLNewObjectBuiltinFactory;
 import com.oracle.truffle.sl.builtins.SLPrintlnBuiltin;
@@ -156,6 +158,7 @@
         installBuiltin(SLAssertFalseBuiltinFactory.getInstance(), registerRootNodes);
         installBuiltin(SLNewObjectBuiltinFactory.getInstance(), registerRootNodes);
         installBuiltin(SLEvalBuiltinFactory.getInstance(), registerRootNodes);
+        installBuiltin(SLImportBuiltinFactory.getInstance(), registerRootNodes);
     }
 
     public void installBuiltin(NodeFactory<? extends SLBuiltinNode> factory, boolean registerRootNodes) {
@@ -217,8 +220,8 @@
         return LAYOUT.newInstance(emptyShape);
     }
 
-    public static boolean isSLObject(Object value) {
-        return LAYOUT.getType().isInstance(value);
+    public static boolean isSLObject(TruffleObject value) {
+        return value instanceof DynamicObject && ((DynamicObject) value).getShape().getObjectType() instanceof SLObjectType;
     }
 
     public static DynamicObject castSLObject(Object value) {
@@ -226,15 +229,23 @@
     }
 
     public static Object fromForeignValue(Object a) {
-        if (a instanceof Long || a instanceof BigInteger) {
+        if (a instanceof Long || a instanceof BigInteger || a instanceof String) {
             return a;
         } else if (a instanceof Number) {
             return ((Number) a).longValue();
+        } else if (a instanceof TruffleObject) {
+            return a;
         }
-        return a;
+        throw new IllegalStateException(a + " is not a Truffle value");
     }
 
     public Object evalAny(Source source) throws IOException {
         return env.parse(source).call();
     }
+
+    public Object importSymbol(String name) {
+        Object object = env.importSymbol(name);
+        Object slValue = fromForeignValue(object);
+        return slValue;
+    }
 }
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java	Mon Nov 23 16:30:16 2015 +0100
@@ -105,7 +105,8 @@
             for (int i = 0; i < arr.length; i++) {
                 arr[i] = fromForeignValue(arr[i]);
             }
-            return dispatch.executeDispatch(frame, function, arr);
+            Object result = dispatch.executeDispatch(frame, function, arr);
+            return result;
         }
     }
 
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java	Wed Nov 18 12:49:12 2015 +0100
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java	Mon Nov 23 16:30:16 2015 +0100
@@ -42,15 +42,14 @@
 
 import com.oracle.truffle.api.CallTarget;
 import com.oracle.truffle.api.Truffle;
-import com.oracle.truffle.api.frame.VirtualFrame;
 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.nodes.RootNode;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.ObjectType;
-import com.oracle.truffle.api.object.Property;
-import com.oracle.truffle.sl.SLLanguage;
+import com.oracle.truffle.sl.nodes.interop.SLForeignReadNode;
+import com.oracle.truffle.sl.nodes.interop.SLForeignWriteNode;
 
 final class SLObjectType extends ObjectType implements ForeignAccess.Factory10, ForeignAccess.Factory {
     private final ForeignAccess access;
@@ -101,7 +100,7 @@
 
     @Override
     public CallTarget accessWrite() {
-        throw new UnsupportedOperationException();
+        return Truffle.getRuntime().createCallTarget(new SLForeignWriteNode());
     }
 
     @Override
@@ -129,19 +128,4 @@
         return SLContext.isSLObject(obj);
     }
 
-    private static class SLForeignReadNode extends RootNode {
-
-        public SLForeignReadNode() {
-            super(SLLanguage.class, null, null);
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            String fieldName = (String) ForeignAccess.getArguments(frame).get(0);
-            DynamicObject obj = (DynamicObject) ForeignAccess.getReceiver(frame);
-            Property property = obj.getShape().getProperty(fieldName);
-            return obj.get(property.getKey());
-        }
-
-    }
 }