[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