[pypy-svn] r9502 - in pypy/dist/pypy: annotation objspace/flow translator translator/test translator/tool
pedronis at codespeak.net
pedronis at codespeak.net
Fri Feb 25 16:38:27 CET 2005
Author: pedronis
Date: Fri Feb 25 16:38:27 2005
New Revision: 9502
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/objspace/flow/flowcontext.py
pypy/dist/pypy/objspace/flow/model.py
pypy/dist/pypy/objspace/flow/objspace.py
pypy/dist/pypy/translator/annrpython.py
pypy/dist/pypy/translator/test/snippet.py
pypy/dist/pypy/translator/test/test_annrpython.py
pypy/dist/pypy/translator/test/test_pyrextrans.py
pypy/dist/pypy/translator/tool/make_dot.py
Log:
- added another test involving exception handling
improved annotation of ex handling code: we pass this and yesterday added test,
notice that the improved logic works only on simplfied flow graph (changed some tests to respect this),
(I have added code that mark a block starting exc handling, thinking I could have needed the info,
right now it seems not the case)
- changed a bit the way we deal with functions never returning but only raising exceptions,
may want to write a test to see whether this effectively helps with the kind of code involved
in multimethods failing paths.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Fri Feb 25 16:38:27 2005
@@ -36,6 +36,10 @@
return obj1
else:
result = SomeObject()
+ is_type_of1 = getattr(obj1, 'is_type_of', None)
+ is_type_of2 = getattr(obj2, 'is_type_of', None)
+ if is_type_of1 and is_type_of1 == is_type_of2:
+ result.is_type_of = is_type_of1
# try to preserve the origin of SomeObjects
if obj1 == result:
return obj1
@@ -292,7 +296,16 @@
if isclassdef(classdef):
classdef = classdef.commonbase(d[x])
d[x] = classdef
- return SomePBC(d)
+ result = SomePBC(d)
+ is_type_of1 = getattr(pbc1, 'is_type_of', None)
+ is_type_of2 = getattr(pbc2, 'is_type_of', None)
+ if is_type_of1 and is_type_of1 == is_type_of2:
+ result.is_type_of = is_type_of1
+ return result
+
+class __extend__(pairtype(SomeImpossibleValue, SomeImpossibleValue)):
+ def union((imp1, imp2)):
+ return SomeImpossibleValue(benign=imp1.benign and imp2.benign)
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
def union((imp1, obj2)):
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Fri Feb 25 16:38:27 2005
@@ -243,11 +243,13 @@
class SomeImpossibleValue(SomeObject):
"""The empty set. Instances are placeholders for objects that
will never show up at run-time, e.g. elements of an empty list."""
+ def __init__(self, benign=False):
+ self.benign = benign
def unionof(*somevalues):
"The most precise SomeValue instance that contains all the values."
- s1 = SomeImpossibleValue()
+ s1 = SomeImpossibleValue(benign=len(somevalues)>0)
for s2 in somevalues:
if s1 != s2:
s1 = pair(s1, s2).union()
Modified: pypy/dist/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/dist/pypy/objspace/flow/flowcontext.py Fri Feb 25 16:38:27 2005
@@ -196,11 +196,11 @@
w_condition,)
def guessexception(self, *classes):
- outcome = self.guessbool(Constant(last_exception),
+ outcome = self.guessbool(Constant(last_exception, last_exception=True),
cases = [None] + list(classes),
replace_last_variable_except_in_first_case = [
- Constant(last_exception), # exc. class
- Constant(last_exc_value)]) # exc. value
+ Constant(last_exception, last_exception=True), # exc. class
+ Constant(last_exc_value, last_exc_value=True)]) # exc. value
if outcome is None:
w_exc_cls, w_exc_value = None, None
else:
Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py (original)
+++ pypy/dist/pypy/objspace/flow/model.py Fri Feb 25 16:38:27 2005
@@ -67,11 +67,15 @@
# Constant(last_exception), see below
self.exits = [] # list of Link(s)
+ self.exc_handler = False # block at the start of exception handling code
+
def __str__(self):
if self.operations:
txt = "block@%d" % self.operations[0].offset
else:
txt = "codeless block"
+ if self.exc_handler:
+ txt = text +" EH"
return txt
def __repr__(self):
@@ -150,7 +154,7 @@
class Constant:
- def __init__(self, value):
+ def __init__(self, value, **flags):
self.value = value # a concrete value
# try to be smart about constant mutable or immutable values
key = type(self.value), self.value # to avoid confusing e.g. 0 and 0.0
@@ -159,7 +163,11 @@
except TypeError:
key = id(self.value)
self.key = key
-
+ if not flags:
+ self.flags = None
+ else:
+ self.flags = flags
+
def __eq__(self, other):
return self.__class__ is other.__class__ and self.key == other.key
@@ -169,6 +177,9 @@
def __hash__(self):
return hash(self.key)
+ def has_flag(self, flag_name):
+ return self.flags and flag_name in self.flags
+
def __repr__(self):
# try to limit the size of the repr to make it more readable
r = repr(self.value)
@@ -177,7 +188,12 @@
r = '%s %s' % (type(self.value).__name__, self.value.__name__)
elif len(r) > 60 or (len(r) > 30 and type(self.value) is not str):
r = r[:20] + '...' + r[-8:]
- return '(%s)' % r
+ if self.flags:
+ flags = ' '.join([':'+f for f in self.flags.keys()])
+ flags = ' '+flags
+ else:
+ flags = ''
+ return '(%s%s)' % (r, flags)
# hack! it is useful to have UNDEFINED be an instance of Constant too.
# PyFrame then automatically uses this Constant as a marker for
Modified: pypy/dist/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/objspace.py (original)
+++ pypy/dist/pypy/objspace/flow/objspace.py Fri Feb 25 16:38:27 2005
@@ -164,6 +164,11 @@
from pypy.objspace.flow import specialcase
specialcase.setup(self)
+ def exception_match(self, w_exc_type, w_check_class):
+ self.executioncontext.crnt_block.exc_handler = True
+ return ObjSpace.exception_match(self, w_exc_type, w_check_class)
+
+
def build_flow(self, func, constargs={}):
"""
"""
@@ -322,7 +327,7 @@
# one specified by 'outcome', and not a subclass of it,
# unless 'outcome' is Exception.
if outcome is not Exception:
- w_exc_cls = Constant(outcome)
+ w_exc_cls = Constant(outcome, last_exception=True)
raise OperationError(w_exc_cls, w_exc_value)
# ______________________________________________________________________
Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py (original)
+++ pypy/dist/pypy/translator/annrpython.py Fri Feb 25 16:38:27 2005
@@ -10,7 +10,6 @@
from pypy.objspace.flow.model import SpaceOperation, FunctionGraph
from pypy.objspace.flow.model import last_exception, last_exc_value
-
class AnnotatorError(Exception):
pass
@@ -217,7 +216,8 @@
if graph.hasonlyexceptionreturns():
# XXX for functions with exceptions what to
# do anyway?
- return self.bookkeeper.immutablevalue(None)
+ #return self.bookkeeper.immutablevalue(None)
+ return annmodel.SomeImpossibleValue(benign=True)
return annmodel.SomeImpossibleValue()
def reflowfromposition(self, position_key):
@@ -354,19 +354,32 @@
and issubclass(link.exitcase, Exception):
last_exception_object = annmodel.SomeObject()
last_exc_value_object = annmodel.SomeObject()
- last_exc_value_vars = last_exception_object.is_type_of = []
+ last_exc_value_vars = []
in_except_block = True
+ last_exception_unknown = True
+ last_exception_unused = True
cells = []
renaming = dict(zip(link.args,link.target.inputargs))
for a,v in zip(link.args,link.target.inputargs):
if a == Constant(last_exception):
assert in_except_block
+ assert last_exception_unknown
cells.append(last_exception_object)
+ last_exception_unused = False
elif a == Constant(last_exc_value):
assert in_except_block
cells.append(last_exc_value_object)
last_exc_value_vars.append(v)
+ elif isinstance(a, Constant) and a.has_flag('last_exception'):
+ assert in_except_block
+ assert last_exception_unused
+ if last_exception_unknown:
+ cell = last_exception_object = self.bookkeeper.immutablevalue(a.value)
+ else:
+ cell = last_exception_object
+ cells.append(cell)
+ last_exception_unknown = False
else:
cell = self.binding(a)
if link.exitcase is True and knownvars is not None and a in knownvars \
@@ -382,6 +395,9 @@
cell.is_type_of = renamed_is_type_of
cells.append(cell)
+ if in_except_block:
+ last_exception_object.is_type_of = last_exc_value_vars
+
self.addpendingblock(fn, link.target, cells)
if block in self.notify:
# reflow from certain positions when this block is done
Modified: pypy/dist/pypy/translator/test/snippet.py
==============================================================================
--- pypy/dist/pypy/translator/test/snippet.py (original)
+++ pypy/dist/pypy/translator/test/snippet.py Fri Feb 25 16:38:27 2005
@@ -729,6 +729,10 @@
def m(self):
return 1
+class Exc4(Exc3):
+ def m(self):
+ return 1
+
class Sp:
def o(self):
raise Exc3
@@ -745,11 +749,33 @@
return e.m()
return 0
+class Mod3:
+ def __init__(self, s):
+ self.s = s
+
+ def p(self):
+ s = self.s
+ try:
+ s.o()
+ except Exc4, e1:
+ return e1.m()
+ except Exc3, e2:
+ try:
+ return e2.m()
+ except Exc4, e3:
+ return e3.m()
+ return 0
+
+
mod = Mod(Sp())
+mod3 = Mod3(Sp())
def exc_deduction_our_exc_plus_others():
return mod.p()
+def exc_deduction_our_excs_plus_others():
+ return mod3.p()
+
class BltinCode:
def __init__(self, func, framecls):
Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py (original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py Fri Feb 25 16:38:27 2005
@@ -115,12 +115,10 @@
assert s.knowntype == int
def test_lists(self):
- fun = self.make_fun(snippet.poor_man_rev_range)
a = RPythonAnnotator()
- a.build_types(fun, [int])
+ end_cell = a.build_types(snippet.poor_man_rev_range, [int])
# result should be a list of integers
- assert a.gettype(fun.getreturnvar()) == list
- end_cell = a.binding(fun.getreturnvar())
+ assert end_cell.knowntype == list
assert end_cell.s_item.knowntype == int
def test_factorial(self):
@@ -489,6 +487,11 @@
s = a.build_types(snippet.exc_deduction_our_exc_plus_others, [])
assert isinstance(s, annmodel.SomeInteger)
+ def test_exc_deduction_our_excs_plus_others(self):
+ a = RPythonAnnotator()
+ s = a.build_types(snippet.exc_deduction_our_excs_plus_others, [])
+ assert isinstance(s, annmodel.SomeInteger)
+
def test_slice_union(self):
a = RPythonAnnotator()
s = a.build_types(snippet.slice_union, [int])
Modified: pypy/dist/pypy/translator/test/test_pyrextrans.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_pyrextrans.py (original)
+++ pypy/dist/pypy/translator/test/test_pyrextrans.py Fri Feb 25 16:38:27 2005
@@ -108,8 +108,7 @@
class TestTypedTestCase:
def getcompiled(self, func):
- t = Translator(func)
- t.simplify()
+ t = Translator(func, simplifying=True)
# builds starting-types from func_defs
argstypelist = []
if func.func_defaults:
Modified: pypy/dist/pypy/translator/tool/make_dot.py
==============================================================================
--- pypy/dist/pypy/translator/tool/make_dot.py (original)
+++ pypy/dist/pypy/translator/tool/make_dot.py Fri Feb 25 16:38:27 2005
@@ -137,7 +137,11 @@
shape = "octagon"
iargs = " ".join(map(repr, block.inputargs))
- data = "%s(%s)\\ninputargs: %s\\n\\n" % (name, block.__class__.__name__, iargs)
+ if block.exc_handler:
+ eh = 'EH'
+ else:
+ eh = ''
+ data = "%s(%s %s)\\ninputargs: %s\\n\\n" % (name, block.__class__.__name__, eh, iargs)
if block.operations and self.func:
maxoffs = max([op.offset for op in block.operations])
if maxoffs >= 0:
More information about the Pypy-commit
mailing list