Skip to content

Commit 284550a

Browse files
committed
Use TransformExceptionToNativeNode to set current exception
1 parent 1488ac7 commit 284550a

File tree

5 files changed

+73
-48
lines changed

5 files changed

+73
-48
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode;
8383
import com.oracle.graal.python.builtins.modules.cext.PythonCextFileBuiltins.PyFile_WriteObject;
8484
import com.oracle.graal.python.builtins.objects.PNone;
85+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
8586
import com.oracle.graal.python.builtins.objects.cext.capi.PThreadState;
8687
import com.oracle.graal.python.builtins.objects.cext.common.NativePointer;
8788
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
@@ -141,21 +142,16 @@ abstract static class PyErr_Restore extends CApiTernaryBuiltinNode {
141142

142143
@Specialization
143144
Object restore(Object typ, Object val, Object tb,
144-
@Cached PrepareExceptionNode prepareExceptionNode) {
145+
@Cached PrepareExceptionNode prepareExceptionNode,
146+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
145147
PythonLanguage language = getLanguage();
146148
PythonContext.PythonThreadState threadState = getContext().getThreadState(language);
147149
if (typ == PNone.NO_VALUE && val == PNone.NO_VALUE) {
148150
threadState.clearCurrentException();
149151
} else {
150-
Object exception;
151-
try {
152-
exception = prepareExceptionNode.execute(null, typ, val);
153-
} catch (PException e) {
154-
threadState.setCurrentException(e);
155-
return PNone.NO_VALUE;
156-
}
152+
Object exception = prepareExceptionNode.execute(null, typ, val);
157153
PException e = PException.fromExceptionInfo(exception, PythonOptions.isPExceptionWithJavaStacktrace(language));
158-
threadState.setCurrentException(e, tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null);
154+
transformExceptionToNativeNode.execute(this, e, tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null);
159155
}
160156
return PNone.NO_VALUE;
161157
}
@@ -169,16 +165,12 @@ static Object run(Object typ, Object val, Object tb,
169165
@Cached GetThreadStateNode getThreadStateNode,
170166
@Cached PrepareExceptionNode prepareExceptionNode,
171167
@Cached ExceptionNodes.SetTracebackNode setTracebackNode,
172-
@Cached ExceptionNodes.SetContextNode setContextNode) {
168+
@Cached ExceptionNodes.SetContextNode setContextNode,
169+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
173170
if (typ != PNone.NO_VALUE) {
174171
PythonContext.PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, PythonContext.get(inliningTarget));
175172
Object exception;
176-
try {
177-
exception = prepareExceptionNode.execute(null, typ, val);
178-
} catch (PException e) {
179-
threadState.setCurrentException(e);
180-
return PNone.NO_VALUE;
181-
}
173+
exception = prepareExceptionNode.execute(null, typ, val);
182174
if (threadState.getCurrentException() != null) {
183175
if (tb != PNone.NO_VALUE) {
184176
setTracebackNode.execute(inliningTarget, exception, tb);
@@ -187,7 +179,7 @@ static Object run(Object typ, Object val, Object tb,
187179
setContextNode.execute(inliningTarget, currentException, exception);
188180
} else {
189181
PException e = PException.fromExceptionInfo(exception, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(inliningTarget)));
190-
threadState.setCurrentException(e, tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null);
182+
transformExceptionToNativeNode.execute(inliningTarget, e, tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null);
191183
}
192184
}
193185
return PNone.NO_VALUE;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
import com.oracle.graal.python.builtins.objects.module.PythonModule;
124124
import com.oracle.graal.python.builtins.objects.object.PythonObject;
125125
import com.oracle.graal.python.builtins.objects.str.PString;
126+
import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback;
126127
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
127128
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
128129
import com.oracle.graal.python.builtins.objects.type.PythonClass;
@@ -999,24 +1000,56 @@ static long doSingleContext(Object cls, CFields nativeMember, HiddenAttr managed
9991000
@GenerateUncached
10001001
public abstract static class TransformExceptionToNativeNode extends Node {
10011002

1002-
public abstract void execute(Frame frame, Node inliningTarget, PException e);
1003+
public abstract void execute(Frame frame, Node inliningTarget, PException e, LazyTraceback tb);
10031004

10041005
public final void execute(Node inliningTarget, PException e) {
1005-
execute(null, inliningTarget, e);
1006+
execute(null, inliningTarget, e, null);
1007+
}
1008+
1009+
public final void execute(Frame frame, Node inliningTarget, PException e) {
1010+
execute(frame, inliningTarget, e, null);
1011+
}
1012+
1013+
public final void execute(Node inliningTarget, PException e, LazyTraceback tb) {
1014+
execute(null, inliningTarget, e, tb);
10061015
}
10071016

10081017
public final void executeCached(PException e) {
1009-
execute(null, this, e);
1018+
execute(null, this, e, null);
10101019
}
10111020

10121021
@Specialization
1013-
static void setCurrentException(Frame frame, Node inliningTarget, PException e,
1022+
static void setCurrentException(Frame frame, Node inliningTarget, PException e, LazyTraceback tb,
10141023
@Cached GetCurrentFrameRef getCurrentFrameRef,
1015-
@Cached GetThreadStateNode getThreadStateNode) {
1024+
@Cached GetThreadStateNode getThreadStateNode,
1025+
@Cached GetClassNode getClassNode,
1026+
@Cached(inline = false) PythonToNativeNode pythonToNativeNode,
1027+
@Cached(inline = false) CStructAccess.WritePointerNode writePointerNode) {
10161028
// TODO connect f_back
10171029
getCurrentFrameRef.execute(frame, inliningTarget).markAsEscaped();
10181030
PythonContext.PythonThreadState threadState = getThreadStateNode.execute(inliningTarget);
1019-
threadState.setCurrentException(e);
1031+
if (tb != null) {
1032+
threadState.setCurrentException(e, tb);
1033+
} else {
1034+
threadState.setCurrentException(e);
1035+
}
1036+
/*
1037+
* Mirror the global exception state to native for faster access. For now, we only write
1038+
* 'PyThreadState.curexc_type' (which is the only one required for 'PyErr_Occurred').
1039+
* Since that won't escape the exception object to the program, we can use
1040+
* 'getUnreifiedException'. As soon as we provide the exception object and the traceback
1041+
* as well, we need to use 'getEscapedException'.
1042+
*/
1043+
PThreadState nativeWrapper = threadState.getNativeWrapper();
1044+
if (nativeWrapper != null) {
1045+
Object exceptionType = getClassNode.execute(inliningTarget, e.getUnreifiedException());
1046+
Object nativeThreadState = PThreadState.getOrCreateNativeThreadState(threadState);
1047+
/*
1048+
* Write a borrowed ref to the native mirror because we need to keep that in sync
1049+
* anyway.
1050+
*/
1051+
writePointerNode.write(nativeThreadState, CFields.PyThreadState__curexc_type, pythonToNativeNode.execute(exceptionType));
1052+
}
10201053
}
10211054
}
10221055

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -835,19 +835,19 @@ public static MethDirectRoot create(PythonLanguage lang, TruffleString name, PEx
835835
@GenerateCached(false)
836836
@GenerateInline
837837
public abstract static class ExternalFunctionInvokeNode extends PNodeWithContext {
838-
abstract Object execute(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable, Object[] cArguments);
838+
abstract Object execute(VirtualFrame frame, Node inliningTarget, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable, Object[] cArguments);
839839

840-
public final Object call(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable,
841-
Object... cArguments) {
842-
return execute(frame, inliningTarget, ctx, threadState, timing, name, callable, cArguments);
840+
public final Object call(VirtualFrame frame, Node inliningTarget, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable, Object... cArguments) {
841+
return execute(frame, inliningTarget, threadState, timing, name, callable, cArguments);
843842
}
844843

845844
@Specialization
846-
static Object invoke(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable, Object[] cArguments,
847-
@Cached(inline = false) GilNode gilNode,
845+
static Object invoke(VirtualFrame frame, Node inliningTarget, PythonThreadState threadState, CApiTiming timing, TruffleString name, Object callable, Object[] cArguments,
848846
@Cached(value = "createFor(this)", uncached = "getUncached()") IndirectCallData indirectCallData,
849847
@CachedLibrary(limit = "2") InteropLibrary lib) {
850848

849+
assert threadState.getCurrentException() == null;
850+
851851
// If any code requested the caught exception (i.e. used 'sys.exc_info()'), we store
852852
// it to the context since we cannot propagate it through the native frames.
853853
Object state = IndirectCallContext.enter(frame, threadState, indirectCallData);
@@ -921,7 +921,7 @@ private static Object invoke(VirtualFrame frame, PythonContext ctx, CApiTiming t
921921
CheckFunctionResultNode checkResultNode, CExtToJavaNode convertReturnValue, PForeignToPTypeNode fromForeign, GetThreadStateNode getThreadStateNode,
922922
ExternalFunctionInvokeNode invokeNode) {
923923
PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, ctx);
924-
Object result = invokeNode.execute(frame, inliningTarget, ctx, threadState, timing, name, callable, cArguments);
924+
Object result = invokeNode.execute(frame, inliningTarget, threadState, timing, name, callable, cArguments);
925925
result = checkResultNode.execute(threadState, name, result);
926926
if (convertReturnValue != null) {
927927
result = convertReturnValue.execute(result);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyCFunctionWrapper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ Object execute(Object[] arguments,
316316
throw checkThrowableBeforeNative(t, toString(), "");
317317
}
318318
} catch (PException e) {
319-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
319+
transformExceptionToNativeNode.execute(inliningTarget, e);
320320
return PythonContext.get(gil).getNativeNull();
321321
} finally {
322322
CApiTiming.exit(timing);
@@ -383,7 +383,7 @@ Object execute(Object[] arguments,
383383
throw checkThrowableBeforeNative(t, toString(), "");
384384
}
385385
} catch (PException e) {
386-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
386+
transformExceptionToNativeNode.execute(inliningTarget, e);
387387
return PythonContext.get(gil).getNativeNull();
388388
} finally {
389389
CApiTiming.exit(timing);
@@ -456,7 +456,7 @@ Object execute(Object[] arguments,
456456
throw checkThrowableBeforeNative(t, toString(), "");
457457
}
458458
} catch (PException e) {
459-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
459+
transformExceptionToNativeNode.execute(inliningTarget, e);
460460
return PythonContext.get(gil).getNativeNull();
461461
} finally {
462462
CApiTiming.exit(timing);
@@ -526,7 +526,7 @@ Object execute(Object[] arguments,
526526
throw checkThrowableBeforeNative(t, toString(), "");
527527
}
528528
} catch (PException e) {
529-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
529+
transformExceptionToNativeNode.execute(inliningTarget, e);
530530
return PythonContext.get(gil).getNativeNull();
531531
} finally {
532532
CApiTiming.exit(timing);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Object execute(Object[] arguments,
157157
throw checkThrowableBeforeNative(t, "GetAttrWrapper", getDelegate());
158158
}
159159
} catch (PException e) {
160-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
160+
transformExceptionToNativeNode.execute(inliningTarget, e);
161161
return PythonContext.get(gil).getNativeNull();
162162
} finally {
163163
CApiTiming.exit(timing);
@@ -210,7 +210,7 @@ Object execute(Object[] arguments,
210210
throw checkThrowableBeforeNative(t, "GetAttrWrapper", getDelegate());
211211
}
212212
} catch (PException e) {
213-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
213+
transformExceptionToNativeNode.execute(inliningTarget, e);
214214
return PythonContext.get(gil).getNativeNull();
215215
} finally {
216216
CApiTiming.exit(timing);
@@ -252,7 +252,7 @@ Object execute(Object[] arguments,
252252
throw checkThrowableBeforeNative(t, "BinaryFuncWrapper", getDelegate());
253253
}
254254
} catch (PException e) {
255-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
255+
transformExceptionToNativeNode.execute(inliningTarget, e);
256256
return PythonContext.get(gil).getNativeNull();
257257
} finally {
258258
CApiTiming.exit(timing);
@@ -298,7 +298,7 @@ Object execute(Object[] arguments,
298298
throw checkThrowableBeforeNative(t, "UnaryFuncWrapper", getDelegate());
299299
}
300300
} catch (PException e) {
301-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
301+
transformExceptionToNativeNode.execute(inliningTarget, e);
302302
return PythonContext.get(gil).getNativeNull();
303303
} finally {
304304
CApiTiming.exit(timing);
@@ -339,7 +339,7 @@ Object execute(Object[] arguments,
339339
throw checkThrowableBeforeNative(t, "InquiryWrapper", getDelegate());
340340
}
341341
} catch (PException e) {
342-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
342+
transformExceptionToNativeNode.execute(inliningTarget, e);
343343
return -1;
344344
} finally {
345345
CApiTiming.exit(timing);
@@ -382,7 +382,7 @@ int execute(Object[] arguments,
382382
throw checkThrowableBeforeNative(t, "ObjobjargWrapper", getDelegate());
383383
}
384384
} catch (PException e) {
385-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
385+
transformExceptionToNativeNode.execute(inliningTarget, e);
386386
return -1;
387387
} finally {
388388
CApiTiming.exit(timing);
@@ -433,7 +433,7 @@ static int init(InitWrapper self, Object[] arguments,
433433
throw checkThrowableBeforeNative(t, "InitWrapper", self.getDelegate());
434434
}
435435
} catch (PException e) {
436-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
436+
transformExceptionToNativeNode.execute(inliningTarget, e);
437437
return -1;
438438
} finally {
439439
CApiTiming.exit(self.timing);
@@ -492,7 +492,7 @@ static Object call(TernaryFunctionWrapper self, Object[] arguments,
492492
throw checkThrowableBeforeNative(t, "TernaryFunctionWrapper", self.getDelegate());
493493
}
494494
} catch (PException e) {
495-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
495+
transformExceptionToNativeNode.execute(inliningTarget, e);
496496
return PythonContext.get(gil).getNativeNull();
497497
} finally {
498498
CApiTiming.exit(self.timing);
@@ -547,7 +547,7 @@ Object execute(Object[] arguments,
547547
throw checkThrowableBeforeNative(t, "RichcmpFunctionWrapper", getDelegate());
548548
}
549549
} catch (PException e) {
550-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
550+
transformExceptionToNativeNode.execute(inliningTarget, e);
551551
return PythonContext.get(gil).getNativeNull();
552552
} finally {
553553
CApiTiming.exit(timing);
@@ -591,7 +591,7 @@ Object execute(Object[] arguments,
591591
throw checkThrowableBeforeNative(t, "SsizeargfuncWrapper", getDelegate());
592592
}
593593
} catch (PException e) {
594-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
594+
transformExceptionToNativeNode.execute(inliningTarget, e);
595595
return PythonContext.get(toJavaNode).getNativeNull();
596596
} finally {
597597
CApiTiming.exit(timing);
@@ -634,7 +634,7 @@ int execute(Object[] arguments,
634634
throw checkThrowableBeforeNative(t, "SsizeobjargfuncWrapper", getDelegate());
635635
}
636636
} catch (PException e) {
637-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
637+
transformExceptionToNativeNode.execute(inliningTarget, e);
638638
return -1;
639639
} finally {
640640
CApiTiming.exit(timing);
@@ -680,7 +680,7 @@ long execute(Object[] arguments,
680680
throw checkThrowableBeforeNative(t, "LenfuncWrapper", getDelegate());
681681
}
682682
} catch (PException e) {
683-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
683+
transformExceptionToNativeNode.execute(inliningTarget, e);
684684
return -1;
685685
} finally {
686686
CApiTiming.exit(timing);
@@ -730,7 +730,7 @@ long execute(Object[] arguments,
730730
throw checkThrowableBeforeNative(t, "HashfuncWrapper", getDelegate());
731731
}
732732
} catch (PException e) {
733-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
733+
transformExceptionToNativeNode.execute(inliningTarget, e);
734734
return -1;
735735
} finally {
736736
CApiTiming.exit(timing);
@@ -777,7 +777,7 @@ static Object call(DescrGetFunctionWrapper self, Object[] arguments,
777777
throw checkThrowableBeforeNative(t, "DescrGetFunctionWrapper", self.getDelegate());
778778
}
779779
} catch (PException e) {
780-
transformExceptionToNativeNode.execute(null, inliningTarget, e);
780+
transformExceptionToNativeNode.execute(inliningTarget, e);
781781
return PythonContext.get(gil).getNativeNull();
782782
} finally {
783783
CApiTiming.exit(self.timing);

0 commit comments

Comments
 (0)