On Sat, May 30, 2009 at 12:10:55AM -0700, alan yung wrote:
> But in the freeze() function, I also cleared app level frames like
> following...
>
>     while len(ec.framestack.items) > 1:
>         ec.framestack.pop()
>
>     stack_unwind()
>
> In that case, I thought this should stop executing the (app-level) function,
> shouldn't it?

No: as I said, stack_unwind() has no effect apart from keeping the usage
of the C stack under control, so we can ignore it for the purpose of
understanding how this code works.  It just empties ec.framestack, but
the real stack of interp-level calls is still there.  So this code just
creates a discrepancy between ec.framestack and the call stack -- and
the call stack wins, as PyPy's interpreter is implemented using the call
stack (like CPython's interpreter).

Enabling stackless in this code changes this fact but at another level.
It's like stack_unwind(): calling it has no visible effect from RPython
code; it just temporary reduces the C stack depth.  Similarly, Stackless
in PyPy is implemented by calling stack_unwind() internally as needed,
so that the C stack depth can be reduced -- but the PyPy interpreter is
still written in a recursive style.  "Reducing the C stack depth" mostly
means copying a part of the C stack away into the heap, where it can be
re-read later.


Oh I see. This is interesting.
If I do something like following (raising UnwindException in the freeze function)

from pypy.translator.stackless.code import UnwindException

def freeze(space):
    global storedExecutionContext
    
    ec = space.getexecutioncontext()
        
    storedExecutionContext.copy(ec)
        
    while len(ec.framestack.items) > 1:
        ec.framestack.pop()
            
    raise UnwindException()
freeze.unwrap_spec = [ObjSpace]


Now I guess it should stop executing the current python level functions, shouldn't it?
 


A bientot,

Armin.