[pypy-commit] pypy tealet: App-level interface. Untested; unsure how to test it...

arigo noreply at buildbot.pypy.org
Wed Jul 6 20:28:42 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: tealet
Changeset: r45380:1035732daa98
Date: 2011-06-12 11:42 +0200
http://bitbucket.org/pypy/pypy/changeset/1035732daa98/

Log:	App-level interface. Untested; unsure how to test it...

diff --git a/pypy/module/tealet/__init__.py b/pypy/module/tealet/__init__.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/tealet/__init__.py
@@ -0,0 +1,13 @@
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+    """Tealets.  XXX document me"""
+
+    appleveldefs = {
+    }
+
+    interpleveldefs = {
+        'Tealet'    : 'interp_tealet.W_Tealet',
+        'MainTealet': 'interp_tealet.W_MainTealet',
+        'error'     : 'space.fromcache(interp_tealet.Cache).w_error',
+    }
diff --git a/pypy/module/tealet/interp_tealet.py b/pypy/module/tealet/interp_tealet.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/tealet/interp_tealet.py
@@ -0,0 +1,74 @@
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app
+
+from pypy.rlib.rtealet import _make_classes, TealetError
+
+# ____________________________________________________________
+
+W_Tealet, W_MainTealet = _make_classes(Wrappable)
+W_Tealet.__name__     = 'W_Tealet'
+W_MainTealet.__name__ = 'W_MainTealet'
+
+class Cache:
+    def __init__(self, space):
+        self.w_error = space.new_exception_class("tealet.error")
+
+def wrap_error(space, error):
+    w_exception_class = space.fromcache(Cache).w_error
+    w_exception = space.call_function(w_exception_class, space.wrap(error.msg))
+    return OperationError(w_exception_class, w_exception)
+
+# ____________________________________________________________
+
+def W_Tealet_run(self):
+    space = self.space
+    w_other = space.call_method(space.wrap(self), 'run')
+    return space.interp_w(W_Tealet, w_other, can_be_None=True)
+
+def W_Tealet___new__(space, w_subtype, __args__):
+    r = space.allocate_instance(W_Tealet, w_subtype)
+    r.space = space
+    return space.wrap(r)
+
+def W_Tealet_switch(w_self):
+    self = space.interp_w(W_Tealet, w_self)
+    try:
+        self.switch()
+    except TealetError, e:
+        raise wrap_error(space, e)
+
+W_Tealet.run = W_Tealet_run
+W_Tealet.typedef = TypeDef(
+        'Tealet',
+        __module__ = 'tealet',
+        __new__ = interp2app(W_Tealet___new__),
+        switch = interp2app(W_Tealet_switch),
+        )
+
+# ____________________________________________________________
+
+def W_MainTealet___new__(space, w_subtype, __args__):
+    r = space.allocate_instance(W_MainTealet, w_subtype)
+    r.__init__()
+    r.space = space
+    return space.wrap(r)
+
+def W_MainTealet_start(w_self, w_tealet):
+    space = self.space
+    self = space.interp_w(W_MainTealet, w_self)
+    tealet = space.interp_w(W_Tealet, w_tealet)
+    try:
+        self.start(tealet)
+    except TealetError, e:
+        raise wrap_error(space, e)
+
+W_MainTealet.typedef = TypeDef(
+        'MainTealet',
+        __module__ = 'tealet',
+        __new__ = interp2app(W_MainTealet___new__),
+        start = interp2app(W_MainTealet_start),
+        )
+
+# ____________________________________________________________
diff --git a/pypy/rlib/rtealet.py b/pypy/rlib/rtealet.py
--- a/pypy/rlib/rtealet.py
+++ b/pypy/rlib/rtealet.py
@@ -14,34 +14,41 @@
 
 
 class TealetError(Exception):
-    pass
+    def __init__(self, msg):
+        self.msg = msg
 
 
-class Tealet(object):
-    _ll_saved_stack = None
+def _make_classes(base_class):
 
-    def __init__(self, main):
-        assert isinstance(main, MainTealet)
-        self.main = main
-        _new(main, self)
+    class Tealet(base_class):
+        lltealet = _tealet_rffi.NULL_TEALET
+        _ll_saved_stack = None
 
-    def switch(self):
-        _switch(self)
+        def switch(self):
+            _switch(self)
 
-    def run(self):
-        raise NotImplementedError
+        def run(self):
+            raise NotImplementedError
 
+    class MainTealet(Tealet):
+        def __init__(self):
+            assert we_are_translated(), "no support for untranslated runs yet"
+            self.main = self
+            self.current = self
+            self.lltealet = _tealet_rffi.tealet_initialize(_tealet_rffi.NULL)
 
-class MainTealet(Tealet):
-    def __init__(self):
-        assert we_are_translated(), "no support for untranslated runs yet"
-        self.main = self
-        self.current = self
-        self.lltealet = _tealet_rffi.tealet_initialize(_tealet_rffi.NULL)
+        def __del__(self):
+            _tealet_rffi.tealet_finalize(self.lltealet)
 
-    def __del__(self):
-        _tealet_rffi.tealet_finalize(self.lltealet)
+        def start(self, tealet):
+            if tealet.lltealet:
+                raise TealetError("tealet already running")
+            tealet.main = self
+            _new(self, tealet)
 
+    return Tealet, MainTealet
+
+Tealet, MainTealet = _make_classes(object)
 
 ## ------------------------------------------------------------
 ## The code below is implementation details.
@@ -123,12 +130,13 @@
 _switch_critical._dont_inline_ = True
 
 def _check_exception(r):
-    if rffi.cast(lltype.Signed, r) != 0:
+    r = rffi.cast(lltype.Signed, r)
+    if r != 0:
         # rare case: tealet.c complains, e.g. out of memory.  I think that
         # in this case it's not really possible to have 'exception != None'.
         # Clean it anyway to avoid it showing up at a random time later.
         switcher.exception = None
-        raise TealetError
+        raise TealetError("internal error %d" % r)
     e = switcher.exception
     if e is not None:
         switcher.exception = None
diff --git a/pypy/rlib/test/demotealet.py b/pypy/rlib/test/demotealet.py
--- a/pypy/rlib/test/demotealet.py
+++ b/pypy/rlib/test/demotealet.py
@@ -75,7 +75,7 @@
 do_switch._dont_inline_ = True
 
 def do_new(main):
-    MyTealet(main)
+    main.start(MyTealet())
 do_new._dont_inline_ = True
 
 def do(current_tealet_index, x):


More information about the pypy-commit mailing list