[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