[pypy-commit] pypy translation-cleanup: Make sure that locals dict creation doesn't prevent translation
rlamy
noreply at buildbot.pypy.org
Thu Aug 30 18:38:23 CEST 2012
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: translation-cleanup
Changeset: r57003:120b233992e8
Date: 2012-08-16 02:42 +0100
http://bitbucket.org/pypy/pypy/changeset/120b233992e8/
Log: Make sure that locals dict creation doesn't prevent translation
* Copy some initialisation code down into FSFrame and simplify it.
* Add test.
diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -3,7 +3,9 @@
from pypy.interpreter.executioncontext import ExecutionContext
from pypy.interpreter.error import OperationError
from pypy.interpreter.pytraceback import PyTraceback
-from pypy.interpreter import pyframe, nestedscope
+from pypy.interpreter import pyframe
+from pypy.interpreter.nestedscope import Cell
+from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS
from pypy.interpreter.argument import ArgumentsForTranslation
from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller,
SReturnValue, SApplicationException, BytecodeCorruption, Reraise,
@@ -343,9 +345,9 @@
class outerfunc: pass # hack
if func.func_closure is not None:
cl = [c.cell_contents for c in func.func_closure]
- outerfunc.closure = [nestedscope.Cell(Constant(value)) for value in cl]
+ outerfunc.closure = [Cell(Constant(value)) for value in cl]
else:
- outerfunc.closure = None
+ outerfunc.closure = []
super(FlowSpaceFrame, self).__init__(space, code, w_globals, outerfunc)
self.last_instr = 0
@@ -357,6 +359,25 @@
arg_list[position] = Constant(value)
self.setfastscope(arg_list)
+ def initialize_frame_scopes(self, outer_func, code):
+ # CO_NEWLOCALS: make a locals dict unless optimized is also set
+ # CO_OPTIMIZED: no locals dict needed at all
+ flags = code.co_flags
+ if flags & CO_OPTIMIZED:
+ pass
+ elif flags & CO_NEWLOCALS:
+ self.w_locals = SpaceOperation('newdict', (), Variable()).result
+ else:
+ assert self.w_globals is not None
+ self.w_locals = self.w_globals
+ ncellvars = len(code.co_cellvars)
+ nfreevars = len(code.co_freevars)
+ closure_size = len(outer_func.closure)
+ if closure_size != nfreevars:
+ raise ValueError("code object received a closure with "
+ "an unexpected number of free variables")
+ self.cells = [Cell() for i in range(ncellvars)] + outer_func.closure
+
def _init_graph(self, func):
# CallableFactory.pycall may add class_ to functions that are methods
name = func.func_name
diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py
--- a/pypy/objspace/flow/objspace.py
+++ b/pypy/objspace/flow/objspace.py
@@ -302,9 +302,8 @@
# ____________________________________________________________
def do_operation(self, name, *args_w):
spaceop = SpaceOperation(name, args_w, Variable())
- if hasattr(self, 'executioncontext'): # not here during bootstrapping
- spaceop.offset = self.executioncontext.frame.last_instr
- self.executioncontext.recorder.append(spaceop)
+ spaceop.offset = self.executioncontext.frame.last_instr
+ self.executioncontext.recorder.append(spaceop)
return spaceop.result
def do_operation_with_implicit_exceptions(self, name, *args_w):
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -987,6 +987,15 @@
pass
py.test.raises(error.FlowingError, "self.codetest(f)")
+ def test_locals_dict(self):
+ def f():
+ x = 5
+ return x
+ exec "None"
+ graph = self.codetest(f)
+ assert len(graph.startblock.exits) == 1
+ assert graph.startblock.exits[0].target == graph.returnblock
+
class TestFlowObjSpaceDelay(Base):
def setup_class(cls):
More information about the pypy-commit
mailing list