[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