Author: Lars Wassermann <[email protected]>
Branch:
Changeset: r57:c0ed35e84d1b
Date: 2013-02-19 13:24 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/c0ed35e84d1b/
Log: (lwassermann, cfbolz): implemented bytecode 143: pushBlockClosure
implemented BlockClosureWrapper
diff --git a/spyvm/constants.py b/spyvm/constants.py
--- a/spyvm/constants.py
+++ b/spyvm/constants.py
@@ -42,6 +42,9 @@
MTHDCTX_RECEIVER = 5
MTHDCTX_TEMP_FRAME_START = 6
+# BlockClosure < Object
+BLOCKCLOSURE_SIZE = 3
+
# ___________________________________________________________________________
# Miscellaneous constants
@@ -104,7 +107,7 @@
"Float" : SO_FLOAT_CLASS,
"MethodContext" : SO_METHODCONTEXT_CLASS,
"BlockContext" : SO_BLOCKCONTEXT_CLASS,
- # "BlockClosure" : SO_BLOCKCLOSURE_CLASS,
+ "BlockClosure" : SO_BLOCKCLOSURE_CLASS,
"Point" : SO_POINT_CLASS,
"LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS,
# "Display" : SO_DISPLAY_CLASS,
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -423,17 +423,26 @@
copiedValues: copiedValues).
self jump: blockSize
"""
+ space = self.space
numArgs, numCopied = splitter[4, 4](self.getbytecode())
j = self.getbytecode()
i = self.getbytecode()
blockSize = (j << 8) | i
- copiedValues = interp.space.w_nil
+ #create new instance of BlockClosure
+ BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space)
+ w_closure = BlockClosureShadow.new(numCopied)
+ closure = wrapper.BlockClosureWrapper(space, w_closure)
+ closure.store_outerContext(self._w_self)
+ closure.store_startpc(self.pc())
+ closure.store_numArgs(numArgs)
if numCopied > 0:
- copiedValues =
interp.space.wrap_list(self.pop_and_return_n(numCopied))
- self.push(interp.space.w_nil)
+ copiedValues = self.pop_and_return_n(numCopied)
+ for i0 in range(numCopied):
+ w_closure.atput0(space, i0, copiedValues[i0])
+ self.push(w_closure)
self.jump(blockSize)
- def jump(self,offset):
+ def jump(self, offset):
self.store_pc(self.pc() + offset)
def jumpConditional(self,bool,position):
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -113,7 +113,9 @@
define_cls("w_Semaphore", "w_LinkedList")
define_cls("w_BlockContext", "w_ContextPart",
instvarsize=constants.BLKCTX_STACK_START)
-
+ define_cls("w_BlockClosure", "w_Object",
+ instvarsize=constants.BLOCKCLOSURE_SIZE,
+ varsized=True)
# make better accessors for classes that can be found in special object
# table
for name in constants.classes_in_special_object_table.keys():
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
@@ -1,6 +1,6 @@
import py
from spyvm import model, interpreter, primitives, shadow
-from spyvm import objspace
+from spyvm import objspace, wrapper
mockclass = objspace.bootstrap_class
@@ -868,7 +868,7 @@
temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3)
temp_array.atput0(space, 2, fakeliterals(space, "pub"))
context.settemp(1, temp_array)
- interp.step(interp.s_active_context())
+ interp.step(context)
return context, temp_array
def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt):
@@ -885,12 +885,28 @@
assert temp_array.at0(space, 2) == fakeliterals(space, "bar")
assert context.top() == fakeliterals(space, "english")
-def test_pushClosureNumCopiedNumArgsBlockSize(bytecode =
pushClosureNumCopiedNumArgsBlockSize):
- for i in range(0, 65536, 7):
- interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i &
0xFF))
- context = interp.s_active_context()
- pc = context.pc()
- # create/find a method with an appropriate blockClosure
- interp.step(interp.s_active_context())
- assert context.pc() == pc + 4 + i
- # assert that the right blockClosure has been pushed
\ No newline at end of file
+def test_pushClosureNumCopied0NumArgsBlockSize(bytecode =
pushClosureNumCopiedNumArgsBlockSize):
+ for i in (0, 0xF0, 0x0FF0, 0xFFF0):
+ interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i &
0xFF))
+ context = interp.s_active_context()
+ pc = context.pc()
+ # create/find a method with an appropriate blockClosure
+ interp.step(context)
+ assert context.pc() == pc + 4 + i
+ closure = wrapper.BlockClosureWrapper(space, context.top())
+ assert closure.startpc() == pc + 4
+ assert closure.outerContext() is context._w_self
+
+def test_pushClosureNumCopied2NumArgsBlockSize(bytecode =
pushClosureNumCopiedNumArgsBlockSize):
+ interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0))
+ context = interp.s_active_context()
+ context.push("english")
+ context.push("bar")
+ pc = context.pc()
+ interp.step(context)
+ assert context.pc() == pc + 4
+ closure = wrapper.BlockClosureWrapper(space, context.top())
+ assert closure.startpc() == pc + 4
+ assert closure.outerContext() is context._w_self
+ assert closure.w_self.at0(space, 0) == "english"
+ assert closure.w_self.at0(space, 1) == "bar"
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -204,6 +204,12 @@
x, store_x = make_int_getter_setter(0)
y, store_y = make_int_getter_setter(1)
+
+class BlockClosureWrapper(Wrapper):
+ outerContext, store_outerContext = make_getter_setter(0)
+ startpc, store_startpc = make_int_getter_setter(1)
+ numArgs, store_numArgs = make_int_getter_setter(2)
+
# XXX Wrappers below are not used yet.
class OffsetWrapper(Wrapper):
offset_x = make_int_getter(0)
@@ -217,4 +223,3 @@
class CursorWrapper(MaskWrapper):
offset = make_getter(4)
-
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit