[pypy-svn] r34787 - in pypy/dist/pypy: interpreter module/_stackless

arigo at codespeak.net arigo at codespeak.net
Mon Nov 20 13:36:35 CET 2006


Author: arigo
Date: Mon Nov 20 13:36:29 2006
New Revision: 34787

Modified:
   pypy/dist/pypy/interpreter/executioncontext.py
   pypy/dist/pypy/module/_stackless/clonable.py
   pypy/dist/pypy/module/_stackless/coroutine.py
   pypy/dist/pypy/module/_stackless/interp_clonable.py
   pypy/dist/pypy/module/_stackless/interp_greenlet.py
Log:
(pedronis around, arigo)

Wack trying to make AppClonableCoroutine do the right thing...


Modified: pypy/dist/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/dist/pypy/interpreter/executioncontext.py	(original)
+++ pypy/dist/pypy/interpreter/executioncontext.py	Mon Nov 20 13:36:29 2006
@@ -38,45 +38,41 @@
         if not frame.hide():
             self.framestack.pop()
 
-    # coroutine: subcontext support
-    def subcontext_new(coobj):
-        coobj.framestack = new_framestack()
-        coobj.w_tracefunc = None
-        coobj.w_profilefunc = None
-        coobj.is_tracing = 0
-    subcontext_new = staticmethod(subcontext_new)
-
-    def subcontext_enter(self, next):
-        self.framestack = next.framestack
-        self.w_tracefunc = next.w_tracefunc
-        self.w_profilefunc = next.w_profilefunc
-        self.is_tracing = next.is_tracing
-
-    def subcontext_leave(self, current):
-        current.framestack = self.framestack
-        current.w_tracefunc = self.w_tracefunc
-        current.w_profilefunc = self.w_profilefunc
-        current.is_tracing = self.is_tracing
-
-    # coroutine: I think this is all, folks!
-
-    # well, not quite: we need an interface for pickling
-    def subcontext_getstate(coobj):
-        # we just save the framestack
-        space = coobj.space
-        items = [space.wrap(item) for item in coobj.framestack.items]
-        return space.newtuple(items)
-    subcontext_getstate = staticmethod(subcontext_getstate)
-
-    def subcontext_setstate(coobj, w_state):
-        from pypy.interpreter.pyframe import PyFrame
-        space = coobj.space
-        items = [space.interp_w(PyFrame, item)
-                 for item in space.unpackiterable(w_state)]
-        coobj.framestack.items = items
-    subcontext_setstate = staticmethod(subcontext_setstate)
 
-    # coroutine: now I really I think this is all, folks!
+    class Subcontext(object):
+        # coroutine: subcontext support
+
+        def __init__(self):
+            self.framestack = new_framestack()
+            self.w_tracefunc = None
+            self.w_profilefunc = None
+            self.is_tracing = 0
+
+        def enter(self, ec):
+            ec.framestack = self.framestack
+            ec.w_tracefunc = self.w_tracefunc
+            ec.w_profilefunc = self.w_profilefunc
+            ec.is_tracing = self.is_tracing
+
+        def leave(self, ec):
+            self.framestack = ec.framestack
+            self.w_tracefunc = ec.w_tracefunc
+            self.w_profilefunc = ec.w_profilefunc
+            self.is_tracing = ec.is_tracing
+
+        # the following interface is for pickling and unpickling
+        def getstate(self, space):
+            # we just save the framestack
+            items = [space.wrap(item) for item in self.framestack.items]
+            return space.newtuple(items)
+
+        def setstate(self, space, w_state):
+            from pypy.interpreter.pyframe import PyFrame
+            items = [space.interp_w(PyFrame, w_item)
+                     for w_item in space.unpackiterable(w_state)]
+            self.framestack.items = items
+        # coroutine: I think this is all, folks!
+
 
     def get_builtin(self):
         try:

Modified: pypy/dist/pypy/module/_stackless/clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/clonable.py	Mon Nov 20 13:36:29 2006
@@ -9,6 +9,11 @@
 
 class AppClonableCoroutine(AppCoroutine, InterpClonableMixin):
 
+    def newsubctx(self):
+        self.hello_local_pool()
+        AppCoroutine.newsubctx(self)
+        self.goodbye_local_pool()
+
     def hello(self):
         self.hello_local_pool()
         AppCoroutine.hello(self)
@@ -40,7 +45,7 @@
                                             "current coroutine"
                                             "; use fork() instead"))
         copy = AppClonableCoroutine(space, state=costate)
-        self.clone_into(copy)
+        copy.subctx = self.clone_into(copy, self.subctx)
         return space.wrap(copy)
 
     def descr__reduce__(self, space):
@@ -59,9 +64,8 @@
 
 class AppClonableCoState(AppCoState):
     def post_install(self):
-        self.current = self.main = AppClonableCoroutine(self.space,
-                                                        is_main=True,
-                                                        state=self)
+        self.current = self.main = AppClonableCoroutine(self.space, state=self)
+        self.main.subctx.framestack = None      # wack
 
 def post_install(module):
     makeStaticMethod(module, 'clonable', 'getcurrent')

Modified: pypy/dist/pypy/module/_stackless/coroutine.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/coroutine.py	(original)
+++ pypy/dist/pypy/module/_stackless/coroutine.py	Mon Nov 20 13:36:29 2006
@@ -45,26 +45,25 @@
     def call(self):
         costate = self.costate
         w_result = self.space.call_args(self.w_func, self.args)
-        #XXX: unreachable code ?
         rstack.resume_point("appthunk", costate, returns=w_result)
         costate.w_tempval = w_result
 
 
 class AppCoroutine(Coroutine): # XXX, StacklessFlags):
 
-    def __init__(self, space, is_main=False, state=None):
+    def __init__(self, space, state):
         self.space = space
-        if state is None:
-            state = self._get_state(space)
         Coroutine.__init__(self, state)
         self.flags = 0
-        self.framestack = None
-        if not is_main:
-             space.getexecutioncontext().subcontext_new(self)
+        self.newsubctx()
+
+    def newsubctx(self):
+        ec = self.space.getexecutioncontext()
+        self.subctx = ec.Subcontext()
 
     def descr_method__new__(space, w_subtype):
         co = space.allocate_instance(AppCoroutine, w_subtype)
-        AppCoroutine.__init__(co, space)
+        AppCoroutine.__init__(co, space, AppCoroutine._get_state(space))
         return space.wrap(co)
 
     def _get_state(space):
@@ -109,11 +108,11 @@
 
     def hello(self):
         ec = self.space.getexecutioncontext()
-        ec.subcontext_enter(self)
+        self.subctx.enter(ec)
 
     def goodbye(self):
         ec = self.space.getexecutioncontext()
-        ec.subcontext_leave(self)
+        self.subctx.leave(ec)
 
     def w_kill(self):
         self.kill()
@@ -160,7 +159,7 @@
             ]
         tup_state = [
             w(self.flags),
-            ec.subcontext_getstate(self),
+            self.subctx.getstate(space),
             w_thunk,
             w(self.parent),
             ]
@@ -176,7 +175,7 @@
         self.flags = space.int_w(w_flags)
         self.parent = space.interp_w(AppCoroutine, w_parent, can_be_None=True)
         ec = self.space.getexecutioncontext()
-        ec.subcontext_setstate(self, w_state)
+        self.subctx.setstate(self.space, w_state)
         self.reconstruct_framechain()
         if space.is_w(w_thunk, space.w_None):
             self.thunk = None
@@ -192,7 +191,7 @@
     def reconstruct_framechain(self):
         from pypy.interpreter.pyframe import PyFrame
         from pypy.rlib.rstack import resume_state_create
-        if self.framestack.empty():
+        if self.subctx.framestack.empty():
             self.frame = None
             return
 
@@ -206,7 +205,7 @@
         # rstack.resume_point("appthunk", costate, returns=w_result)
         appthunk_frame = resume_state_create(_bind_frame, "appthunk", costate)
         chain = appthunk_frame
-        for frame in self.framestack.items:
+        for frame in self.subctx.framestack.items:
             assert isinstance(frame, PyFrame)
             # rstack.resume_point("evalframe", self, executioncontext, returns=result)
             evalframe_frame = resume_state_create(chain, "evalframe", frame, ec)
@@ -253,8 +252,8 @@
 
 def w_descr__framestack(space, self):
     assert isinstance(self, AppCoroutine)
-    if self.framestack:
-        items = [space.wrap(item) for item in self.framestack.items]
+    if self.subctx.framestack is not None:
+        items = [space.wrap(item) for item in self.subctx.framestack.items]
         return space.newtuple(items)
     else:
         return space.newtuple([])
@@ -305,5 +304,5 @@
         self.space = space
         
     def post_install(self):
-        self.current = self.main = AppCoroutine(self.space, is_main=True,
-                                                state=self)
+        self.current = self.main = AppCoroutine(self.space, state=self)
+        self.main.subctx.framestack = None    # wack

Modified: pypy/dist/pypy/module/_stackless/interp_clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/interp_clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/interp_clonable.py	Mon Nov 20 13:36:29 2006
@@ -18,17 +18,25 @@
     def goodbye_local_pool(self):
         if we_are_translated():
             self.local_pool = gc_swap_pool(self.saved_pool)
+            self.saved_pool = None
 
-    def clone_into(self, copy):
+    def clone_into(self, copy, extradata=None):
         if not we_are_translated():
             raise NotImplementedError
-        if self.local_pool is None:   # force it now
-            self.local_pool = gc_swap_pool(gc_swap_pool(None))
         # cannot gc_clone() directly self, because it is not in its own
         # local_pool.  Moreover, it has a __del__, which cloning doesn't
         # support properly at the moment.
         copy.parent = self.parent
-        copy.frame, copy.local_pool = gc_clone(self.frame, self.local_pool)
+        # the hello/goodbye pair has two purposes: it forces
+        # self.local_pool to be computed even if it was None up to now,
+        # and it puts the 'data' tuple in the correct pool to be cloned.
+        self.hello_local_pool()
+        data = (self.frame, extradata)
+        self.goodbye_local_pool()
+        # clone!
+        data, copy.local_pool = gc_clone(data, self.local_pool)
+        copy.frame, extradata = data
+        return extradata
 
 
 class InterpClonableCoroutine(Coroutine, InterpClonableMixin):

Modified: pypy/dist/pypy/module/_stackless/interp_greenlet.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/interp_greenlet.py	(original)
+++ pypy/dist/pypy/module/_stackless/interp_greenlet.py	Mon Nov 20 13:36:29 2006
@@ -60,8 +60,10 @@
             assert isinstance(w_parent, AppGreenlet)
             self.w_parent = w_parent
         Coroutine.__init__(self, state)
-        if not is_main:
-            space.getexecutioncontext().subcontext_new(self)
+        self.subctx = space.getexecutioncontext().Subcontext()
+        if is_main:
+            self.subctx.framestack = None     # wack
+        else:
             self.bind(GreenletThunk(space, state, self))
 
     def descr_method__new__(space, w_subtype, w_callable):
@@ -75,11 +77,11 @@
 
     def hello(self):
         ec = self.space.getexecutioncontext()
-        ec.subcontext_enter(self)
+        self.subctx.enter(ec)
 
     def goodbye(self):
         ec = self.space.getexecutioncontext()
-        ec.subcontext_leave(self)
+        self.subctx.leave(ec)
 
     def w_getcurrent(space):
         return space.wrap(AppGreenlet._get_state(space).current)
@@ -143,10 +145,11 @@
 
 def w_get_frame(space, w_self):
     self = space.interp_w(AppGreenlet, w_self)    
-    if not self.has_ever_run or space.is_true(self.w_dead):
+    if (not self.has_ever_run or space.is_true(self.w_dead) or
+        self.costate.current is self):
         return space.w_None
     try:
-        return self.framestack.top(0)
+        return self.subctx.framestack.top(0)
     except IndexError:
         return space.w_None
 



More information about the Pypy-commit mailing list