[pypy-svn] r45521 - in pypy/dist/pypy/translator: . cli cli/test test

antocuni at codespeak.net antocuni at codespeak.net
Mon Aug 6 16:06:23 CEST 2007


Author: antocuni
Date: Mon Aug  6 16:06:22 2007
New Revision: 45521

Modified:
   pypy/dist/pypy/translator/cli/gencli.py
   pypy/dist/pypy/translator/cli/test/runtest.py
   pypy/dist/pypy/translator/exceptiontransform.py
   pypy/dist/pypy/translator/test/test_exceptiontransform.py
Log:
port exceptiontransform to ootype, step #3: exceptiontransform ported to ootype :-).

Test passes, but it still does not work with gencli :-(



Modified: pypy/dist/pypy/translator/cli/gencli.py
==============================================================================
--- pypy/dist/pypy/translator/cli/gencli.py	(original)
+++ pypy/dist/pypy/translator/cli/gencli.py	Mon Aug  6 16:06:22 2007
@@ -49,7 +49,7 @@
     DictConst = constant.CLIDictConst
     WeakRefConst = constant.CLIWeakRefConst
 
-    def __init__(self, tmpdir, translator, entrypoint, config=None):
+    def __init__(self, tmpdir, translator, entrypoint, config=None, exctrans=False):
         GenOO.__init__(self, tmpdir, translator, entrypoint, config)
         for node in get_prebuilt_nodes(translator, self.db):
             self.db.pending_node(node)
@@ -62,6 +62,11 @@
                 SSI_to_SSA(graph)
                 build_trees(graph)
 
+        if exctrans:
+            etrafo = translator.getexceptiontransformer()
+            for graph in translator.graphs:
+                etrafo.create_exception_handling(graph)
+
     def generate_source(self):
         GenOO.generate_source(self)
         self.db.const_count.dump(self.const_stat)

Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py	Mon Aug  6 16:06:22 2007
@@ -127,15 +127,16 @@
             assert False, 'Input type %s not supported' % arg_type
 
 
-def compile_function(func, annotation=[], graph=None, backendopt=True, auto_raise_exc=False):
+def compile_function(func, annotation=[], graph=None, backendopt=True,
+                     auto_raise_exc=False, exctrans=False):
     olddefs = patch()
-    gen = _build_gen(func, annotation, graph, backendopt)
+    gen = _build_gen(func, annotation, graph, backendopt, exctrans)
     gen.generate_source()
     exe_name = gen.build_exe()
     unpatch(*olddefs) # restore original values
     return CliFunctionWrapper(exe_name, func.__name__, auto_raise_exc)
 
-def _build_gen(func, annotation, graph=None, backendopt=True):
+def _build_gen(func, annotation, graph=None, backendopt=True, exctrans=False):
     try: 
         func = func.im_func
     except AttributeError: 
@@ -169,7 +170,7 @@
     else:
         tmpdir = udir
 
-    return GenCli(tmpdir, t, TestEntryPoint(main_graph, True))
+    return GenCli(tmpdir, t, TestEntryPoint(main_graph, True), exctrans=exctrans)
 
 class CliFunctionWrapper(object):
     def __init__(self, exe_name, name=None, auto_raise_exc=False):

Modified: pypy/dist/pypy/translator/exceptiontransform.py
==============================================================================
--- pypy/dist/pypy/translator/exceptiontransform.py	(original)
+++ pypy/dist/pypy/translator/exceptiontransform.py	Mon Aug  6 16:06:22 2007
@@ -5,6 +5,7 @@
 from pypy.objspace.flow.model import Block, Constant, Variable, Link, \
     c_last_exception, SpaceOperation, checkgraph, FunctionGraph
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.lltypesystem import lloperation
 from pypy.rpython.memory.lladdress import NULL
 from pypy.rpython import rtyper
@@ -31,30 +32,24 @@
         return PrimitiveErrorValue[T]
     elif isinstance(T, lltype.Ptr):
         return lltype.nullptr(T.TO)
+    elif isinstance(T, ootype.OOType):
+        return ootype.null(T)
     assert 0, "not implemented yet"
 
 def error_constant(T):
     return Constant(error_value(T), T)
 
-class ExceptionTransformer(object):
+class BaseExceptionTransformer(object):
+
     def __init__(self, translator):
         self.translator = translator
         self.raise_analyzer = canraise.RaiseAnalyzer(translator)
         edata = translator.rtyper.getexceptiondata()
         self.lltype_of_exception_value = edata.lltype_of_exception_value
         self.lltype_of_exception_type = edata.lltype_of_exception_type
-        mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
-        l2a = annmodel.lltype_to_annotation
+        self.mixlevelannotator  = MixLevelHelperAnnotator(translator.rtyper)
+        exc_data, null_type, null_value = self.setup_excdata()
 
-        EXCDATA = lltype.Struct('ExcData',
-            ('exc_type',  self.lltype_of_exception_type),
-            ('exc_value', self.lltype_of_exception_value))
-        self.EXCDATA = EXCDATA
-
-        exc_data = lltype.malloc(EXCDATA, immortal=True)
-        null_type = lltype.nullptr(self.lltype_of_exception_type.TO)
-        null_value = lltype.nullptr(self.lltype_of_exception_value.TO)
-        
         def rpyexc_occured():
             exc_type = exc_data.exc_type
             return bool(exc_type)
@@ -80,89 +75,48 @@
             # assert(!RPyExceptionOccurred());
             exc_data.exc_type = etype
             exc_data.exc_value = evalue
-        
-        RPYEXC_OCCURED_TYPE = lltype.FuncType([], lltype.Bool)
-        rpyexc_occured_graph = mixlevelannotator.getgraph(
-            rpyexc_occured, [], l2a(lltype.Bool))
-        self.rpyexc_occured_ptr = Constant(lltype.functionptr(
-            RPYEXC_OCCURED_TYPE, "RPyExceptionOccurred",
-            graph=rpyexc_occured_graph,
-            exception_policy="exc_helper"),
-            lltype.Ptr(RPYEXC_OCCURED_TYPE))
 
-        # XXX tmp HACK for genllvm
-        _RPYEXC_OCCURED_TYPE = lltype.FuncType([], lltype.Signed)
-        _rpyexc_occured_graph = mixlevelannotator.getgraph(
-            _rpyexc_occured, [], l2a(lltype.Signed))
-        self._rpyexc_occured_ptr = Constant(lltype.functionptr(
-            _RPYEXC_OCCURED_TYPE, "_RPyExceptionOccurred",
-            graph=_rpyexc_occured_graph,
-            exception_policy="exc_helper"),
-            lltype.Ptr(_RPYEXC_OCCURED_TYPE))
-        
-        RPYEXC_FETCH_TYPE_TYPE = lltype.FuncType([], self.lltype_of_exception_type)
-        rpyexc_fetch_type_graph = mixlevelannotator.getgraph(
-            rpyexc_fetch_type, [],
-            l2a(self.lltype_of_exception_type))
-        self.rpyexc_fetch_type_ptr = Constant(lltype.functionptr(
-            RPYEXC_FETCH_TYPE_TYPE, "RPyFetchExceptionType",
-            graph=rpyexc_fetch_type_graph,
-            exception_policy="exc_helper"),
-            lltype.Ptr(RPYEXC_FETCH_TYPE_TYPE))
-        
-        RPYEXC_FETCH_VALUE_TYPE = lltype.FuncType([], self.lltype_of_exception_value)
-        rpyexc_fetch_value_graph = mixlevelannotator.getgraph(
-            rpyexc_fetch_value, [],
-            l2a(self.lltype_of_exception_value))
-        self.rpyexc_fetch_value_ptr = Constant(lltype.functionptr(
-            RPYEXC_FETCH_VALUE_TYPE, "RPyFetchExceptionValue",
-            graph=rpyexc_fetch_value_graph,
-            exception_policy="exc_helper"),
-            lltype.Ptr(RPYEXC_FETCH_VALUE_TYPE))
-
-        RPYEXC_CLEAR = lltype.FuncType([], lltype.Void)
-        rpyexc_clear_graph = mixlevelannotator.getgraph(
-            rpyexc_clear, [], l2a(lltype.Void))
-        self.rpyexc_clear_ptr = Constant(lltype.functionptr(
-            RPYEXC_CLEAR, "RPyClearException",
-            graph=rpyexc_clear_graph,
-            exception_policy="exc_helper"),
-            lltype.Ptr(RPYEXC_CLEAR))
-
-        RPYEXC_RAISE = lltype.FuncType([self.lltype_of_exception_type,
-                                        self.lltype_of_exception_value],
-                                        lltype.Void)
-        rpyexc_raise_graph = mixlevelannotator.getgraph(
-            rpyexc_raise, [l2a(self.lltype_of_exception_type),
-                           l2a(self.lltype_of_exception_value)],
-            l2a(lltype.Void))
-        self.rpyexc_raise_ptr = Constant(lltype.functionptr(
-            RPYEXC_RAISE, "RPyRaiseException",
-            graph=rpyexc_raise_graph,
-            exception_policy="exc_helper",
-            jitcallkind='rpyexc_raise',   # for the JIT
-            ),
-            lltype.Ptr(RPYEXC_RAISE))
+        self.rpyexc_occured_ptr = self.build_func(
+            "RPyExceptionOccurred",
+            rpyexc_occured,
+            [], lltype.Bool)
 
-        mixlevelannotator.finish()
+        # XXX tmp HACK for genllvm
+        self._rpyexc_occured_ptr = self.build_func(
+            "_RPyExceptionOccurred",
+            _rpyexc_occured,
+            [], lltype.Signed)
+
+        self.rpyexc_fetch_type_ptr = self.build_func(
+            "RPyFetchExceptionType",
+            rpyexc_fetch_type,
+            [], self.lltype_of_exception_type)
+
+        self.rpyexc_fetch_value_ptr = self.build_func(
+            "RPyFetchExceptionValue",
+            rpyexc_fetch_value,
+            [], self.lltype_of_exception_value)
+
+        self.rpyexc_clear_ptr = self.build_func(
+            "RPyClearException",
+            rpyexc_clear,
+            [], lltype.Void)
+
+        self.rpyexc_raise_ptr = self.build_func(
+            "RPyRaiseException",
+            rpyexc_raise,
+            [self.lltype_of_exception_type, self.lltype_of_exception_value],
+            lltype.Void,
+            jitcallkind='rpyexc_raise') # for the JIT
 
-        self.exc_data_ptr = exc_data
-        self.cexcdata = Constant(exc_data, lltype.Ptr(EXCDATA))
-        
+        self.mixlevelannotator.finish()
         self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
-        p = lltype.nullptr(self.lltype_of_exception_type.TO)
-        self.c_null_etype = Constant(p, self.lltype_of_exception_type)
-        p = lltype.nullptr(self.lltype_of_exception_value.TO)
-        self.c_null_evalue = Constant(p, self.lltype_of_exception_value)
 
-    def gen_getfield(self, name, llops):
-        c_name = inputconst(lltype.Void, name)
-        return llops.genop('getfield', [self.cexcdata, c_name],
-                           resulttype = getattr(self.EXCDATA, name))
-
-    def gen_setfield(self, name, v_value, llops):
-        c_name = inputconst(lltype.Void, name)
-        llops.genop('setfield', [self.cexcdata, c_name, v_value])
+    def build_func(self, name, fn, inputtypes, rettype, **kwds):
+        l2a = annmodel.lltype_to_annotation
+        graph = self.mixlevelannotator.getgraph(fn, map(l2a, inputtypes), l2a(rettype))
+        return self.constant_func(name, inputtypes, rettype, graph, 
+                                  exception_policy="exc_helper", **kwds)
 
     def transform_completely(self):
         for graph in self.translator.graphs:
@@ -177,7 +131,7 @@
         Because of the added exitswitch we need an additional block.
         """
         if hasattr(graph, 'exceptiontransformed'):
-            assert self.exc_data_ptr._same_obj(graph.exceptiontransformed)
+            assert self.same_obj(self.exc_data_ptr, graph.exceptiontransformed)
             return
         else:
             self.raise_analyzer.analyze_direct_call(graph)
@@ -308,9 +262,7 @@
         excblock.closeblock(Link([var_type, var_value], newgraph.exceptblock))
         startblock.exits[True].target = excblock
         startblock.exits[True].args = []
-        FUNCTYPE = lltype.FuncType(ARGTYPES, op.result.concretetype)
-        fptr = Constant(lltype.functionptr(FUNCTYPE, "dummy_exc1", graph=newgraph),
-                        lltype.Ptr(FUNCTYPE))
+        fptr = self.constant_func("dummy_exc1", ARGTYPES, op.result.concretetype, newgraph)
         return newgraph, SpaceOperation("direct_call", [fptr] + callargs, op.result) 
 
     def gen_exc_check(self, block, returnblock, normalafterblock=None):
@@ -319,26 +271,17 @@
         #block.operations.append(SpaceOperation("safe_call", [self.rpyexc_occured_ptr], var_exc_occured))
 
         llops = rtyper.LowLevelOpList(None)
-        alloc_shortcut = False
 
         spaceop = block.operations[-1]
-        if spaceop.opname in ('malloc', 'malloc_varsize'):
-            alloc_shortcut = True
-        elif spaceop.opname == 'direct_call':
-            fnobj = spaceop.args[0].value._obj
-            if hasattr(fnobj, '_callable'):
-                oopspec = getattr(fnobj._callable, 'oopspec', None)
-                if oopspec and oopspec == 'newlist(length)':
-                    alloc_shortcut = True
-                    
+        alloc_shortcut = self.check_for_alloc_shortcut(spaceop)
+
+        # XXX: does alloc_shortcut make sense also for ootype?
         if alloc_shortcut:
             T = spaceop.result.concretetype
-            var_no_exc = llops.genop('ptr_nonzero', [spaceop.result],
-                                     lltype.Bool)            
+            var_no_exc = self.gen_nonnull(spaceop.result, llops)
         else:
             v_exc_type = self.gen_getfield('exc_type', llops)
-            var_no_exc = llops.genop('ptr_iszero', [v_exc_type],
-                                     lltype.Bool)
+            var_no_exc = self.gen_isnull(v_exc_type, llops)
 
         block.operations.extend(llops)
         
@@ -384,3 +327,110 @@
             self.gen_setfield('exc_value', self.c_null_evalue, llops)
             self.gen_setfield('exc_type',  self.c_null_etype,  llops)
             normalafterblock.operations[:0] = llops
+
+class LLTypeExceptionTransformer(BaseExceptionTransformer):
+
+    def setup_excdata(self):
+        EXCDATA = lltype.Struct('ExcData',
+            ('exc_type',  self.lltype_of_exception_type),
+            ('exc_value', self.lltype_of_exception_value))
+        self.EXCDATA = EXCDATA
+
+        exc_data = lltype.malloc(EXCDATA, immortal=True)
+        null_type = lltype.nullptr(self.lltype_of_exception_type.TO)
+        null_value = lltype.nullptr(self.lltype_of_exception_value.TO)
+
+        self.exc_data_ptr = exc_data
+        self.cexcdata = Constant(exc_data, lltype.Ptr(self.EXCDATA))
+        self.c_null_etype = Constant(null_type, self.lltype_of_exception_type)
+        self.c_null_evalue = Constant(null_value, self.lltype_of_exception_value)
+
+        return exc_data, null_type, null_value
+
+    def constant_func(self, name, inputtypes, rettype, graph, **kwds):
+        FUNC_TYPE = lltype.FuncType(inputtypes, rettype)
+        fn_ptr = lltype.functionptr(FUNC_TYPE, name, graph=graph, **kwds)
+        return Constant(fn_ptr, lltype.Ptr(FUNC_TYPE))
+
+    def gen_getfield(self, name, llops):
+        c_name = inputconst(lltype.Void, name)
+        return llops.genop('getfield', [self.cexcdata, c_name],
+                           resulttype = getattr(self.EXCDATA, name))
+
+    def gen_setfield(self, name, v_value, llops):
+        c_name = inputconst(lltype.Void, name)
+        llops.genop('setfield', [self.cexcdata, c_name, v_value])
+
+    def gen_isnull(self, v, llops):
+        return llops.genop('ptr_iszero', [v], lltype.Bool)
+
+    def gen_nonnull(self, v, llops):
+        return llops.genop('ptr_nonzero', [v], lltype.Bool)
+
+    def same_obj(self, ptr1, ptr2):
+        return ptr1._same_obj(ptr2)
+
+    def check_for_alloc_shortcut(self, spaceop):
+        if spaceop.opname in ('malloc', 'malloc_varsize'):
+            return True
+        elif spaceop.opname == 'direct_call':
+            fnobj = spaceop.args[0].value._obj
+            if hasattr(fnobj, '_callable'):
+                oopspec = getattr(fnobj._callable, 'oopspec', None)
+                if oopspec and oopspec == 'newlist(length)':
+                    return True
+        return False
+
+class OOTypeExceptionTransformer(BaseExceptionTransformer):
+
+    def setup_excdata(self):
+        EXCDATA = ootype.Record({'exc_type': self.lltype_of_exception_type,
+                                 'exc_value': self.lltype_of_exception_value})
+        self.EXCDATA = EXCDATA
+
+        exc_data = ootype.new(EXCDATA)
+        null_type = ootype.null(self.lltype_of_exception_type)
+        null_value = ootype.null(self.lltype_of_exception_value)
+
+        self.exc_data_ptr = exc_data
+        self.cexcdata = Constant(exc_data, self.EXCDATA)
+
+        self.c_null_etype = Constant(null_type, self.lltype_of_exception_type)
+        self.c_null_evalue = Constant(null_value, self.lltype_of_exception_value)
+
+        return exc_data, null_type, null_value
+
+    def constant_func(self, name, inputtypes, rettype, graph, **kwds):
+        FUNC_TYPE = ootype.StaticMethod(inputtypes, rettype)
+        fn_ptr = ootype.static_meth(FUNC_TYPE, name, graph=graph, **kwds)
+        return Constant(fn_ptr, FUNC_TYPE)
+
+    def gen_getfield(self, name, llops):
+        c_name = inputconst(lltype.Void, name)
+        return llops.genop('oogetfield', [self.cexcdata, c_name],
+                           resulttype = self.EXCDATA._field_type(name))
+
+    def gen_setfield(self, name, v_value, llops):
+        c_name = inputconst(lltype.Void, name)
+        llops.genop('oosetfield', [self.cexcdata, c_name, v_value])
+
+    def gen_isnull(self, v, llops):
+        nonnull = self.gen_nonnull(v, llops)
+        return llops.genop('bool_not', [nonnull], lltype.Bool)
+
+    def gen_nonnull(self, v, llops):
+        return llops.genop('oononnull', [v], lltype.Bool)
+
+    def same_obj(self, obj1, obj2):
+        return obj1 is obj2
+
+    def check_for_alloc_shortcut(self, spaceop):
+        return False
+
+def ExceptionTransformer(translator):
+    type_system = translator.rtyper.type_system.name
+    if type_system == 'lltypesystem':
+        return LLTypeExceptionTransformer(translator)
+    else:
+        assert type_system == 'ootypesystem'
+        return OOTypeExceptionTransformer(translator)

Modified: pypy/dist/pypy/translator/test/test_exceptiontransform.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_exceptiontransform.py	(original)
+++ pypy/dist/pypy/translator/test/test_exceptiontransform.py	Mon Aug  6 16:06:22 2007
@@ -2,10 +2,7 @@
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.translator.simplify import join_blocks
 from pypy.translator import exceptiontransform
-from pypy.translator.c import genc, gc
-from pypy.objspace.flow.model import c_last_exception
 from pypy.rpython.test.test_llinterp import get_interpreter
-from pypy.translator.c.test.test_genc import compile
 from pypy import conftest
 import sys
 
@@ -16,20 +13,6 @@
     if not hasattr(sys, 'gettotalrefcount') and not conftest.option.view:
         py.test.skip("test needs a debug build of Python")
 
-def transform_func(fn, inputtypes):
-    t = TranslationContext()
-    t.buildannotator().build_types(fn, inputtypes)
-    t.buildrtyper().specialize()
-    if conftest.option.view:
-        t.view()
-    g = graphof(t, fn)
-    etrafo = exceptiontransform.ExceptionTransformer(t)
-    etrafo.create_exception_handling(g)
-    join_blocks(g)
-    if conftest.option.view:
-        t.view()
-    return t, g
-
 _already_transformed = {}
 
 def interpret(func, values):
@@ -41,164 +24,201 @@
         _already_transformed[t] = True
     return interp.eval_graph(graph, values)
 
-def test_simple():
-    def one():
-        return 1
-    
-    def foo():
-        one()
-        return one()
-
-    t, g = transform_func(foo, [])
-    assert len(list(g.iterblocks())) == 2 # graph does not change 
-    result = interpret(foo, [])
-    assert result == 1
-    f = compile(foo, [])
-    assert f() == 1
+class BaseTestExceptionTransform:
+    type_system = None
+
+    def transform_func(self, fn, inputtypes):
+        t = TranslationContext()
+        t.buildannotator().build_types(fn, inputtypes)
+        t.buildrtyper(type_system=self.type_system).specialize()
+        if conftest.option.view:
+            t.view()
+        g = graphof(t, fn)
+        etrafo = exceptiontransform.ExceptionTransformer(t)
+        etrafo.create_exception_handling(g)
+        join_blocks(g)
+        if conftest.option.view:
+            t.view()
+        return t, g
+
+    def compile(self, fn, inputargs):
+        raise NotImplementedError
     
-def test_passthrough():
-    def one(x):
-        if x:
-            raise ValueError()
-
-    def foo():
-        one(0)
-        one(1)
-    t, g = transform_func(foo, [])
-    f = compile(foo, [])
-    py.test.raises(ValueError, f)
-
-def test_catches():
-    def one(x):
-        if x == 1:
-            raise ValueError()
-        elif x == 2:
-            raise TypeError()
-        return x - 5
-
-    def foo(x):
-        x = one(x)
-        try:
+    def test_simple(self):
+        def one():
+            return 1
+
+        def foo():
+            one()
+            return one()
+
+        t, g = self.transform_func(foo, [])
+        assert len(list(g.iterblocks())) == 2 # graph does not change 
+        result = interpret(foo, [])
+        assert result == 1
+        f = self.compile(foo, [])
+        assert f() == 1
+
+    def test_passthrough(self):
+        def one(x):
+            if x:
+                raise ValueError()
+
+        def foo():
+            one(0)
+            one(1)
+        t, g = self.transform_func(foo, [])
+        f = self.compile(foo, [])
+        py.test.raises(ValueError, f)
+
+    def test_catches(self):
+        def one(x):
+            if x == 1:
+                raise ValueError()
+            elif x == 2:
+                raise TypeError()
+            return x - 5
+
+        def foo(x):
             x = one(x)
-        except ValueError:
-            return 1 + x
-        except TypeError:
-            return 2 + x
-        except:
-            return 3 + x
-        return 4 + x
-    t, g = transform_func(foo, [int])
-    assert len(list(g.iterblocks())) == 9
-    f = compile(foo, [int])
-    result = interpret(foo, [6])
-    assert result == 2
-    result = f(6)
-    assert result == 2
-    result = interpret(foo, [7])
-    assert result == 4
-    result = f(7)
-    assert result == 4
-    result = interpret(foo, [8])
-    assert result == 2
-    result = f(8)
-    assert result == 2
-
-def test_bare_except():
-    def one(x):
-        if x == 1:
-            raise ValueError()
-        elif x == 2:
-            raise TypeError()
-        return x - 5
-
-    def foo(x):
-        x = one(x)
-        try:
+            try:
+                x = one(x)
+            except ValueError:
+                return 1 + x
+            except TypeError:
+                return 2 + x
+            except:
+                return 3 + x
+            return 4 + x
+        t, g = self.transform_func(foo, [int])
+        assert len(list(g.iterblocks())) == 9
+        f = self.compile(foo, [int])
+        result = interpret(foo, [6])
+        assert result == 2
+        result = f(6)
+        assert result == 2
+        result = interpret(foo, [7])
+        assert result == 4
+        result = f(7)
+        assert result == 4
+        result = interpret(foo, [8])
+        assert result == 2
+        result = f(8)
+        assert result == 2
+
+    def test_bare_except(self):
+        def one(x):
+            if x == 1:
+                raise ValueError()
+            elif x == 2:
+                raise TypeError()
+            return x - 5
+
+        def foo(x):
             x = one(x)
-        except:
-            return 1 + x
-        return 4 + x
-    t, g = transform_func(foo, [int])
-    assert len(list(g.iterblocks())) == 5
-    f = compile(foo, [int])
-    result = interpret(foo, [6])
-    assert result == 2
-    result = f(6)
-    assert result == 2
-    result = interpret(foo, [7])
-    assert result == 3
-    result = f(7)
-    assert result == 3
-    result = interpret(foo, [8])
-    assert result == 2
-    result = f(8)
-    assert result == 2
-    
-def test_raises():
-    def foo(x):
-        if x:
-            raise ValueError()
-    t, g = transform_func(foo, [int])
-    assert len(list(g.iterblocks())) == 3
-    f = compile(foo, [int])
-    f(0)
-    py.test.raises(ValueError, f, 1)
-
-def test_needs_keepalive():
-    check_debug_build()
-    from pypy.rpython.lltypesystem import lltype
-    X = lltype.GcStruct("X",
-                        ('y', lltype.Struct("Y", ('z', lltype.Signed))))
-    def can_raise(n):
-        if n:
-            raise Exception
-        else:
-            return 1
-    def foo(n):
-        x = lltype.malloc(X)
-        y = x.y
-        y.z = 42
-        r = can_raise(n)
-        return r + y.z
-    f = compile(foo, [int])
-    res = f(0)
-    assert res == 43
-
-def test_no_multiple_transform():
-    def f(x):
-        return x + 1
-    t = TranslationContext()
-    t.buildannotator().build_types(f, [int])
-    t.buildrtyper().specialize()
-    g = graphof(t, f)
-    etrafo = exceptiontransform.ExceptionTransformer(t)
-    etrafo.create_exception_handling(g)
-    etrafo2 = exceptiontransform.ExceptionTransformer(t)
-    py.test.raises(AssertionError, etrafo2.create_exception_handling, g)
-
-def test_preserve_can_raise():
-    def f(x):
-        raise ValueError
-    t = TranslationContext()
-    t.buildannotator().build_types(f, [int])
-    t.buildrtyper().specialize()
-    g = graphof(t, f)
-    etrafo = exceptiontransform.ExceptionTransformer(t)
-    etrafo.create_exception_handling(g)    
-    assert etrafo.raise_analyzer.analyze_direct_call(g)
-
-def test_inserting_zeroing_op():
-    from pypy.rpython.lltypesystem import lltype
-    S = lltype.GcStruct("S", ('x', lltype.Signed))
-    def f(x):
-        s = lltype.malloc(S)
-        s.x = 0
-        return s.x
-    t = TranslationContext()
-    t.buildannotator().build_types(f, [int])
-    t.buildrtyper().specialize()
-    g = graphof(t, f)
-    etrafo = exceptiontransform.ExceptionTransformer(t)
-    etrafo.create_exception_handling(g)
-    ops = dict.fromkeys([o.opname for b, o in g.iterblockops()])
-    assert 'zero_gc_pointers_inside' in ops
+            try:
+                x = one(x)
+            except:
+                return 1 + x
+            return 4 + x
+        t, g = self.transform_func(foo, [int])
+        assert len(list(g.iterblocks())) == 5
+        f = self.compile(foo, [int])
+        result = interpret(foo, [6])
+        assert result == 2
+        result = f(6)
+        assert result == 2
+        result = interpret(foo, [7])
+        assert result == 3
+        result = f(7)
+        assert result == 3
+        result = interpret(foo, [8])
+        assert result == 2
+        result = f(8)
+        assert result == 2
+
+    def test_raises(self):
+        def foo(x):
+            if x:
+                raise ValueError()
+        t, g = self.transform_func(foo, [int])
+        assert len(list(g.iterblocks())) == 3
+        f = self.compile(foo, [int])
+        f(0)
+        py.test.raises(ValueError, f, 1)
+
+
+    def test_no_multiple_transform(self):
+        def f(x):
+            return x + 1
+        t = TranslationContext()
+        t.buildannotator().build_types(f, [int])
+        t.buildrtyper(type_system=self.type_system).specialize()
+        g = graphof(t, f)
+        etrafo = exceptiontransform.ExceptionTransformer(t)
+        etrafo.create_exception_handling(g)
+        etrafo2 = exceptiontransform.ExceptionTransformer(t)
+        py.test.raises(AssertionError, etrafo2.create_exception_handling, g)
+
+    def test_preserve_can_raise(self):
+        def f(x):
+            raise ValueError
+        t = TranslationContext()
+        t.buildannotator().build_types(f, [int])
+        t.buildrtyper(type_system=self.type_system).specialize()
+        g = graphof(t, f)
+        etrafo = exceptiontransform.ExceptionTransformer(t)
+        etrafo.create_exception_handling(g)    
+        assert etrafo.raise_analyzer.analyze_direct_call(g)
+
+
+class TestLLType(BaseTestExceptionTransform):
+    type_system = 'lltype'
+
+    def compile(self, fn, inputargs):
+        from pypy.translator.c.test.test_genc import compile
+        return compile(fn, inputargs)
+
+    def test_needs_keepalive(self):
+        check_debug_build()
+        from pypy.rpython.lltypesystem import lltype
+        X = lltype.GcStruct("X",
+                            ('y', lltype.Struct("Y", ('z', lltype.Signed))))
+        def can_raise(n):
+            if n:
+                raise Exception
+            else:
+                return 1
+        def foo(n):
+            x = lltype.malloc(X)
+            y = x.y
+            y.z = 42
+            r = can_raise(n)
+            return r + y.z
+        f = self.compile(foo, [int])
+        res = f(0)
+        assert res == 43
+
+    def test_inserting_zeroing_op(self):
+        from pypy.rpython.lltypesystem import lltype
+        S = lltype.GcStruct("S", ('x', lltype.Signed))
+        def f(x):
+            s = lltype.malloc(S)
+            s.x = 0
+            return s.x
+        t = TranslationContext()
+        t.buildannotator().build_types(f, [int])
+        t.buildrtyper(type_system=self.type_system).specialize()
+        g = graphof(t, f)
+        etrafo = exceptiontransform.ExceptionTransformer(t)
+        etrafo.create_exception_handling(g)
+        ops = dict.fromkeys([o.opname for b, o in g.iterblockops()])
+        assert 'zero_gc_pointers_inside' in ops
+
+class TestOOType(BaseTestExceptionTransform):
+    type_system = 'ootype'
+
+    def compile(self, fn, inputargs):
+        from pypy.translator.cli.test.runtest import compile_function
+        # XXX: set exctrans=True
+        return compile_function(fn, inputargs, auto_raise_exc=True, exctrans=False)



More information about the Pypy-commit mailing list