[pypy-svn] r5352 - in pypy/trunk/src/pypy/objspace/flow: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Jun 26 12:49:16 CEST 2004
Author: arigo
Date: Sat Jun 26 12:48:39 2004
New Revision: 5352
Added:
pypy/trunk/src/pypy/objspace/flow/specialcase.py (contents, props changed)
Modified:
pypy/trunk/src/pypy/objspace/flow/objspace.py
pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py
Log:
'raise' in flow graphs. Requires special-casing the app_prepare_raise()
app-helper, so here is some framework to handle special cases.
Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/objspace.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/objspace.py Sat Jun 26 12:48:39 2004
@@ -22,7 +22,7 @@
self.w_None = Constant(None)
self.w_False = Constant(False)
self.w_True = Constant(True)
- for exc in [KeyError, ValueError, StopIteration]:
+ for exc in [KeyError, ValueError, IndexError, StopIteration]:
clsname = exc.__name__
setattr(self, 'w_'+clsname, Constant(exc))
#self.make_builtins()
@@ -100,6 +100,11 @@
#print >> sys.stderr, '*** reraise', etype, evalue
raise OperationError, OperationError(self.wrap(etype), self.wrap(evalue)), etb
+ def setup_executioncontext(self, ec):
+ self.executioncontext = ec
+ from pypy.objspace.flow import specialcase
+ self.specialcases = specialcase.setup(self)
+
def build_flow(self, func, constargs={}):
"""
"""
@@ -111,7 +116,7 @@
closure = [extract_cell_content(c) for c in func.func_closure]
ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
constargs, closure)
- self.executioncontext = ec
+ self.setup_executioncontext(ec)
ec.build_flow()
name = ec.graph.name
for c in "<>&!":
@@ -148,6 +153,13 @@
return w_item
def call_args(self, w_callable, args):
+ try:
+ sc = self.specialcases[self.unwrap(w_callable)]
+ except (UnwrapException, KeyError):
+ pass
+ else:
+ return sc(self, args)
+
if args.kwds_w:
w_args, w_kwds = args.pack()
return self.do_operation('call', w_callable, w_args, w_kwds)
Added: pypy/trunk/src/pypy/objspace/flow/specialcase.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/flow/specialcase.py Sat Jun 26 12:48:39 2004
@@ -0,0 +1,52 @@
+import types
+from pypy.interpreter import pyopcode
+from pypy.interpreter.error import OperationError
+from pypy.objspace.flow.objspace import UnwrapException
+from pypy.objspace.flow.model import Variable
+
+
+def getconstclass(space, w_cls):
+ try:
+ ecls = space.unwrap(w_cls)
+ except UnwrapException:
+ pass
+ else:
+ if isinstance(ecls, (type, types.ClassType)):
+ return ecls
+ return None
+
+
+def prepare_raise(space, args):
+ """Special-case for 'raise' statements.
+
+ Only accept the following syntaxes:
+ * raise Class
+ * raise Class, Arg
+ * raise Class(...)
+ """
+ assert len(args.args_w) == 2 and args.kwds_w == {}
+ w_arg1, w_arg2 = args.args_w
+ #
+ # Note that we immediately raise the correct OperationError to
+ # prevent further processing by pyopcode.py.
+ #
+ etype = getconstclass(space, w_arg1)
+ if etype is not None:
+ # raise Class or raise Class, Arg: ignore the Arg
+ raise OperationError(w_arg1, Variable())
+ else:
+ # raise Instance: we need a hack to figure out of which class it is.
+ # Normally, Instance should have been created by the previous operation
+ # which should be a simple_call(<Class>, ...).
+ # Fetch the <Class> out of there. (This doesn't work while replaying)
+ spaceop = space.executioncontext.crnt_ops[-1]
+ assert spaceop.opname == 'simple_call'
+ assert spaceop.result is w_arg1
+ w_type = spaceop.args[0]
+ raise OperationError(w_type, w_arg2)
+
+
+def setup(space):
+ return {
+ pyopcode.prepare_raise.get_function(space): prepare_raise,
+ }
Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Sat Jun 26 12:48:39 2004
@@ -222,6 +222,30 @@
x = self.codetest(self.freevar(3))
self.show(x)
+ #__________________________________________________________
+ def raise1(msg):
+ raise IndexError
+
+ def test_raise1(self):
+ x = self.codetest(self.raise1)
+ self.show(x)
+
+ #__________________________________________________________
+ def raise2(msg):
+ raise IndexError, msg
+
+ def test_raise2(self):
+ x = self.codetest(self.raise2)
+ self.show(x)
+
+ #__________________________________________________________
+ def raise3(msg):
+ raise IndexError(msg)
+
+ def test_raise3(self):
+ x = self.codetest(self.raise3)
+ self.show(x)
+
if __name__ == '__main__':
testit.main()
More information about the Pypy-commit
mailing list