[pypy-commit] pypy framestate: Split locals from stack in FlowContext - WIP
rlamy
noreply at buildbot.pypy.org
Thu Nov 20 01:34:21 CET 2014
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r74605:82688ed76170
Date: 2014-11-20 00:33 +0000
http://bitbucket.org/pypy/pypy/changeset/82688ed76170/
Log: Split locals from stack in FlowContext - WIP
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -278,6 +278,25 @@
"cmp_exc_match",
]
+class sliceview(object):
+ def __init__(self, lst, start, stop):
+ self.lst = lst
+ self.start = start
+ self.stop = stop
+
+ def __getitem__(self, n):
+ assert 0 <= self.start + n < self.stop
+ return self.lst[self.start + n]
+
+ def __setitem__(self, n, value):
+ assert 0 <= self.start + n < self.stop
+ self.lst[self.start + n] = value
+
+ def __delitem__(self, n):
+ assert 0 <= self.start + n < self.stop
+ del self.lst[self.start + n]
+
+
class FlowContext(object):
def __init__(self, graph, code):
self.graph = graph
@@ -301,63 +320,71 @@
self.closure = list(closure)
assert len(self.closure) == len(self.pycode.co_freevars)
+ @property
+ def locals_w(self):
+ return sliceview(self.locals_stack_w, 0, self.nlocals)
+
+ @property
+ def stack(self):
+ return sliceview(self.locals_stack_w, self.nlocals, len(self.locals_stack_w))
+
+ @property
+ def stackdepth(self):
+ assert self.valuestackdepth >= self.nlocals
+ return self.valuestackdepth - self.nlocals
+
+ @stackdepth.setter
+ def stackdepth(self, n):
+ assert 0 <= n <= self.stacksize
+ self.valuestackdepth = self.nlocals + n
+
def init_locals_stack(self, code):
"""
Initialize the locals and the stack.
The locals are ordered according to self.pycode.signature.
"""
- self.valuestackdepth = code.co_nlocals
+ self.nlocals = self.valuestackdepth = code.co_nlocals
+ self.stacksize = code.co_stacksize
self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals)
def pushvalue(self, w_object):
- depth = self.valuestackdepth
- self.locals_stack_w[depth] = w_object
- self.valuestackdepth = depth + 1
+ depth = self.stackdepth
+ self.stackdepth = depth + 1
+ self.stack[depth] = w_object
def popvalue(self):
- depth = self.valuestackdepth - 1
- assert depth >= self.pycode.co_nlocals, "pop from empty value stack"
- w_object = self.locals_stack_w[depth]
- self.locals_stack_w[depth] = None
- self.valuestackdepth = depth
+ depth = self.stackdepth - 1
+ w_object = self.stack[depth]
+ self.stack[depth] = None
+ self.stackdepth = depth
return w_object
def peekvalue(self, index_from_top=0):
# NOTE: top of the stack is peekvalue(0).
- index = self.valuestackdepth + ~index_from_top
- assert index >= self.pycode.co_nlocals, (
- "peek past the bottom of the stack")
- return self.locals_stack_w[index]
+ index = self.stackdepth + ~index_from_top
+ return self.stack[index]
def settopvalue(self, w_object, index_from_top=0):
- index = self.valuestackdepth + ~index_from_top
- assert index >= self.pycode.co_nlocals, (
- "settop past the bottom of the stack")
- self.locals_stack_w[index] = w_object
+ index = self.stackdepth + ~index_from_top
+ self.stack[index] = w_object
def popvalues(self, n):
values_w = [self.popvalue() for i in range(n)]
values_w.reverse()
return values_w
- def dropvalues(self, n):
- finaldepth = self.valuestackdepth - n
- for n in range(finaldepth, self.valuestackdepth):
- self.locals_stack_w[n] = None
- self.valuestackdepth = finaldepth
-
def dropvaluesuntil(self, finaldepth):
- for n in range(finaldepth, self.valuestackdepth):
- self.locals_stack_w[n] = None
- self.valuestackdepth = finaldepth
+ for n in range(finaldepth, self.stackdepth):
+ self.stack[n] = None
+ self.stackdepth = finaldepth
def save_locals_stack(self):
return self.locals_stack_w[:self.valuestackdepth]
def restore_locals_stack(self, items_w):
self.locals_stack_w[:len(items_w)] = items_w
- self.dropvaluesuntil(len(items_w))
+ self.dropvaluesuntil(len(items_w) - self.nlocals)
def getstate(self, next_offset):
# getfastscope() can return real None, for undefined locals
@@ -516,8 +543,8 @@
# hack for unrolling iterables, don't use this
def replace_in_stack(self, oldvalue, newvalue):
w_new = Constant(newvalue)
- stack_items_w = self.locals_stack_w
- for i in range(self.valuestackdepth - 1, self.pycode.co_nlocals - 1, -1):
+ stack_items_w = self.stack
+ for i in range(self.stackdepth - 1, - 1, -1):
w_v = stack_items_w[i]
if isinstance(w_v, Constant):
if w_v.value is oldvalue:
@@ -870,7 +897,7 @@
op.simple_call(w_exitfunc, w_None, w_None, w_None).eval(self)
def LOAD_FAST(self, varindex):
- w_value = self.locals_stack_w[varindex]
+ w_value = self.locals_w[varindex]
if w_value is None:
raise FlowingError("Local variable referenced before assignment")
self.pushvalue(w_value)
@@ -915,7 +942,7 @@
def STORE_FAST(self, varindex):
w_newvalue = self.popvalue()
assert w_newvalue is not None
- self.locals_stack_w[varindex] = w_newvalue
+ self.locals_w[varindex] = w_newvalue
if isinstance(w_newvalue, Variable):
w_newvalue.rename(self.getlocalvarname(varindex))
@@ -1128,11 +1155,11 @@
op.simple_call(w_append_meth, w_value).eval(self)
def DELETE_FAST(self, varindex):
- if self.locals_stack_w[varindex] is None:
+ if self.locals_w[varindex] is None:
varname = self.getlocalvarname(varindex)
message = "local variable '%s' referenced before assignment"
raise UnboundLocalError(message, varname)
- self.locals_stack_w[varindex] = None
+ self.locals_w[varindex] = None
def STORE_MAP(self, oparg):
w_key = self.popvalue()
@@ -1295,21 +1322,21 @@
def __init__(self, ctx, handlerposition):
self.handlerposition = handlerposition
- self.valuestackdepth = ctx.valuestackdepth
+ self.stackdepth = ctx.stackdepth
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.handlerposition == other.handlerposition and
- self.valuestackdepth == other.valuestackdepth)
+ self.stackdepth == other.stackdepth)
def __ne__(self, other):
return not (self == other)
def __hash__(self):
- return hash((self.handlerposition, self.valuestackdepth))
+ return hash((self.handlerposition, self.stackdepth))
def cleanupstack(self, ctx):
- ctx.dropvaluesuntil(self.valuestackdepth)
+ ctx.dropvaluesuntil(self.stackdepth)
def handle(self, ctx, unroller):
raise NotImplementedError
More information about the pypy-commit
mailing list