[pypy-commit] lang-smalltalk default: refactored the interpreter to use the c stack when building contexts
lwassermann
noreply at buildbot.pypy.org
Fri Mar 1 17:58:30 CET 2013
Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch:
Changeset: r112:785411941697
Date: 2013-03-01 17:52 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/785411941697/
Log: refactored the interpreter to use the c stack when building contexts
there is (at least one) problem with the jit generation.
Unfortunately, the error message is too cryptic and websearch does
not help
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -26,16 +26,19 @@
_w_last_active_context = None
cnt = 0
_last_indent = ""
+ _loop = True
jit_driver = jit.JitDriver(
greens=['pc', 'self', 'method'],
reds=['s_active_context'],
get_printable_location=get_printable_location
)
- def __init__(self, space, image=None, image_name=""):
+ def __init__(self, space, image=None, image_name="", max_stack_depth=500):
self.space = space
self.image = image
self.image_name = image_name
+ self.max_stack_depth = max_stack_depth
+ self._loop = False
def interpret_with_w_frame(self, w_frame):
try:
@@ -79,6 +82,7 @@
return bytecodeimpl(s_active_context, self, next)
def loop(self, w_active_context):
+ self._loop = True
s_active_context = w_active_context.as_context_get_shadow(self.space)
while True:
pc = s_active_context._pc
@@ -87,8 +91,12 @@
self.jit_driver.jit_merge_point(
pc=pc, self=self, method=method,
s_active_context=s_active_context)
- w_new_context = self.step(s_active_context)
+ try:
+ w_new_context = self.step(s_active_context)
+ except StackOverflow, e:
+ w_new_context = e.w_context
if w_new_context is not None:
+ # we return to the context mentioned -> mark all contexts in between as mark_returned
s_active_context = w_new_context.as_context_get_shadow(self.space)
def perform(self, w_receiver, selector, *arguments_w):
@@ -117,11 +125,49 @@
except ReturnFromTopLevel, e:
return e.object
+ def stack_frame(self, w_new_frame):
+ if not self._loop:
+ return w_new_frame # this test is done to not loop in test,
+ # but rather step just once where wanted
+ if self.max_stack_depth == 1:
+ raise StackOverflow(w_new_frame)
+ #method = s_active_context.w_method()
+ #print method.get_identifier_string()
+ interp = StackedInterpreter(self.space, self.image, self.image_name,
+ self.max_stack_depth - 1)
+ return interp.loop(w_new_frame)
+
+class StackedInterpreter(Interpreter):
+ def __init__(self, space, image, image_name, max_stack_depth):
+ self.space = space
+ self.image = image
+ self.image_name = image_name
+ self.max_stack_depth = max_stack_depth
+
+ def loop(self, w_active_context):
+ s_active_context = w_active_context.as_context_get_shadow(self.space)
+ while True:
+ pc = s_active_context._pc
+ method = s_active_context.method()
+
+ self.jit_driver.jit_merge_point(
+ pc=pc, self=self, method=method,
+ s_active_context=s_active_context)
+ w_return_to_context = self.step(s_active_context)
+ if (w_return_to_context is not None
+ and w_return_to_context is not w_active_context):
+ assert w_return_to_context._shadow._w_sender is not w_active_context
+ w_active_context.as_context_get_shadow(self.space).mark_returned()
+ return w_return_to_context
class ReturnFromTopLevel(Exception):
def __init__(self, object):
self.object = object
+class StackOverflow(Exception):
+ def __init__(self, w_top_context):
+ self.w_context = w_top_context
+
def make_call_primitive_bytecode(primitive, selector, argcount):
def callPrimitive(self, interp, current_bytecode):
# WARNING: this is used for bytecodes for which it is safe to
@@ -277,9 +323,9 @@
w_frame = s_method.create_frame(self.space, receiver, arguments,
self.w_self())
self.pop()
- return w_frame
+ return interp.stack_frame(w_frame)
- def _return(self, object, interp, w_return_to):
+ def _return(self, return_value, interp, w_return_to):
# for tests, when returning from the top-level context
if w_return_to.is_same_object(self.space.w_nil):
raise ReturnFromTopLevel(return_value)
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -67,7 +67,7 @@
def wrapped(interp, s_frame, argument_count_m1):
w_result = func(interp, s_frame, argument_count_m1)
if result_is_new_frame:
- return w_result
+ return interp.stack_frame(w_result)
if not no_result:
assert w_result is not None
s_frame.push(w_result)
@@ -110,7 +110,7 @@
# needs to be updated
s_frame.pop_n(len_unwrap_spec) # only if no exception occurs!
if result_is_new_frame:
- return w_result
+ return interp.stack_frame(w_result)
elif not no_result:
assert w_result is not None
s_frame.push(w_result)
diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py
--- a/spyvm/test/test_bootstrappedimage.py
+++ b/spyvm/test/test_bootstrappedimage.py
@@ -50,7 +50,7 @@
# we can't find PCSystem, because Smalltalkdict is nil...
import time
t0 = time.time()
- sends = perform(w(20), 'benchFib')
+ sends = perform(w(5), 'benchFib')
t1 = time.time()
t = t1 - t0
print str(tools.space.unwrap_int(sends)/t) + " sends per second"
\ No newline at end of file
diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py
--- a/spyvm/test/test_interpreter.py
+++ b/spyvm/test/test_interpreter.py
@@ -6,6 +6,9 @@
space = objspace.ObjSpace()
interp = interpreter.Interpreter(space)
+def step_in_interp(ctxt): # due to missing resets in between tests
+ interp._loop = False
+ return interp.step(ctxt)
# expose the bytecode's values as global constants.
# Bytecodes that have a whole range are exposed as global functions:
@@ -122,12 +125,12 @@
def test_unknownBytecode():
w_frame, s_frame = new_frame(unknownBytecode)
- py.test.raises(interpreter.MissingBytecode, interp.step, s_frame)
+ py.test.raises(interpreter.MissingBytecode, step_in_interp, s_frame)
# push bytecodes
def test_pushReceiverBytecode():
w_frame, s_frame = new_frame(pushReceiverBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.top().is_same_object(
s_frame.w_receiver())
@@ -140,9 +143,9 @@
w_demo.store(space, 2, "baz")
w_frame, s_frame = new_frame(bytecode, receiver = w_demo)
s_frame = w_frame.as_context_get_shadow(space)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == ["egg", "bar", "baz"]
def test_pushTemporaryVariableBytecode(bytecode=(pushTemporaryVariableBytecode(0) +
@@ -151,9 +154,9 @@
w_frame, s_frame = new_frame(bytecode)
s_frame = w_frame.as_context_get_shadow(space)
s_frame.settemp(2, "temp")
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == ["foo", "bar", "temp"]
def test_pushLiteralConstantBytecode(bytecode=pushLiteralConstantBytecode(0) +
@@ -161,9 +164,9 @@
pushLiteralConstantBytecode(2)):
w_frame, s_frame = new_frame(bytecode)
s_frame.w_method().setliterals(fakeliterals(space, "a", "b", "c"))
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == [fakesymbol("a"),
fakesymbol("b"),
fakesymbol("c")]
@@ -174,7 +177,7 @@
w_association.store(space, 1, "myvalue")
w_frame, s_frame = new_frame(bytecode)
s_frame.w_method().setliterals( fakeliterals(space, w_association))
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == ["myvalue"]
def test_storeAndPopReceiverVariableBytecode(bytecode=storeAndPopReceiverVariableBytecode,
@@ -184,8 +187,8 @@
w_object = shadow.new()
w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index))
s_frame.store_w_receiver(w_object)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
if popped:
assert s_frame.stack() == []
else:
@@ -201,8 +204,8 @@
for index in range(8):
w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index))
#s_frame.temps = [None] * 8
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == []
for test_index in range(8):
print w_frame._vars
@@ -213,141 +216,141 @@
def test_pushConstantTrueBytecode():
w_frame, s_frame = new_frame(pushConstantTrueBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_true)
assert s_frame.stack() == []
def test_pushConstantFalseBytecode():
w_frame, s_frame = new_frame(pushConstantFalseBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_false)
assert s_frame.stack() == []
def test_pushConstantNilBytecode():
w_frame, s_frame = new_frame(pushConstantNilBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_nil)
assert s_frame.stack() == []
def test_pushConstantMinusOneBytecode():
w_frame, s_frame = new_frame(pushConstantMinusOneBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_minus_one)
assert s_frame.stack() == []
def test_pushConstantZeroBytecode():
w_frame, s_frame = new_frame(pushConstantZeroBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_zero)
assert s_frame.stack() == []
def test_pushConstantOneBytecode():
w_frame, s_frame = new_frame(pushConstantOneBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_one)
assert s_frame.stack() == []
def test_pushConstantTwoBytecode():
w_frame, s_frame = new_frame(pushConstantTwoBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().is_same_object(space.w_two)
assert s_frame.stack() == []
def test_pushActiveContextBytecode():
w_frame, s_frame = new_frame(pushActiveContextBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop() == w_frame
assert s_frame.stack() == []
def test_duplicateTopBytecode():
w_frame, s_frame = new_frame(pushConstantZeroBytecode + duplicateTopBytecode)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == [space.w_zero, space.w_zero]
def test_bytecodePrimBitAnd():
w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == 0
assert s_frame.stack() == []
def test_bytecodePrimBitOr():
w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == 3
assert s_frame.stack() == []
def test_bytecodePrimBitShift():
w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == 4
assert s_frame.stack() == []
def test_bytecodePrimClass():
w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecodePrimClass)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop() == space.w_SmallInteger
assert s_frame.stack() == []
def test_bytecodePrimSubtract():
w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == -1
assert s_frame.stack() == []
def test_bytecodePrimMultiply():
w_frame, s_frame = new_frame(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == -2
assert s_frame.stack() == []
def test_bytecodePrimDivide():
w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == -2
assert s_frame.stack() == []
def test_bytecodePrimDiv():
w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == -2
assert s_frame.stack() == []
def test_bytecodePrimMod():
w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop().value == 0
assert s_frame.stack() == []
def test_bytecodePrimEquivalent():
w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop() == space.w_false
assert s_frame.stack() == []
w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pop() == space.w_true
assert s_frame.stack() == []
@@ -359,7 +362,7 @@
s_frame.push(w_fakeclass)
run_with_faked_primitive_methods(
[[w_fakeclassclass, primitives.NEW, 0, "new"]],
- interp.step,
+ step_in_interp,
s_frame)
w_fakeinst = s_frame.pop()
assert s_frame.stack() == []
@@ -375,7 +378,7 @@
s_frame.push(space.w_two)
run_with_faked_primitive_methods(
[[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]],
- interp.step,
+ step_in_interp,
s_frame)
w_fakeinst = s_frame.pop()
assert s_frame.stack() == []
@@ -389,7 +392,7 @@
s_frame.push(w_fakeinst)
run_with_faked_primitive_methods(
[[w_fakeclass, primitives.SIZE, 0, "size"]],
- interp.step,
+ step_in_interp,
s_frame)
assert s_frame.pop().value == 5
assert s_frame.stack() == []
@@ -413,15 +416,15 @@
w_frame, s_frame = new_frame(bytecodes)
s_frame.w_method().setliterals(literals)
s_frame.push(w_object)
- w_active_context = interp.step(s_frame)
+ w_active_context = step_in_interp(s_frame)
s_active_context = w_active_context.as_context_get_shadow(space)
assert s_active_context.w_sender() == w_frame
assert s_active_context.stack() == []
assert w_active_context.as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object)
assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo])
assert s_frame.stack() == []
- interp.step(s_active_context)
- w_active_context = interp.step(s_active_context)
+ step_in_interp(s_active_context)
+ w_active_context = step_in_interp(s_active_context)
s_active_context = w_active_context.as_context_get_shadow(space)
assert w_active_context == w_frame
assert s_active_context.stack() == [result]
@@ -457,7 +460,7 @@
s_frame.w_method().setliterals(fakeliterals(space, "foo", "-"))
s_frame.push(space.wrap_int(50))
s_frame.push(space.wrap_int(8))
- w_new_frame = interp.step(s_frame)
+ w_new_frame = step_in_interp(s_frame)
assert w_new_frame is None
assert len(s_frame.stack()) == 1
w_result = s_frame.pop()
@@ -472,9 +475,9 @@
w_frame, s_frame = new_frame(pushConstantZeroBytecode +
pushConstantOneBytecode +
bytecodePrimMakePoint)
- interp.step(s_frame)
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
w_point = s_frame.top()
from spyvm.wrapper import PointWrapper
point = PointWrapper(interp.space, w_point)
@@ -485,55 +488,55 @@
w_frame, s_frame = new_frame(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15))
s_frame.push(space.w_false)
pc = s_frame.pc() + 2
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc
s_frame.push(space.w_true)
pc = s_frame.pc() + 2
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 15
def test_longJumpIfFalse():
w_frame, s_frame = new_frame(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) +
pushConstantFalseBytecode + longJumpIfFalse(0) + chr(15))
- interp.step(s_frame)
+ step_in_interp(s_frame)
pc = s_frame.pc() + 2
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc
- interp.step(s_frame)
+ step_in_interp(s_frame)
pc = s_frame.pc() + 2
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 15
def test_longUnconditionalJump():
w_frame, s_frame = new_frame(longUnconditionalJump(4) + chr(15))
pc = s_frame.pc() + 2
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 15
def test_shortUnconditionalJump():
w_frame, s_frame = new_frame(chr(145))
pc = s_frame.pc() + 1
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 2
def test_shortConditionalJump():
w_frame, s_frame = new_frame(pushConstantTrueBytecode + shortConditionalJump(3) +
pushConstantFalseBytecode + shortConditionalJump(3))
- interp.step(s_frame)
+ step_in_interp(s_frame)
pc = s_frame.pc() + 1
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc
- interp.step(s_frame)
+ step_in_interp(s_frame)
pc = s_frame.pc() + 1
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 4
def test_popStackBytecode():
w_frame, s_frame = new_frame(pushConstantTrueBytecode +
popStackBytecode)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == [space.w_true]
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == []
def test_extendedPushBytecode():
@@ -557,8 +560,8 @@
w_association.store(space, 1, "myvalue")
w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecode)
s_frame.w_method().setliterals(fakeliterals(space, w_association))
- interp.step(s_frame)
- interp.step(s_frame)
+ step_in_interp(s_frame)
+ step_in_interp(s_frame)
assert w_association.fetch(space, 1).is_same_object(space.w_one)
def test_extendedStoreAndPopBytecode():
@@ -587,7 +590,7 @@
w_object = shadow.new()
s_frame.push(w_object)
s_frame.push(space.w_one)
- w_active_context = interp.step(s_frame)
+ w_active_context = step_in_interp(s_frame)
s_active_context = w_active_context.as_context_get_shadow(space)
assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol]
assert s_active_context.w_receiver() is w_object
@@ -604,7 +607,7 @@
for i in range(6):
s_frame.push(space.w_one)
s_frame.push(space.w_two)
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.stack() == [space.w_true, space.w_false,
space.w_true, space.w_false,
space.w_false, space.w_true]
@@ -638,13 +641,13 @@
w_frame, s_frame = new_frame(bytecodes)
s_frame.w_method().setliterals(literals)
s_frame.push(w_object)
- w_active_context = interp.step(s_frame)
+ w_active_context = step_in_interp(s_frame)
s_active_context = w_active_context.as_context_get_shadow(space)
for w_specificclass in [w_super, w_supersuper]:
w_caller_context = w_active_context
s_caller_context = s_active_context
- interp.step(s_active_context)
- w_active_context = interp.step(s_active_context)
+ step_in_interp(s_active_context)
+ w_active_context = step_in_interp(s_active_context)
s_active_context = w_active_context.as_context_get_shadow(space)
assert s_active_context.w_sender() == w_caller_context
assert s_active_context.stack() == []
@@ -755,12 +758,13 @@
#
# [ :a :b | a - b ] valueWithArguments: #(3 2)
def test():
- assert interpret_bc(
+ val = interpret_bc(
[ 137, 119, 200, 164, 6,
105, 104, 16, 17, 177,
125, 33, 224, 124 ],
fakeliterals(space, "valueWithArguments:",
- [3, 2])).value == 1
+ [3, 2]))
+ assert val.value == 1
run_with_faked_primitive_methods(
[[space.w_BlockContext, primitives.VALUE_WITH_ARGS,
1, "valueWithArguments:"]],
@@ -856,7 +860,7 @@
s_frame.push(fakeliterals(space, "egg"))
s_frame.push(fakeliterals(space, "bar"))
s_frame.push(fakeliterals(space, "baz"))
- interp.step(s_frame)
+ step_in_interp(s_frame)
array = s_frame.pop()
assert array.at0(space, 0) == fakeliterals(space, "egg")
assert array.at0(space, 1) == fakeliterals(space, "bar")
@@ -864,7 +868,7 @@
def test_bc_pushNewArray(bytecode=pushNewArrayBytecode):
w_frame, s_frame = new_frame(bytecode + chr(0x07))
- interp.step(s_frame)
+ step_in_interp(s_frame)
array = s_frame.pop()
assert array.size() == 7
assert array.at0(space, 0) == space.w_nil
@@ -872,7 +876,7 @@
def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode):
w_frame, s_frame = new_frame(bytecode + chr(0) + chr(0))
s_frame.settemp(0, space.w_Array.as_class_get_shadow(interp.space).new(2))
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.top() == space.w_nil
def setupTempArrayAndContext(bytecode):
@@ -883,7 +887,7 @@
temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3)
temp_array.atput0(space, 2, fakeliterals(space, "pub"))
s_frame.settemp(1, temp_array)
- interp.step(s_frame)
+ step_in_interp(s_frame)
return s_frame, temp_array
def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode):
@@ -905,7 +909,7 @@
w_frame, s_frame = new_frame(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF))
pc = s_frame.pc()
# create/find a method with an appropriate blockClosure
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 4 + i
closure = wrapper.BlockClosureWrapper(space, s_frame.top())
assert closure.startpc() == pc + 4
@@ -916,7 +920,7 @@
s_frame.push("english")
s_frame.push("bar")
pc = s_frame.pc()
- interp.step(s_frame)
+ step_in_interp(s_frame)
assert s_frame.pc() == pc + 4
closure = wrapper.BlockClosureWrapper(space, s_frame.top())
assert closure.startpc() == pc + 4
@@ -949,3 +953,40 @@
[[space.w_BlockClosure, primitives.CLOSURE_VALUE_VALUE,
2, "value:value:"]],
test)
+
+def test_stacking_interpreter():
+ # | testBlock |
+ # testBlock := [ :aNumber |
+ # aNumber = 0
+ # ifTrue: [ 0 ]
+ # ifFalse: [ (testBlock value: aNumber - 1) + aNumber ]].
+ # ^ testBlock value: 11
+ import operator
+ interp = interpreter.Interpreter(space, max_stack_depth=2)
+ #create a method with the correct bytecodes and a literal
+ bytes = reduce(operator.add, map(chr, [0x8a, 0x01, 0x68, 0x10, 0x8f, 0x11,
+ 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x75, 0xa4, 0x09, 0x8c, 0x00, 0x01,
+ 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00,
+ 0x00, 0x20, 0xca, 0x7c]))
+ w_method = model.W_CompiledMethod(len(bytes))
+ w_method.islarge = 1
+ w_method.bytes = bytes
+ w_method.argsize=0
+ w_method.tempsize=1
+ w_method.setliterals([space.wrap_int(11)])
+
+ #create a frame for that method
+ w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), [])
+ try:
+ interp.loop(w_frame)
+ except interpreter.ReturnFromTopLevel, e:
+ assert space.unwrap_int(e.object) == 66
+ except interpreter.StackOverflow, e:
+ assert False
+ try:
+ interp = interpreter.StackedInterpreter(space, None, "", 10)
+ interp.loop(w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []))
+ except interpreter.StackOverflow, e:
+ assert e.w_context.getclass(space) is space.w_MethodContext
+ except interpreter.ReturnFromTopLevel, e:
+ assert False
\ No newline at end of file
More information about the pypy-commit
mailing list