# HG changeset patch # User Matthias Grimmer # Date 1448292616 -3600 # Node ID c1f804ce6cad8c53a41e43347ee821498392947c # Parent 37fabf84537a53b7994b9b8867bd3f4439dfc775 Extend interop functionality for SL diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java --- /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); + } +} diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java --- 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); + } } diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTargetableNode.java --- /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); +} diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java --- 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; + } } diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java --- 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}); + } } diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java --- /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()); + } + } +} diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java --- /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()); + } + } + +} diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java --- /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); + } + } +} diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java --- 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); } /** diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java --- 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 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; + } } diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java --- 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; } } diff -r 37fabf84537a -r c1f804ce6cad truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java --- 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()); - } - - } }