[pypy-svn] rev 1278 - in pypy/branch/builtinrefactor/pypy: interpreterinterpreter/test objspace
arigo at codespeak.net
arigo at codespeak.net
Tue Sep 9 21:38:31 CEST 2003
Author: arigo
Date: Tue Sep 9 21:38:29 2003
New Revision: 1278
Added:
pypy/branch/builtinrefactor/pypy/interpreter/generator.py
Modified:
pypy/branch/builtinrefactor/pypy/interpreter/function.py
pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py
pypy/branch/builtinrefactor/pypy/interpreter/pycode.py
pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py
pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py
pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py
pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py
pypy/branch/builtinrefactor/pypy/objspace/trivial.py
Log:
interpreter tests working again
Modified: pypy/branch/builtinrefactor/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/function.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/function.py Tue Sep 9 21:38:29 2003
@@ -25,7 +25,8 @@
def call(self, w_args, w_kwds=None):
scope_w = self.parse_args(w_args, w_kwds)
- frame = self.func_code.create_frame(self.space, self.w_globals)
+ frame = self.func_code.create_frame(self.space, self.w_globals,
+ self.closure)
frame.setfastscope(scope_w)
return frame.run()
Added: pypy/branch/builtinrefactor/pypy/interpreter/generator.py
==============================================================================
--- (empty file)
+++ pypy/branch/builtinrefactor/pypy/interpreter/generator.py Tue Sep 9 21:38:29 2003
@@ -0,0 +1,88 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import NoValue
+from pypy.interpreter.eval import Frame
+from pypy.interpreter.pyframe import ControlFlowException, ExitFrame
+
+#
+# Generator support. Note that GeneratorFrame is not a subclass of PyFrame.
+# PyCode objects use a custom subclass of both PyFrame and GeneratorFrame
+# when they need to interpret Python bytecode that is a generator.
+# Otherwise, GeneratorFrame could also be used to define, say,
+# built-in generators (which are usually done in CPython as functions
+# that return iterators).
+#
+
+class GeneratorFrame(Frame):
+ "A frame attached to a generator."
+
+ def run(self):
+ "Build a generator-iterator."
+ self.exhausted = False
+ return GeneratorIterator(self)
+
+ ### extra opcodes ###
+
+ # XXX mmmh, GeneratorFrame is supposed to be independent from
+ # Python bytecode... Well, it is. These are not used when
+ # GeneratorFrame is used with other kinds of Code subclasses.
+
+ def RETURN_VALUE(f): # overridden
+ raise SGeneratorReturn()
+
+ def YIELD_VALUE(f):
+ w_yieldedvalue = f.valuestack.pop()
+ raise SYieldValue(w_yieldedvalue)
+ YIELD_STMT = YIELD_VALUE # misnamed in old versions of dis.opname
+
+
+class GeneratorIterator(object):
+ "An iterator created by a generator."
+
+ def __init__(self, frame):
+ self.frame = frame
+ self.running = False
+
+ def nextvalue(self):
+ # raise NoValue when exhausted
+ if self.running:
+ space = self.frame.space
+ raise OperationError(space.w_ValueError,
+ space.wrap('generator already executing'))
+ if self.frame.exhausted:
+ raise NoValue
+ self.running = True
+ try:
+ return Frame.run(self.frame)
+ finally:
+ self.running = False
+
+
+ # XXX trick for trivialobjspace
+ # XXX make these __iter__() and next() app-visible
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ # XXX trivialobjspace only !!
+ try:
+ return self.nextvalue()
+ except NoValue:
+ raise StopIteration
+
+#
+# the specific ControlFlowExceptions used by generators
+#
+
+class SYieldValue(ControlFlowException):
+ """Signals a 'yield' statement.
+ Argument is the wrapped object to return."""
+ def action(self, frame, last_instr, executioncontext):
+ w_yieldvalue = self.args[0]
+ raise ExitFrame(w_yieldvalue)
+
+class SGeneratorReturn(ControlFlowException):
+ """Signals a 'return' statement inside a generator."""
+ def emptystack(self, frame):
+ frame.exhausted = True
+ raise NoValue
Modified: pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py Tue Sep 9 21:38:29 2003
@@ -1,3 +1,4 @@
+from pypy.interpreter.error import OperationError
from pypy.interpreter.eval import UNDEFINED
from pypy.interpreter.pyopcode import PyInterpFrame
@@ -56,6 +57,7 @@
raise OperationError(space.w_TypeError,
"directly executed code object "
"may not contain free variables")
+ closure = []
else:
if len(closure) != nfreevars:
raise ValueError("code object received a closure with "
@@ -88,7 +90,7 @@
cell.set(w_value)
def setfastscope(self, scope_w):
- PyInterpFrame.setfastscope(scope_w)
+ PyInterpFrame.setfastscope(self, scope_w)
if self.code.co_cellvars:
# the first few cell vars could shadow already-set arguments,
# in the same order as they appear in co_varnames
@@ -158,10 +160,9 @@
nfreevars = len(codeobj.co_freevars)
freevars = [f.valuestack.pop() for i in range(nfreevars)]
freevars.reverse()
- w_freevars = f.space.newtuple(freevars)
defaultarguments = [f.valuestack.pop() for i in range(numdefaults)]
defaultarguments.reverse()
w_defaultarguments = f.space.newtuple(defaultarguments)
w_func = f.space.newfunction(f.space.unwrap(w_codeobj),
- f.w_globals, w_defaultarguments, w_freevars)
+ f.w_globals, w_defaultarguments, freevars)
f.valuestack.push(w_func)
Modified: pypy/branch/builtinrefactor/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pycode.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pycode.py Tue Sep 9 21:38:29 2003
@@ -60,11 +60,14 @@
def create_frame(self, space, w_globals, closure=None):
"Create an empty PyFrame suitable for this code object."
# select the appropriate kind of frame
+ from pypy.interpreter.pyopcode import PyInterpFrame as Frame
if self.co_cellvars or self.co_freevars:
from pypy.interpreter.nestedscope import PyNestedScopeFrame as F
- else:
- from pypy.interpreter.pyopcode import PyInterpFrame as F
- return F(space, self, w_globals, closure)
+ Frame = enhanceclass(Frame, F)
+ if self.co_flags & CO_GENERATOR:
+ from pypy.interpreter.generator import GeneratorFrame as F
+ Frame = enhanceclass(Frame, F)
+ return Frame(space, self, w_globals, closure)
def signature(self):
"([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)."
@@ -85,10 +88,23 @@
def getvarnames(self):
return self.co_varnames
- def is_generator(self):
- return self.co_flags & CO_GENERATOR
-
def dictscope_needed(self):
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
# class bodies only have CO_NEWLOCALS.
return not (self.co_flags & CO_OPTIMIZED)
+
+
+def enhanceclass(baseclass, newclass, cache={}):
+ # this is a bit too dynamic for RPython, but it looks nice
+ # and I assume that we can easily change it into a static
+ # pre-computed table
+ if issubclass(newclass, baseclass):
+ return newclass
+ else:
+ try:
+ return cache[baseclass, newclass]
+ except KeyError:
+ class Mixed(newclass, baseclass):
+ pass
+ cache[baseclass, newclass] = Mixed
+ return Mixed
Modified: pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py Tue Sep 9 21:38:29 2003
@@ -265,15 +265,6 @@
"""Signals a 'return' statement.
Argument is the wrapped object to return."""
def emptystack(self, frame):
- if frame.code.is_generator():
- raise baseobjspace.NoValue
- w_returnvalue = self.args[0]
- raise ExitFrame(w_returnvalue)
-
-class SYieldValue(ControlFlowException):
- """Signals a 'yield' statement.
- Argument is the wrapped object to return."""
- def action(self, frame, last_instr, executioncontext):
w_returnvalue = self.args[0]
raise ExitFrame(w_returnvalue)
Modified: pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py Tue Sep 9 21:38:29 2003
@@ -312,11 +312,6 @@
w_returnvalue = f.valuestack.pop()
raise pyframe.SReturnValue(w_returnvalue)
- def YIELD_VALUE(f):
- w_yieldedvalue = f.valuestack.pop()
- raise pyframe.SYieldValue(w_yieldedvalue)
- YIELD_STMT = YIELD_VALUE # misnamed in dis.opname
-
def EXEC_STMT(f):
w_locals = f.valuestack.pop()
w_globals = f.valuestack.pop()
Modified: pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py Tue Sep 9 21:38:29 2003
@@ -19,9 +19,9 @@
w_tempmodule = space.newmodule(w("__temp__"))
w_glob = space.getattr(w_tempmodule, w("__dict__"))
space.setitem(w_glob, w("__builtins__"), space.w_builtins)
-
- scopedcode = gateway.ScopedCode(space, space.unwrap(w_code), w_glob)
- scopedcode.eval_frame()
+
+ code = space.unwrap(w_code)
+ code.exec_code(space, w_glob, w_glob)
wrappedargs = w(args)
wrappedfunc = space.getitem(w_glob, w(functionname))
Modified: pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py (original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py Tue Sep 9 21:38:29 2003
@@ -68,7 +68,8 @@
def f(x):
return x
- cpycode = f.func_code
+ from pypy.interpreter.pycode import PyCode
+ cpycode = PyCode()._from_code(f.func_code)
w_globals = self.space.newdict([])
w_defs = self.space.newtuple([])
w_f = self.space.newfunction(cpycode, w_globals, w_defs)
Modified: pypy/branch/builtinrefactor/pypy/objspace/trivial.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/trivial.py (original)
+++ pypy/branch/builtinrefactor/pypy/objspace/trivial.py Tue Sep 9 21:38:29 2003
@@ -157,7 +157,9 @@
#ec = self.getexecutioncontext() # .framestack.items[-1]
#ec.print_detailed_traceback(self)
- etype, evalue = sys.exc_info()[:2]
+ etype, evalue, etb = sys.exc_info()
+ if etype is OperationError:
+ raise etype, evalue, etb # just re-raise it
name = etype.__name__
if hasattr(self, 'w_' + name):
nt = getattr(self, 'w_' + name)
@@ -171,7 +173,7 @@
else:
nt = etype
nv = evalue
- raise OperationError(nt, nv)
+ raise OperationError, OperationError(nt, nv), etb
def _auto(name, sourcefn, classlocals):
s = """
More information about the Pypy-commit
mailing list