[pypy-svn] r24623 - in pypy/dist/pypy/translator/c: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon Mar 20 17:58:19 CET 2006
Author: cfbolz
Date: Mon Mar 20 17:58:18 2006
New Revision: 24623
Modified:
pypy/dist/pypy/translator/c/exceptiontransform.py
pypy/dist/pypy/translator/c/test/test_exceptiontransform.py
Log:
first step in removing exceptions completely: use RPyExceptionOccured to check
whether an exception is active
Modified: pypy/dist/pypy/translator/c/exceptiontransform.py
==============================================================================
--- pypy/dist/pypy/translator/c/exceptiontransform.py (original)
+++ pypy/dist/pypy/translator/c/exceptiontransform.py Mon Mar 20 17:58:18 2006
@@ -1,14 +1,35 @@
from pypy.translator.unsimplify import split_block
from pypy.translator.backendopt import canraise
from pypy.objspace.flow.model import Block, Constant, Variable, Link, \
- c_last_exception, SpaceOperation
+ c_last_exception, SpaceOperation, checkgraph
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.lladdress import NULL
from pypy.rpython import rclass
+from pypy.rpython.rarithmetic import r_uint
+PrimitiveErrorValue = {lltype.Signed: -1,
+ lltype.Unsigned: r_uint(-1),
+ lltype.Float: -1.0,
+ lltype.Char: chr(255),
+ lltype.Bool: True,
+ llmemory.Address: NULL,
+ lltype.Void: None}
+
+def error_value(T):
+ if isinstance(T, lltype.Primitive):
+ return Constant(PrimitiveErrorValue[T], T)
+ elif isinstance(T, Ptr):
+ return Constant(None, T)
+ assert 0, "not implemented yet"
class ExceptionTransformer(object):
def __init__(self, translator):
self.translator = translator
self.raise_analyzer = canraise.RaiseAnalyzer(translator)
+ RPYEXC_OCCURED_TYPE = lltype.FuncType([], lltype.Bool)
+ self.rpyexc_occured_ptr = Constant(lltype.functionptr(
+ RPYEXC_OCCURED_TYPE, "RPyExceptionOccurred", external="C"),
+ lltype.Ptr(RPYEXC_OCCURED_TYPE))
def create_exception_handling(self, graph):
"""After an exception in a direct_call (or indirect_call), that is not caught
@@ -19,35 +40,35 @@
Because of the added exitswitch we need an additional block.
"""
exc_data = self.translator.rtyper.getexceptiondata()
- for block in graph.iterblocks():
- last_operation = len(block.operations)-1
- if block.exitswitch == c_last_exception:
- last_operation -= 1
- for i in range(last_operation, -1, -1):
- op = block.operations[i]
- print "considering op", op, i
- if not self.raise_analyzer.can_raise(op):
- continue
-
- afterblock = split_block(self.translator, graph, block, i+1)
-
- block.exitswitch = c_last_exception
-
- #non-exception case
- block.exits[0].exitcase = block.exits[0].llexitcase = None
-
- #exception occurred case
- etype = Variable('extra_etype')
- etype.concretetype = exc_data.lltype_of_exception_type
- evalue = Variable('extra_evalue')
- evalue.concretetype = exc_data.lltype_of_exception_value
-
- l = Link([etype, evalue], graph.exceptblock)
- l.extravars(etype, evalue)
- l.prevblock = block
- l.exitcase = Exception
- r_case = rclass.get_type_repr(self.translator.rtyper)
- l.llexitcase = r_case.convert_const(l.exitcase)
+ for block in list(graph.iterblocks()): #collect the blocks before changing them
+ self.transform_block(graph, block)
+ checkgraph(graph)
+
+ def transform_block(self, graph, block):
+ last_operation = len(block.operations)-1
+ if block.exitswitch == c_last_exception:
+ last_operation -= 1
+ for i in range(last_operation, -1, -1):
+ op = block.operations[i]
+ print "considering op", op, i
+ if not self.raise_analyzer.can_raise(op):
+ continue
+
+ afterblock = split_block(self.translator, graph, block, i+1)
+
+ var_exc_occured = Variable()
+ var_exc_occured.concretetype = lltype.Bool
+
+ block.operations.append(SpaceOperation("direct_call", [self.rpyexc_occured_ptr], var_exc_occured))
+ block.exitswitch = var_exc_occured
+
+ #non-exception case
+ block.exits[0].exitcase = block.exits[0].llexitcase = False
+
+ #exception occurred case
+ l = Link([error_value(graph.returnblock.inputargs[0].concretetype)], graph.returnblock)
+ l.prevblock = block
+ l.exitcase = l.llexitcase = True
- block.exits.append(l)
+ block.exits.append(l)
Modified: pypy/dist/pypy/translator/c/test/test_exceptiontransform.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_exceptiontransform.py (original)
+++ pypy/dist/pypy/translator/c/test/test_exceptiontransform.py Mon Mar 20 17:58:18 2006
@@ -37,5 +37,5 @@
one(0)
one(1)
t, g = transform_func(foo, [])
- assert len(list(g.iterblocks())) == 5
+ assert len(list(g.iterblocks())) == 4
More information about the Pypy-commit
mailing list