Ronny Pfannschmidt avatar Ronny Pfannschmidt committed 551ae4b

store and restore the threadstate on exceptions like pypy/stackless do

Comments (0)

Files changed (2)

 		PyThreadState* tstate = PyThreadState_GET();
 		current->recursion_depth = tstate->recursion_depth;
 		current->top_frame = tstate->frame;
+		current->exc_type = tstate->exc_type;
+		current->exc_value = tstate->exc_value;
+		current->exc_traceback = tstate->exc_traceback;
+
 	}
 	err = _PyGreenlet_slp_switch();
 	if (err < 0) {   /* error */
 		tstate->recursion_depth = target->recursion_depth;
 		tstate->frame = target->top_frame;
 		target->top_frame = NULL;
+		tstate->exc_type = target->exc_type;
+		target->exc_type = NULL;
+		tstate->exc_value = target->exc_value;
+		target->exc_value = NULL;
+		tstate->exc_traceback = target->exc_traceback;
+		target->exc_traceback = NULL;
+
 		ts_current = target;
 		Py_INCREF(target);
 		Py_DECREF(origin);
 		ts_target->stack_prev = ts_current;
 	}
 	ts_target->top_frame = NULL;
+	ts_target->exc_type = NULL;
+	ts_target->exc_value = NULL;
+	ts_target->exc_traceback = NULL;
 	ts_target->recursion_depth = PyThreadState_GET()->recursion_depth;
 	err = _PyGreenlet_switchstack();
 	/* returns twice!
 	   - stack_prev is not visited: holds previous stack pointer, but it's not referenced */
 	Py_VISIT((PyObject*)self->parent);
 	Py_VISIT(self->run_info);
+	Py_VISIT(self->exc_type);
+	Py_VISIT(self->exc_value);
+	Py_VISIT(self->exc_traceback);
 	/* XXX: hack: visit all greenlet's frames
 	   Even though we don't reference frames beyond the top one, we need
 	   to visit them all, otherwise those frames will mark this greenlet
 	Py_TRASHCAN_SAFE_BEGIN(self);
 #endif /* GREENLET_USE_GC */
 	Py_CLEAR(self->parent);
+	Py_CLEAR(self->exc_value);
+	Py_CLEAR(self->exc_type);
+	Py_CLEAR(self->exc_traceback);
 	if (PyGreenlet_ACTIVE(self)) {
 		/* Hacks hacks hacks copied from instance_dealloc() */
 		/* Temporarily resurrect the greenlet. */
 	PyObject* weakreflist;
 	PyObject* stub_refs[3]; /* objects held on stack in the stub */
 	PyObject* switch_refs[2]; /* objects held on stack in switch or throw */
+	PyObject* exc_type;
+	PyObject* exc_value;
+	PyObject* exc_traceback;
+
 } PyGreenlet;
 
 #define PyGreenlet_Check(op)      PyObject_TypeCheck(op, &PyGreenlet_Type)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.