|
45 | 45 | import com.oracle.graal.python.builtins.PythonBuiltinClassType;
|
46 | 46 | import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
|
47 | 47 | import com.oracle.graal.python.builtins.objects.PNone;
|
| 48 | +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; |
48 | 49 | import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
|
49 | 50 | import com.oracle.graal.python.builtins.objects.tuple.PTuple;
|
50 | 51 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
|
| 52 | +import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode; |
51 | 53 | import com.oracle.graal.python.nodes.ErrorMessages;
|
52 | 54 | import com.oracle.graal.python.nodes.PGuards;
|
53 | 55 | import com.oracle.graal.python.nodes.PRaiseNode;
|
|
62 | 64 | import com.oracle.truffle.api.dsl.Specialization;
|
63 | 65 | import com.oracle.truffle.api.frame.VirtualFrame;
|
64 | 66 | import com.oracle.truffle.api.nodes.Node;
|
65 |
| -import com.oracle.truffle.api.profiles.InlinedBranchProfile; |
| 67 | +import com.oracle.truffle.api.profiles.InlinedConditionProfile; |
66 | 68 |
|
67 | 69 | /**
|
68 | 70 | * Creates an exception out of type and value, similarly to CPython's
|
69 | 71 | * {@code PyErr_NormalizeException}. Returns the normalized exception.
|
70 | 72 | */
|
71 | 73 | @ImportStatic(PGuards.class)
|
72 | 74 | public abstract class PrepareExceptionNode extends Node {
|
73 |
| - public abstract PBaseException execute(VirtualFrame frame, Object type, Object value); |
| 75 | + public abstract Object execute(VirtualFrame frame, Object type, Object value); |
74 | 76 |
|
75 | 77 | @Specialization
|
76 |
| - static PBaseException doException(PBaseException exc, @SuppressWarnings("unused") PNone value) { |
| 78 | + static Object doException(PBaseException exc, @SuppressWarnings("unused") PNone value) { |
77 | 79 | return exc;
|
78 | 80 | }
|
79 | 81 |
|
80 |
| - @Specialization(guards = "!isPNone(value)") |
81 |
| - static PBaseException doException(@SuppressWarnings("unused") PBaseException exc, @SuppressWarnings("unused") Object value, |
| 82 | + @Specialization(guards = "check.execute(inliningTarget, exc)", limit = "1") |
| 83 | + static Object doException(PythonAbstractNativeObject exc, @SuppressWarnings("unused") PNone value, |
| 84 | + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, |
| 85 | + @SuppressWarnings("unused") @Shared @Cached PyExceptionInstanceCheckNode check) { |
| 86 | + return exc; |
| 87 | + } |
| 88 | + |
| 89 | + @Specialization(guards = {"check.execute(inliningTarget, exc)", "!isPNone(value)"}, limit = "1") |
| 90 | + static Object doException(@SuppressWarnings("unused") PBaseException exc, @SuppressWarnings("unused") Object value, |
| 91 | + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, |
| 92 | + @SuppressWarnings("unused") @Shared @Cached PyExceptionInstanceCheckNode check, |
82 | 93 | @Shared @Cached PRaiseNode raiseNode) {
|
83 | 94 | throw raiseNode.raise(TypeError, ErrorMessages.INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE);
|
84 | 95 | }
|
85 | 96 |
|
86 |
| - @Specialization(guards = "isTypeNode.execute(type)", limit = "1") |
87 |
| - static PBaseException doException(VirtualFrame frame, Object type, PBaseException value, |
| 97 | + @Specialization(guards = {"isTypeNode.execute(type)", "!isPNone(value)", "!isPTuple(value)"}, limit = "1") |
| 98 | + static Object doExceptionOrCreate(VirtualFrame frame, Object type, Object value, |
88 | 99 | @Bind("this") Node inliningTarget,
|
89 | 100 | @SuppressWarnings("unused") @Shared("isType") @Cached IsTypeNode isTypeNode,
|
| 101 | + @Shared @Cached PyExceptionInstanceCheckNode check, |
90 | 102 | @Cached BuiltinFunctions.IsInstanceNode isInstanceNode,
|
91 |
| - @Cached InlinedBranchProfile isNotInstanceProfile, |
| 103 | + @Cached InlinedConditionProfile isInstanceProfile, |
92 | 104 | @Shared @Cached IsSubtypeNode isSubtypeNode,
|
93 | 105 | @Shared @Cached PRaiseNode raiseNode,
|
94 | 106 | @Shared("callCtor") @Cached CallNode callConstructor) {
|
95 |
| - if (isInstanceNode.executeWith(frame, value, type)) { |
96 |
| - checkExceptionClass(type, isSubtypeNode, raiseNode); |
| 107 | + checkExceptionClass(type, isSubtypeNode, raiseNode); |
| 108 | + if (isInstanceProfile.profile(inliningTarget, isInstanceNode.executeWith(frame, value, type))) { |
97 | 109 | return value;
|
98 | 110 | } else {
|
99 |
| - isNotInstanceProfile.enter(inliningTarget); |
100 |
| - return doCreateObject(frame, type, value, isTypeNode, isSubtypeNode, raiseNode, callConstructor); |
| 111 | + Object instance = callConstructor.execute(frame, type, value); |
| 112 | + if (check.execute(inliningTarget, instance)) { |
| 113 | + return instance; |
| 114 | + } else { |
| 115 | + return handleInstanceNotAnException(type, instance); |
| 116 | + } |
101 | 117 | }
|
102 | 118 | }
|
103 | 119 |
|
104 | 120 | @Specialization(guards = "isTypeNode.execute(type)", limit = "1")
|
105 |
| - static PBaseException doCreate(VirtualFrame frame, Object type, @SuppressWarnings("unused") PNone value, |
| 121 | + static Object doCreate(VirtualFrame frame, Object type, @SuppressWarnings("unused") PNone value, |
| 122 | + @Bind("this") Node inliningTarget, |
106 | 123 | @SuppressWarnings("unused") @Shared("isType") @Cached IsTypeNode isTypeNode,
|
| 124 | + @Shared @Cached PyExceptionInstanceCheckNode check, |
107 | 125 | @Shared @Cached IsSubtypeNode isSubtypeNode,
|
108 | 126 | @Shared @Cached PRaiseNode raiseNode,
|
109 | 127 | @Shared("callCtor") @Cached CallNode callConstructor) {
|
110 | 128 | checkExceptionClass(type, isSubtypeNode, raiseNode);
|
111 | 129 | Object instance = callConstructor.execute(frame, type);
|
112 |
| - if (instance instanceof PBaseException) { |
113 |
| - return (PBaseException) instance; |
| 130 | + if (check.execute(inliningTarget, instance)) { |
| 131 | + return instance; |
114 | 132 | } else {
|
115 | 133 | return handleInstanceNotAnException(type, instance);
|
116 | 134 | }
|
117 | 135 | }
|
118 | 136 |
|
119 | 137 | @Specialization(guards = "isTypeNode.execute(type)", limit = "1")
|
120 |
| - static PBaseException doCreateTuple(VirtualFrame frame, Object type, PTuple value, |
| 138 | + static Object doCreateTuple(VirtualFrame frame, Object type, PTuple value, |
121 | 139 | @Bind("this") Node inliningTarget,
|
122 | 140 | @SuppressWarnings("unused") @Shared("isType") @Cached IsTypeNode isTypeNode,
|
| 141 | + @Shared @Cached PyExceptionInstanceCheckNode check, |
123 | 142 | @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode,
|
124 | 143 | @Shared @Cached IsSubtypeNode isSubtypeNode,
|
125 | 144 | @Shared @Cached PRaiseNode raiseNode,
|
126 | 145 | @Shared("callCtor") @Cached CallNode callConstructor) {
|
127 | 146 | checkExceptionClass(type, isSubtypeNode, raiseNode);
|
128 | 147 | Object[] args = getObjectArrayNode.execute(inliningTarget, value);
|
129 | 148 | Object instance = callConstructor.execute(frame, type, args);
|
130 |
| - if (instance instanceof PBaseException) { |
131 |
| - return (PBaseException) instance; |
132 |
| - } else { |
133 |
| - return handleInstanceNotAnException(type, instance); |
134 |
| - } |
135 |
| - } |
136 |
| - |
137 |
| - @Specialization(guards = {"isTypeNode.execute(type)", "!isPNone(value)", "!isPTuple(value)", "!isPBaseException(value)"}, limit = "1") |
138 |
| - static PBaseException doCreateObject(VirtualFrame frame, Object type, Object value, |
139 |
| - @SuppressWarnings("unused") @Shared("isType") @Cached IsTypeNode isTypeNode, |
140 |
| - @Shared @Cached IsSubtypeNode isSubtypeNode, |
141 |
| - @Shared @Cached PRaiseNode raiseNode, |
142 |
| - @Shared("callCtor") @Cached CallNode callConstructor) { |
143 |
| - checkExceptionClass(type, isSubtypeNode, raiseNode); |
144 |
| - Object instance = callConstructor.execute(frame, type, value); |
145 |
| - if (instance instanceof PBaseException) { |
146 |
| - return (PBaseException) instance; |
| 149 | + if (check.execute(inliningTarget, instance)) { |
| 150 | + return instance; |
147 | 151 | } else {
|
148 | 152 | return handleInstanceNotAnException(type, instance);
|
149 | 153 | }
|
150 | 154 | }
|
151 | 155 |
|
152 | 156 | @Fallback
|
153 |
| - static PBaseException doError(Object type, @SuppressWarnings("unused") Object value, |
| 157 | + static Object doError(Object type, @SuppressWarnings("unused") Object value, |
154 | 158 | @Shared @Cached PRaiseNode raiseNode) {
|
155 | 159 | throw raiseNode.raise(TypeError, ErrorMessages.EXCEPTIONS_MUST_BE_CLASSES_OR_INSTANCES_DERIVING_FROM_BASE_EX, type);
|
156 | 160 | }
|
|
0 commit comments