|
41 | 41 | import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
|
42 | 42 | import com.oracle.graal.python.nodes.call.CallNode;
|
43 | 43 | import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
|
| 44 | +import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode.NotImplementedHandler; |
44 | 45 | import com.oracle.graal.python.nodes.expression.BinaryOpNode;
|
45 | 46 | import com.oracle.graal.python.nodes.expression.ExpressionNode;
|
46 | 47 | import com.oracle.graal.python.nodes.frame.ReadNode;
|
|
58 | 59 | public abstract class GetItemNode extends BinaryOpNode implements ReadNode {
|
59 | 60 | private static final String P_OBJECT_IS_NOT_SUBSCRIPTABLE = "'%p' object is not subscriptable";
|
60 | 61 |
|
61 |
| - @Child private LookupAndCallBinaryNode callGetitemNode; |
62 |
| - |
63 | 62 | public ExpressionNode getPrimary() {
|
64 | 63 | return getLeftNode();
|
65 | 64 | }
|
@@ -124,47 +123,49 @@ public Object doTupleError(VirtualFrame frame, PTuple primary, Object index,
|
124 | 123 | }
|
125 | 124 |
|
126 | 125 | @Specialization(replaces = {"doBuiltinList", "doBuiltinTuple"})
|
127 |
| - Object doAnyObject(VirtualFrame frame, Object primary, Object index) { |
128 |
| - if (callGetitemNode == null) { |
129 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
130 |
| - callGetitemNode = insert(LookupAndCallBinaryNode.create(__GETITEM__, null, () -> new LookupAndCallBinaryNode.NotImplementedHandler() { |
131 |
| - @Child private IsBuiltinClassProfile isBuiltinClassProfile; |
132 |
| - @Child private PRaiseNode raiseNode; |
133 |
| - @Child private CallNode callClassGetItemNode; |
134 |
| - @Child private GetAttributeNode getClassGetItemNode; |
135 |
| - |
136 |
| - @Override |
137 |
| - public Object execute(VirtualFrame frame, Object arg, Object arg2) { |
138 |
| - if (PGuards.isPythonClass(arg)) { |
139 |
| - if (getClassGetItemNode == null) { |
140 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
141 |
| - getClassGetItemNode = insert(GetAttributeNode.create(__CLASS_GETITEM__)); |
142 |
| - isBuiltinClassProfile = insert(IsBuiltinClassProfile.create()); |
143 |
| - } |
144 |
| - Object classGetItem = null; |
145 |
| - try { |
146 |
| - classGetItem = getClassGetItemNode.executeObject(frame, arg); |
147 |
| - } catch (PException e) { |
148 |
| - e.expect(AttributeError, isBuiltinClassProfile); |
149 |
| - // fall through to normal error handling |
150 |
| - } |
151 |
| - if (classGetItem != null) { |
152 |
| - if (callClassGetItemNode == null) { |
153 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
154 |
| - callClassGetItemNode = insert(CallNode.create()); |
155 |
| - } |
156 |
| - return callClassGetItemNode.execute(frame, classGetItem, arg2); |
157 |
| - } |
158 |
| - } |
159 |
| - if (raiseNode == null) { |
| 126 | + Object doAnyObject(VirtualFrame frame, Object primary, Object index, |
| 127 | + @Cached("createGetItemLookupAndCall()") LookupAndCallBinaryNode callGetitemNode) { |
| 128 | + return callGetitemNode.executeObject(frame, primary, index); |
| 129 | + } |
| 130 | + |
| 131 | + public static LookupAndCallBinaryNode createGetItemLookupAndCall() { |
| 132 | + return LookupAndCallBinaryNode.create(__GETITEM__, null, GetItemNodeNotImplementedHandler::new); |
| 133 | + } |
| 134 | + |
| 135 | + private static final class GetItemNodeNotImplementedHandler extends NotImplementedHandler { |
| 136 | + @Child private IsBuiltinClassProfile isBuiltinClassProfile; |
| 137 | + @Child private PRaiseNode raiseNode; |
| 138 | + @Child private CallNode callClassGetItemNode; |
| 139 | + @Child private GetAttributeNode getClassGetItemNode; |
| 140 | + |
| 141 | + @Override |
| 142 | + public Object execute(VirtualFrame frame, Object arg, Object arg2) { |
| 143 | + if (PGuards.isPythonClass(arg)) { |
| 144 | + if (getClassGetItemNode == null) { |
| 145 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 146 | + getClassGetItemNode = insert(GetAttributeNode.create(__CLASS_GETITEM__)); |
| 147 | + isBuiltinClassProfile = insert(IsBuiltinClassProfile.create()); |
| 148 | + } |
| 149 | + Object classGetItem = null; |
| 150 | + try { |
| 151 | + classGetItem = getClassGetItemNode.executeObject(frame, arg); |
| 152 | + } catch (PException e) { |
| 153 | + e.expect(AttributeError, isBuiltinClassProfile); |
| 154 | + // fall through to normal error handling |
| 155 | + } |
| 156 | + if (classGetItem != null) { |
| 157 | + if (callClassGetItemNode == null) { |
160 | 158 | CompilerDirectives.transferToInterpreterAndInvalidate();
|
161 |
| - raiseNode = insert(PRaiseNode.create()); |
| 159 | + callClassGetItemNode = insert(CallNode.create()); |
162 | 160 | }
|
163 |
| - throw raiseNode.raise(TypeError, P_OBJECT_IS_NOT_SUBSCRIPTABLE, arg); |
| 161 | + return callClassGetItemNode.execute(frame, classGetItem, arg2); |
164 | 162 | }
|
165 |
| - })); |
| 163 | + } |
| 164 | + if (raiseNode == null) { |
| 165 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 166 | + raiseNode = insert(PRaiseNode.create()); |
| 167 | + } |
| 168 | + throw raiseNode.raise(TypeError, P_OBJECT_IS_NOT_SUBSCRIPTABLE, arg); |
166 | 169 | }
|
167 |
| - return callGetitemNode.executeObject(frame, primary, index); |
168 | 170 | }
|
169 |
| - |
170 | 171 | }
|
0 commit comments