Mercurial > hg > truffle
comparison truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java @ 22415:c1f804ce6cad
Extend interop functionality for SL
author | Matthias Grimmer <grimmer@ssw.jku.at> |
---|---|
date | Mon, 23 Nov 2015 16:30:16 +0100 |
parents | dc83cc1f94f2 |
children | b272920e26b2 |
comparison
equal
deleted
inserted
replaced
22383:37fabf84537a | 22415:c1f804ce6cad |
---|---|
39 * SOFTWARE. | 39 * SOFTWARE. |
40 */ | 40 */ |
41 package com.oracle.truffle.sl.nodes.access; | 41 package com.oracle.truffle.sl.nodes.access; |
42 | 42 |
43 import com.oracle.truffle.api.CompilerDirectives; | 43 import com.oracle.truffle.api.CompilerDirectives; |
44 import com.oracle.truffle.api.dsl.NodeChild; | |
45 import com.oracle.truffle.api.dsl.NodeChildren; | |
46 import com.oracle.truffle.api.dsl.Specialization; | |
44 import com.oracle.truffle.api.frame.VirtualFrame; | 47 import com.oracle.truffle.api.frame.VirtualFrame; |
48 import com.oracle.truffle.api.interop.ForeignAccess; | |
49 import com.oracle.truffle.api.interop.Message; | |
50 import com.oracle.truffle.api.interop.TruffleObject; | |
51 import com.oracle.truffle.api.nodes.Node; | |
45 import com.oracle.truffle.api.nodes.NodeInfo; | 52 import com.oracle.truffle.api.nodes.NodeInfo; |
53 import com.oracle.truffle.api.object.DynamicObject; | |
46 import com.oracle.truffle.api.source.SourceSection; | 54 import com.oracle.truffle.api.source.SourceSection; |
47 import com.oracle.truffle.api.utilities.ConditionProfile; | 55 import com.oracle.truffle.api.utilities.ConditionProfile; |
48 import com.oracle.truffle.sl.SLException; | 56 import com.oracle.truffle.sl.SLException; |
49 import com.oracle.truffle.sl.nodes.SLExpressionNode; | 57 import com.oracle.truffle.sl.nodes.SLExpressionNode; |
50 import com.oracle.truffle.sl.runtime.SLContext; | 58 import com.oracle.truffle.sl.runtime.SLContext; |
54 * expression on the right hand side of the equals operator, followed by the object expression on | 62 * expression on the right hand side of the equals operator, followed by the object expression on |
55 * the left side of the dot operator, and then sets the named property of this object to the new | 63 * the left side of the dot operator, and then sets the named property of this object to the new |
56 * value if the property already exists or adds a new property. Finally, it returns the new value. | 64 * value if the property already exists or adds a new property. Finally, it returns the new value. |
57 */ | 65 */ |
58 @NodeInfo(shortName = ".=") | 66 @NodeInfo(shortName = ".=") |
59 public final class SLWritePropertyNode extends SLExpressionNode { | 67 @NodeChildren({@NodeChild(value = "receiver", type = SLExpressionNode.class), @NodeChild(value = "value", type = SLExpressionNode.class)}) |
60 | 68 public abstract class SLWritePropertyNode extends SLExpressionNode { |
61 public static SLWritePropertyNode create(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) { | |
62 return new SLWritePropertyNode(src, receiverNode, propertyName, valueNode); | |
63 } | |
64 | 69 |
65 @Child protected SLExpressionNode receiverNode; | 70 @Child protected SLExpressionNode receiverNode; |
66 protected final String propertyName; | 71 protected final String propertyName; |
67 @Child protected SLExpressionNode valueNode; | 72 @Child protected SLExpressionNode valueNode; |
68 @Child protected SLWritePropertyCacheNode cacheNode; | 73 @Child protected SLWritePropertyCacheNode cacheNode; |
69 private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile(); | 74 private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile(); |
70 | 75 |
71 private SLWritePropertyNode(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) { | 76 SLWritePropertyNode(SourceSection src, String propertyName) { |
72 super(src); | 77 super(src); |
73 this.receiverNode = receiverNode; | |
74 this.propertyName = propertyName; | 78 this.propertyName = propertyName; |
75 this.valueNode = valueNode; | |
76 this.cacheNode = SLWritePropertyCacheNodeGen.create(propertyName); | 79 this.cacheNode = SLWritePropertyCacheNodeGen.create(propertyName); |
77 } | 80 } |
78 | 81 |
79 @Override | 82 @Specialization(guards = "isSLObject(object)") |
80 public Object executeGeneric(VirtualFrame frame) { | 83 public Object doSLObject(DynamicObject object, Object value) { |
81 Object value = valueNode.executeGeneric(frame); | |
82 Object object = receiverNode.executeGeneric(frame); | |
83 if (receiverTypeCondition.profile(SLContext.isSLObject(object))) { | 84 if (receiverTypeCondition.profile(SLContext.isSLObject(object))) { |
84 cacheNode.executeObject(SLContext.castSLObject(object), value); | 85 cacheNode.executeObject(SLContext.castSLObject(object), value); |
85 } else { | 86 } else { |
86 CompilerDirectives.transferToInterpreter(); | 87 CompilerDirectives.transferToInterpreter(); |
87 throw new SLException("unexpected receiver type"); | 88 throw new SLException("unexpected receiver type"); |
88 } | 89 } |
89 return value; | 90 return value; |
90 } | 91 } |
92 | |
93 @Child private Node foreignWrite; | |
94 | |
95 @Specialization | |
96 public Object doForeignObject(VirtualFrame frame, TruffleObject object, Object value) { | |
97 if (foreignWrite == null) { | |
98 CompilerDirectives.transferToInterpreterAndInvalidate(); | |
99 this.foreignWrite = insert(Message.WRITE.createNode()); | |
100 } | |
101 return ForeignAccess.execute(foreignWrite, frame, object, new Object[]{propertyName, value}); | |
102 } | |
91 } | 103 } |