On May 31, 2004, at 4:56 PM, Martin v. Löwis wrote:
Bob Ippolito wrote:
I'm not quite sure you are up to date on how Stackless 3.0 works. The assembly code is only there to facilitate "hard switching", which is only required to do tasklet switching in the face of some C extension that doesn't know about Stackless.
Yes, that was my understanding. "Some C extensions" includes Tcl and COM, right? Unless I'm mistaken, it also includes map, filter, and .encode/.decode of unicode objects (or any other C module that calls back into Python, except for tasklet mechanism of stackless itself).
You're definitely correct about Tcl and COM.. COM is however a total non-issue because Win32/x86 is very well supported by Christian ;)
I'm believe that map and filter are non-recursive, I am not sure about unicode encode/decode. I don't think it's very common to do a tasklet switch in the middle of a unicode encode or decode, though :)
In these cases, copying out the stack will break the exception chain that the Visual C++ compiler creates through the FS segment, so that an attempt to throw an exception will cause a program crash, right?
I'm also not sure how it could "break C++ exception handling" in scenarios where it wouldn't be broken anyway. I'd like to see a test of that that passes under regular Python but fails in Stackless for this.
The VC++ exception mechanism puts a linked chain of exception frames on the stack, where, at the beginning of each function, the stack pointer is stored at FS:18 (or some such), and the old value of FS:18 is stored on the stack. Then, when an exception occurs, this linked list is used to traverse the stack. If multiple stacks are used in a single thread, then this linked list gets messed up.
Without trying, I think the following call chain might cause a crash if Stackless is compiled with exception handling on:
Py-func1() -> C-func1() -> Py-func2() -> switch to new tasklet Py-func3() -> C-func2() -> throw exception()
I don't see how it could cause problems unless this is valid: Py_Func1 -> CPlusPlus_ExceptionCatcher -> Py_Func2 -> CPlusPlus_ExceptionThrower -> throws exception()
If that *is* valid, how the heck does Py_Func2 get cleaned up? I have to admit that I'm not very familiar with C++'s implementation of exceptions.