|
26 | 26 | package com.oracle.graal.python.nodes.subscript;
|
27 | 27 |
|
28 | 28 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
|
| 29 | +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; |
29 | 30 |
|
30 |
| -import com.oracle.graal.python.builtins.objects.object.PythonObject; |
31 |
| -import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.GetattributeNode; |
| 31 | +import com.oracle.graal.python.builtins.objects.PNone; |
| 32 | +import com.oracle.graal.python.nodes.ErrorMessages; |
| 33 | +import com.oracle.graal.python.nodes.PRaiseNode; |
32 | 34 | import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode;
|
| 35 | +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; |
33 | 36 | import com.oracle.graal.python.nodes.expression.ExpressionNode;
|
34 | 37 | import com.oracle.graal.python.nodes.frame.WriteNode;
|
35 | 38 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
36 | 39 | import com.oracle.graal.python.nodes.statement.StatementNode;
|
| 40 | +import com.oracle.truffle.api.CompilerDirectives; |
37 | 41 | import com.oracle.truffle.api.dsl.Cached;
|
38 | 42 | import com.oracle.truffle.api.dsl.NodeChild;
|
39 | 43 | import com.oracle.truffle.api.dsl.Specialization;
|
|
45 | 49 | @NodeChild(value = "slice", type = ExpressionNode.class)
|
46 | 50 | @NodeChild(value = "right", type = ExpressionNode.class)
|
47 | 51 | public abstract class SetItemNode extends StatementNode implements WriteNode {
|
| 52 | + @Child private PRaiseNode raiseNode; |
48 | 53 |
|
49 | 54 | public abstract ExpressionNode getPrimary();
|
50 | 55 |
|
@@ -105,22 +110,34 @@ public void executeWith(VirtualFrame frame, Object value) {
|
105 | 110 | public abstract void executeWith(VirtualFrame frame, Object primary, Object slice, Object value);
|
106 | 111 |
|
107 | 112 | @Specialization
|
108 |
| - void doSpecialObject(VirtualFrame frame, PythonObject primary, int index, Object value, |
109 |
| - @Cached("create()") GetattributeNode getSetitemNode, |
110 |
| - @Cached("create()") GetClassNode getClassNode, |
111 |
| - @Cached("create()") CallTernaryMethodNode callNode) { |
112 |
| - Object primaryClass = getClassNode.execute(primary); |
113 |
| - Object setItemMethod = getSetitemNode.execute(frame, primaryClass, __SETITEM__); |
114 |
| - callNode.execute(frame, setItemMethod, primary, index, value); |
| 113 | + void doIntIndex(VirtualFrame frame, Object primary, int index, Object value, |
| 114 | + @Cached GetClassNode getClassNode, |
| 115 | + @Cached("create(__SETITEM__)") LookupSpecialMethodNode lookupSetitem, |
| 116 | + @Cached CallTernaryMethodNode callSetitem) { |
| 117 | + Object setitem = lookupSetitem.execute(frame, getClassNode.execute(primary), primary); |
| 118 | + if (setitem == PNone.NO_VALUE) { |
| 119 | + getRaiseNode().raise(TypeError, ErrorMessages.P_OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, primary); |
| 120 | + } |
| 121 | + callSetitem.execute(frame, setitem, primary, index, value); |
115 | 122 | }
|
116 | 123 |
|
117 |
| - @Specialization |
118 |
| - void doSpecialObject1(VirtualFrame frame, Object primary, Object index, Object value, |
119 |
| - @Cached("create()") GetattributeNode getSetitemNode, |
120 |
| - @Cached("create()") GetClassNode getClassNode, |
121 |
| - @Cached("create()") CallTernaryMethodNode callNode) { |
122 |
| - Object primaryClass = getClassNode.execute(primary); |
123 |
| - Object setItemMethod = getSetitemNode.execute(frame, primaryClass, __SETITEM__); |
124 |
| - callNode.execute(frame, setItemMethod, primary, index, value); |
| 124 | + @Specialization(replaces = "doIntIndex") |
| 125 | + void doGeneric(VirtualFrame frame, Object primary, Object index, Object value, |
| 126 | + @Cached GetClassNode getClassNode, |
| 127 | + @Cached("create(__SETITEM__)") LookupSpecialMethodNode lookupSetitem, |
| 128 | + @Cached CallTernaryMethodNode callSetitem) { |
| 129 | + Object setitem = lookupSetitem.execute(frame, getClassNode.execute(primary), primary); |
| 130 | + if (setitem == PNone.NO_VALUE) { |
| 131 | + getRaiseNode().raise(TypeError, ErrorMessages.P_OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, primary); |
| 132 | + } |
| 133 | + callSetitem.execute(frame, setitem, primary, index, value); |
| 134 | + } |
| 135 | + |
| 136 | + private PRaiseNode getRaiseNode() { |
| 137 | + if (raiseNode == null) { |
| 138 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 139 | + raiseNode = insert(PRaiseNode.create()); |
| 140 | + } |
| 141 | + return raiseNode; |
125 | 142 | }
|
126 | 143 | }
|
0 commit comments