|
230 | 230 | import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
|
231 | 231 | import com.oracle.graal.python.nodes.expression.InplaceArithmetic;
|
232 | 232 | import com.oracle.graal.python.nodes.expression.LookupAndCallInplaceNode;
|
| 233 | +import com.oracle.graal.python.nodes.expression.UnaryArithmetic; |
233 | 234 | import com.oracle.graal.python.nodes.frame.GetCurrentFrameRef;
|
234 | 235 | import com.oracle.graal.python.nodes.function.FunctionRootNode;
|
235 | 236 | import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
|
@@ -4077,6 +4078,75 @@ static int doBytes(PBytes bytes,
|
4077 | 4078 | }
|
4078 | 4079 | }
|
4079 | 4080 |
|
| 4081 | + // directly called without landing function |
| 4082 | + @Builtin(name = "PyNumber_UnaryOp", minNumOfPositionalArgs = 2) |
| 4083 | + @GenerateNodeFactory |
| 4084 | + abstract static class PyNumberUnaryOp extends PythonBinaryBuiltinNode { |
| 4085 | + static int MAX_CACHE_SIZE = UnaryArithmetic.values().length; |
| 4086 | + |
| 4087 | + @Specialization(guards = {"cachedOp == op", "left.isIntLike()"}, limit = "MAX_CACHE_SIZE") |
| 4088 | + static Object doIntLikePrimitiveWrapper(VirtualFrame frame, PrimitiveNativeWrapper left, @SuppressWarnings("unused") int op, |
| 4089 | + @Cached("op") @SuppressWarnings("unused") int cachedOp, |
| 4090 | + @Cached("createCallNode(op)") LookupAndCallUnaryNode callNode, |
| 4091 | + @Cached ToNewRefNode toSulongNode, |
| 4092 | + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, |
| 4093 | + @Cached GetNativeNullNode getNativeNullNode) { |
| 4094 | + try { |
| 4095 | + return toSulongNode.execute(callNode.executeObject(frame, left.getLong())); |
| 4096 | + } catch (PException e) { |
| 4097 | + transformExceptionToNativeNode.execute(e); |
| 4098 | + return toSulongNode.execute(getNativeNullNode.execute()); |
| 4099 | + } |
| 4100 | + } |
| 4101 | + |
| 4102 | + @Specialization(guards = "cachedOp == op", limit = "MAX_CACHE_SIZE", replaces = "doIntLikePrimitiveWrapper") |
| 4103 | + static Object doObject(VirtualFrame frame, Object left, @SuppressWarnings("unused") int op, |
| 4104 | + @Cached AsPythonObjectNode leftToJava, |
| 4105 | + @Cached("op") @SuppressWarnings("unused") int cachedOp, |
| 4106 | + @Cached("createCallNode(op)") LookupAndCallUnaryNode callNode, |
| 4107 | + @Cached ToNewRefNode toSulongNode, |
| 4108 | + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, |
| 4109 | + @Cached GetNativeNullNode getNativeNullNode) { |
| 4110 | + // still try to avoid expensive materialization of primitives |
| 4111 | + Object result; |
| 4112 | + try { |
| 4113 | + Object leftValue; |
| 4114 | + if (left instanceof PrimitiveNativeWrapper) { |
| 4115 | + leftValue = PyNumberBinOp.extract((PrimitiveNativeWrapper) left); |
| 4116 | + } else { |
| 4117 | + leftValue = leftToJava.execute(left); |
| 4118 | + } |
| 4119 | + result = callNode.executeObject(frame, leftValue); |
| 4120 | + } catch (PException e) { |
| 4121 | + transformExceptionToNativeNode.execute(e); |
| 4122 | + result = getNativeNullNode.execute(); |
| 4123 | + } |
| 4124 | + return toSulongNode.execute(result); |
| 4125 | + } |
| 4126 | + |
| 4127 | + /** |
| 4128 | + * This needs to stay in sync with {@code abstract.c: enum e_unaryop}. |
| 4129 | + */ |
| 4130 | + static LookupAndCallUnaryNode createCallNode(int op) { |
| 4131 | + UnaryArithmetic unaryArithmetic; |
| 4132 | + switch (op) { |
| 4133 | + case 0: |
| 4134 | + unaryArithmetic = UnaryArithmetic.Pos; |
| 4135 | + break; |
| 4136 | + case 1: |
| 4137 | + unaryArithmetic = UnaryArithmetic.Neg; |
| 4138 | + break; |
| 4139 | + case 2: |
| 4140 | + unaryArithmetic = UnaryArithmetic.Invert; |
| 4141 | + break; |
| 4142 | + default: |
| 4143 | + throw CompilerDirectives.shouldNotReachHere("invalid unary operator"); |
| 4144 | + } |
| 4145 | + return unaryArithmetic.create(); |
| 4146 | + } |
| 4147 | + } |
| 4148 | + |
| 4149 | + // directly called without landing function |
4080 | 4150 | @Builtin(name = "PyNumber_BinOp", minNumOfPositionalArgs = 3)
|
4081 | 4151 | @GenerateNodeFactory
|
4082 | 4152 | abstract static class PyNumberBinOp extends PythonTernaryBuiltinNode {
|
@@ -4186,6 +4256,7 @@ private static BinaryArithmetic getBinaryArithmetic(int op) {
|
4186 | 4256 |
|
4187 | 4257 | }
|
4188 | 4258 |
|
| 4259 | + // directly called without landing function |
4189 | 4260 | @Builtin(name = "PyNumber_InPlaceBinOp", minNumOfPositionalArgs = 3)
|
4190 | 4261 | @GenerateNodeFactory
|
4191 | 4262 | abstract static class PyNumberInPlaceBinOp extends PythonTernaryBuiltinNode {
|
|
0 commit comments