[prev in list] [next in list] [prev in thread] [next in thread]
List: pypy-svn
Subject: [pypy-svn] rev 2225 - in pypy/trunk/src/pypy: interpreter
From: arigo () codespeak ! net
Date: 2003-11-19 16:51:49
Message-ID: 20031119165149.C83325A2D9 () thoth ! codespeak ! net
[Download RAW message or body]
Author: arigo
Date: Wed Nov 19 17:51:48 2003
New Revision: 2225
Modified:
pypy/trunk/src/pypy/interpreter/baseobjspace.py
pypy/trunk/src/pypy/interpreter/pyframe.py
pypy/trunk/src/pypy/objspace/flow/flowcontext.py
pypy/trunk/src/pypy/objspace/flow/model.py
pypy/trunk/src/pypy/objspace/flow/objspace.py
pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py
pypy/trunk/src/pypy/tool/test.py
pypy/trunk/src/pypy/translator/tool/make_dot.py
Log:
Exception support for the flow objspace.
M pypy/interpreter/pyframe.py
M pypy/interpreter/baseobjspace.py
M pypy/tool/test.py
Added a flag 'full_exceptions' in object spaces.
Allows FlowObjSpace to signal that it doesn't
really support all exception operations like
normalization and traceback printing.
M pypy/objspace/flow/model.py
M pypy/translator/tool/make_dot.py
FunctionGraphs now have additional 'end' blocks,
listed in the 'exceptblocks' dict, one per
possible exception class that it can raise.
M pypy/objspace/flow/test/test_objspace.py
M pypy/objspace/flow/flowcontext.py
M pypy/objspace/flow/objspace.py
The necessary logic.
The plan now is to have all operations tentatively raise exceptions like
KeyError, IndexError, OverflowError, so that they appear in the CFG; a later
simplification pass can apply the RPython specification that implicit uncaught
exceptions should not occur.
Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Wed Nov 19 17:51:48 2003
@@ -19,6 +19,8 @@
class ObjSpace:
"""Base class for the interpreter-level implementations of object spaces.
http://codespeak.net/moin/pypy/moin.cgi/ObjectSpace"""
+
+ full_exceptions = True # full support for exceptions (normalization & more)
def __init__(self):
"Basic initialization of objects."
@@ -157,15 +159,15 @@
# Match identical items.
if self.is_true(self.is_(w_exc_type, w_item)):
return True
- # Test within iterables (i.e. tuples)
try:
- exclst = self.unpackiterable(w_item)
- check_list.extend(exclst)
- except OperationError:
- # w_item is not iterable; it should then be an Exception.
# Match subclasses.
if self.is_true(self.issubtype(w_exc_type, w_item)):
return True
+ except OperationError:
+ # Assume that this is a TypeError: w_item not a type,
+ # and assume that w_item is then actually a tuple.
+ exclst = self.unpackiterable(w_item)
+ check_list.extend(exclst)
return False
def call_function(self, w_func, *args_w, **kw_w):
Modified: pypy/trunk/src/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyframe.py (original)
+++ pypy/trunk/src/pypy/interpreter/pyframe.py Wed Nov 19 17:51:48 2003
@@ -159,10 +159,11 @@
# push the exception to the value stack for inspection by the
# exception handler (the code after the except:)
operationerr = unroller.args[0]
- w_normalized = normalize_exception(frame.space,
- operationerr.w_type,
- operationerr.w_value)
- w_type, w_value = frame.space.unpacktuple(w_normalized, 2)
+ w_type = operationerr.w_type
+ w_value = operationerr.w_value
+ if frame.space.full_exceptions:
+ w_normalized = normalize_exception(frame.space, w_type, w_value)
+ w_type, w_value = frame.space.unpacktuple(w_normalized, 2)
# the stack setup is slightly different than in CPython:
# instead of the traceback, we store the unroller object,
# wrapped.
Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Wed Nov 19 17:51:48 2003
@@ -2,6 +2,7 @@
from pypy.interpreter.miscutils import Stack
from pypy.interpreter.pyframe \
import ControlFlowException, ExitFrame, PyFrame
+from pypy.interpreter.error import OperationError
from pypy.objspace.flow.model import *
from pypy.objspace.flow.framestate import FrameState
@@ -152,10 +153,16 @@
block.patchframe(frame, self)
except ExitFrame:
continue # restarting a dead SpamBlock
- w_result = frame.eval(self)
- if w_result is not None:
- link = Link([w_result], self.graph.returnblock)
+ try:
+ w_result = frame.eval(self)
+ except OperationError, e:
+ exc_type = self.space.unwrap(e.w_type) # e.w_value ignored
+ link = Link([], self.graph.getexceptblock(exc_type))
self.crnt_block.closeblock(link)
+ else:
+ if w_result is not None:
+ link = Link([w_result], self.graph.returnblock)
+ self.crnt_block.closeblock(link)
self.fixeggblocks()
def fixeggblocks(self):
Modified: pypy/trunk/src/pypy/objspace/flow/model.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/model.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/model.py Wed Nov 19 17:51:48 2003
@@ -13,12 +13,24 @@
self.returnblock = Block([return_var or Variable()])
self.returnblock.operations = ()
self.returnblock.exits = ()
+ self.exceptblocks = {} # Blocks corresponding to exception results
def getargs(self):
return self.startblock.inputargs
+
def getreturnvar(self):
return self.returnblock.inputargs[0]
+ def getexceptblock(self, exc_type):
+ try:
+ block = self.exceptblocks[exc_type]
+ except KeyError:
+ block = self.exceptblocks[exc_type] = Block([])
+ block.exc_type = exc_type
+ block.operations = ()
+ block.exits = ()
+ return block
+
class Link:
def __init__(self, args, target, exitcase=None):
assert len(args) == len(target.inputargs), "output args mismatch"
@@ -84,7 +96,7 @@
return hash(self.value)
def __repr__(self):
- return '%r' % (self.value,)
+ return '(%r)' % (self.value,)
class UndefinedConstant(Constant):
# for local variables not defined yet.
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 Wed Nov 19 17:51:48 2003
@@ -14,11 +14,17 @@
# ______________________________________________________________________
class FlowObjSpace(ObjSpace):
+ full_exceptions = False
+
def initialize(self):
import __builtin__
self.w_builtins = Constant(__builtin__.__dict__)
self.w_None = Constant(None)
- self.w_KeyError = Constant(KeyError)
+ self.w_False = Constant(False)
+ self.w_True = Constant(True)
+ for exc in [KeyError, ValueError]:
+ clsname = exc.__name__
+ setattr(self, 'w_'+clsname, Constant(exc))
#self.make_builtins()
#self.make_sys()
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 Wed Nov 19 17:51:48 2003
@@ -21,9 +21,8 @@
def reallyshow(self, x):
import os
- from pypy.translator.test.make_dot import make_dot
- from pypy.tool.udir import udir
- dest = make_dot(x, udir, 'ps')
+ from pypy.translator.tool.make_dot import make_dot
+ dest = make_dot(x.name, x)
os.system('gv %s' % str(dest))
def show(self, x):
@@ -159,6 +158,50 @@
x = self.codetest(self.break_continue)
self.show(x)
+ #__________________________________________________________
+ def unpack_tuple(lst):
+ a, b, c = lst
+
+ def test_unpack_tuple(self):
+ x = self.codetest(self.unpack_tuple)
+ self.show(x)
+
+ #__________________________________________________________
+ def reverse_3(lst):
+ try:
+ a, b, c = lst
+ except:
+ return 0, 0, 0
+ else:
+ return c, b, a
+
+ def test_reverse_3(self):
+ x = self.codetest(self.reverse_3)
+ self.show(x)
+
+ #__________________________________________________________
+ def finallys(lst):
+ x = 1
+ try:
+ x = 2
+ try:
+ x = 3
+ a, = lst
+ x = 4
+ except KeyError:
+ return 5
+ except ValueError:
+ return 6
+ b, = lst
+ x = 7
+ finally:
+ x = 8
+ return x
+
+ def test_finallys(self):
+ x = self.codetest(self.finallys)
+ self.show(x)
+
if __name__ == '__main__':
test.main()
Modified: pypy/trunk/src/pypy/tool/test.py
==============================================================================
--- pypy/trunk/src/pypy/tool/test.py (original)
+++ pypy/trunk/src/pypy/tool/test.py Wed Nov 19 17:51:48 2003
@@ -44,7 +44,7 @@
def addError(self, test, err):
# XXX not nice:
from pypy.interpreter.baseobjspace import OperationError
- if isinstance(err[1], OperationError):
+ if isinstance(err[1], OperationError) and test.space.full_exceptions:
if err[1].match(test.space, test.space.w_AssertionError):
self.addFailure(test, err)
return
@@ -58,7 +58,7 @@
def addError(self, test, err):
from pypy.interpreter.baseobjspace import OperationError
- if isinstance(err[1], OperationError):
+ if isinstance(err[1], OperationError) and test.space.full_exceptions:
if err[1].match(test.space, test.space.w_AssertionError):
self.addFailure(test, err)
return
@@ -121,7 +121,7 @@
self.stream.writeln(self.separator2)
t1 = self._exc_info_to_string(err)
t2 = ''
- if isinstance(err[1], OperationError):
+ if isinstance(err[1], OperationError) and test.space.full_exceptions:
t2 = '\nand at app-level:\n\n'
sio = StringIO.StringIO()
err[1].print_application_traceback(test.space, sio)
Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py
==============================================================================
--- pypy/trunk/src/pypy/translator/tool/make_dot.py (original)
+++ pypy/trunk/src/pypy/translator/tool/make_dot.py Wed Nov 19 17:51:48 2003
@@ -87,7 +87,7 @@
self.emit_node(name, label=data, shape="box", fillcolor="green", style="filled")
#('%(name)s [fillcolor="green", shape=box, label="%(data)s"];' % locals())
self.emit_edge(name, self.blockname(funcgraph.startblock), 'startblock')
- self.emit_edge(name, self.blockname(funcgraph.returnblock), 'returnblock', style="dashed")
+ #self.emit_edge(name, self.blockname(funcgraph.returnblock), 'returnblock', style="dashed")
def visit_Block(self, block):
# do the block itself
@@ -100,6 +100,8 @@
if not numblocks:
shape = "box"
fillcolor="green"
+ if hasattr(block, 'exc_type'):
+ lines.insert(0, 'exc_type: %s' % block.exc_type.__name__)
elif numblocks == 1:
shape = "box"
else:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic