Skip to content

Commit 61dea6f

Browse files
committed
[GR-65832] Move native exception state fully to native thread state
PullRequest: graalpython/3835
2 parents 117d28b + f63c58e commit 61dea6f

File tree

16 files changed

+164
-520
lines changed

16 files changed

+164
-520
lines changed

graalpython/com.oracle.graal.python.cext/include/internal/pycore_pyerrors.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
1+
/* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2022 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -25,8 +25,6 @@ extern void _PyErr_FiniTypes(PyInterpreterState *);
2525
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
2626
{
2727
assert(tstate != NULL);
28-
// GraalPy change
29-
assert(tstate->current_exception == Graal_PyTruffleErr_Occurred(tstate));
3028
if (tstate->current_exception == NULL) {
3129
return NULL;
3230
}

graalpython/com.oracle.graal.python.cext/src/errors.c

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
4040
void
4141
_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc)
4242
{
43-
// GraalPy change
44-
// PyObject *old_exc = tstate->current_exception;
43+
PyObject *old_exc = tstate->current_exception;
4544
tstate->current_exception = exc;
46-
// Py_XDECREF(old_exc);
45+
Py_XDECREF(old_exc);
4746
}
4847

4948
static PyObject*
@@ -80,13 +79,13 @@ _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
8079
assert(value == NULL);
8180
assert(traceback == NULL);
8281
_PyErr_SetRaisedException(tstate, NULL);
83-
// return;
82+
return;
8483
}
85-
#if 0 // GraalPy change
8684
assert(PyExceptionClass_Check(type));
8785
if (value != NULL && type == (PyObject *)Py_TYPE(value)) {
8886
/* Already normalized */
89-
assert(((PyBaseExceptionObject *)value)->traceback != Py_None);
87+
// GraalPy change
88+
// assert(((PyBaseExceptionObject *)value)->traceback != Py_None);
9089
}
9190
else {
9291
PyObject *exc = _PyErr_CreateException(type, value);
@@ -112,24 +111,20 @@ _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
112111
return;
113112
}
114113
}
115-
PyObject *old_traceback = ((PyBaseExceptionObject *)value)->traceback;
116-
((PyBaseExceptionObject *)value)->traceback = traceback;
117-
Py_XDECREF(old_traceback);
114+
// GraalPy change: upcall for setting the traceback
115+
GraalPyTruffleErr_SetTraceback(value, traceback);
116+
// GraalPy change: the traceback is now owned by the managed side
117+
Py_XDECREF(traceback);
118118
_PyErr_SetRaisedException(tstate, value);
119119
Py_DECREF(type);
120-
#else // GraalPy change: different implementation
121-
PyErr_Restore(type, value, traceback);
122-
#endif // GraalPy change
123120
}
124121

125-
#if 0 // GraalPy change
126122
void
127123
PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
128124
{
129125
PyThreadState *tstate = _PyThreadState_GET();
130126
_PyErr_Restore(tstate, type, value, traceback);
131127
}
132-
#endif // GraalPy change
133128

134129
void
135130
PyErr_SetRaisedException(PyObject *exc)
@@ -138,15 +133,7 @@ PyErr_SetRaisedException(PyObject *exc)
138133
_PyErr_SetRaisedException(tstate, exc);
139134
}
140135

141-
142136
#if 0 // GraalPy change
143-
void
144-
PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
145-
{
146-
PyThreadState *tstate = _PyThreadState_GET();
147-
_PyErr_Restore(tstate, type, value, traceback);
148-
}
149-
150137
_PyErr_StackItem *
151138
_PyErr_GetTopmostException(PyThreadState *tstate)
152139
{
@@ -160,7 +147,6 @@ _PyErr_GetTopmostException(PyThreadState *tstate)
160147
}
161148
return exc_info;
162149
}
163-
#endif // GraalPy change
164150

165151
static PyObject *
166152
get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObject *value)
@@ -183,6 +169,7 @@ get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObj
183169
}
184170
return note;
185171
}
172+
#endif // GraalPy change
186173

187174
void
188175
_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
@@ -537,7 +524,6 @@ void
537524
_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
538525
PyObject **p_traceback)
539526
{
540-
#if 0 // GraalPy change
541527
PyObject *exc = _PyErr_GetRaisedException(tstate);
542528
*p_value = exc;
543529
if (exc == NULL) {
@@ -546,18 +532,9 @@ _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
546532
}
547533
else {
548534
*p_type = Py_NewRef(Py_TYPE(exc));
549-
*p_traceback = Py_XNewRef(((PyBaseExceptionObject *)exc)->traceback);
535+
// GraalPy change: upcall to get the traceback
536+
*p_traceback = PyException_GetTraceback(*p_value);
550537
}
551-
#else // GraalPy change: different implementation
552-
if (_PyErr_Occurred(tstate)) {
553-
// avoid the upcall if there is no current exception
554-
GraalPyTruffleErr_Fetch(p_type, p_value, p_traceback);
555-
} else {
556-
*p_type = NULL;
557-
*p_value = NULL;
558-
*p_traceback = NULL;
559-
}
560-
#endif // GraalPy change
561538
}
562539

563540

@@ -690,6 +667,7 @@ _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
690667
exc_value ? exc_value : Py_None,
691668
exc_traceback ? exc_traceback : Py_None);
692669
}
670+
#endif // GraalPy change
693671

694672

695673
/* Like PyErr_Restore(), but if an exception is already set,
@@ -751,6 +729,7 @@ _PyErr_ChainExceptions1(PyObject *exc)
751729
}
752730
}
753731

732+
#if 0 // GraalPy change
754733
/* Set the currently set exception's context to the given exception.
755734
756735
If the provided exc_info is NULL, then the current Python thread state's

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_traceback.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -70,6 +70,7 @@ def fake_frame():
7070
Tester.test(frame)
7171
except RuntimeError as e:
7272
assert e.__traceback__
73+
assert e.__traceback__.tb_frame is sys._getframe(0)
7374
assert e.__traceback__.tb_next
7475
assert e.__traceback__.tb_next.tb_frame is frame
7576
assert e.__traceback__.tb_next.tb_next is None

0 commit comments

Comments
 (0)