Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: 
Changeset: r73:13fb55f6a092
Date: 2013-02-20 15:56 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/13fb55f6a092/

Log:    merge

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -370,7 +370,7 @@
         self.pop()
 
     # closure bytecodes
-    def pushNewArrayPopIntoArray(self, interp):
+    def pushNewArrayBytecode(self, interp):
         arraySize, popIntoArray = splitter[7, 1](self.getbytecode())
         newArray = None
         if popIntoArray == 1:
@@ -388,19 +388,19 @@
         w_indirectTemps = self.gettemp(index_of_array)
         return index_in_array, w_indirectTemps
 
-    def pushTempAtInTempVectorAt(self, interp):
+    def pushRemoteTempLongBytecode(self, interp):
         index_in_array, w_indirectTemps = self._extract_index_and_temps()
         self.push(w_indirectTemps.at0(self.space, index_in_array))
 
-    def storeTempAtInTempVectorAt(self, interp):
+    def storeRemoteTempLongBytecode(self, interp):
         index_in_array, w_indirectTemps = self._extract_index_and_temps()
         w_indirectTemps.atput0(self.space, index_in_array, self.top())
 
-    def popAndStoreTempAtInTempVectorAt(self, interp):
+    def storeAndPopRemoteTempLongBytecode(self, interp):
         index_in_array, w_indirectTemps = self._extract_index_and_temps()
         w_indirectTemps.atput0(self.space, index_in_array, self.pop())
 
-    def pushClosureNumCopiedNumArgsBlockSize(self, interp):
+    def pushClosureCopyCopiedValuesBytecode(self, interp):
         """ Copied from Blogpost: 
http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/
         ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: 
numArgs blockSize: blockSize
         "Simulate the action of a 'closure copy' bytecode whose result is the
@@ -427,16 +427,8 @@
         i = self.getbytecode()
         blockSize = (j << 8) | i
         #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 = self.pop_and_return_n(numCopied)
-            for i0 in range(numCopied):
-                closure.atput0(i0, copiedValues[i0])
+        w_closure, closure = space.newClosure(self._w_self, self.pc(), 
numArgs, 
+                                            self.pop_and_return_n(numCopied))
         self.push(w_closure)
         self.jump(blockSize)
 
@@ -572,12 +564,12 @@
             (135, "popStackBytecode"),
             (136, "duplicateTopBytecode"),
             (137, "pushActiveContextBytecode"),
-            (138, "pushNewArrayPopIntoArray"),
+            (138, "pushNewArrayBytecode"),
             (139, "experimentalBytecode"),
-            (140, "pushTempAtInTempVectorAt"),
-            (141, "storeTempAtInTempVectorAt"),
-            (142, "popAndStoreTempAtInTempVectorAt"),
-            (143, "pushClosureNumCopiedNumArgsBlockSize"),
+            (140, "pushRemoteTempLongBytecode"),
+            (141, "storeRemoteTempLongBytecode"),
+            (142, "storeAndPopRemoteTempLongBytecode"),
+            (143, "pushClosureCopyCopiedValuesBytecode"),
             (144, 151, "shortUnconditionalJump"),
             (152, 159, "shortConditionalJump"),
             (160, 167, "longUnconditionalJump"),
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -1,6 +1,4 @@
-from spyvm import constants
-from spyvm import model
-from spyvm import shadow
+from spyvm import constants, model, shadow, wrapper
 from spyvm.error import UnwrappingError, WrappingError
 from rpython.rlib.objectmodel import instantiate
 from rpython.rlib.rarithmetic import intmask, r_uint
@@ -254,9 +252,27 @@
         elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value)
         raise UnwrappingError()
 
+    def unwrap_array(self, w_array):
+        # Check that our argument has pointers format and the class:
+        if not w_array.getclass(self).is_same_object(self.w_Array):
+            raise PrimitiveFailedError()
+        assert isinstance(w_array, model.W_PointersObject)
+        
+        return [w_array.at0(self, i) for i in range(w_array.size())]
+        
     def _freeze_(self):
         return True
 
+    def newClosure(self, outerContext, pc, numArgs, copiedValues):
+        BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self)
+        w_closure = BlockClosureShadow.new(len(copiedValues))
+        closure = wrapper.BlockClosureWrapper(self, w_closure)
+        closure.store_outerContext(outerContext)
+        closure.store_startpc(pc)
+        closure.store_numArgs(numArgs)
+        for i0 in range(len(copiedValues)):
+            closure.atput0(i0, copiedValues[i0])
+        return w_closure, closure
 
 def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None,
                     name='?', format=shadow.POINTERS, varsized=False):
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -97,6 +97,9 @@
                     elif spec is str:
                         assert isinstance(w_arg, model.W_BytesObject)
                         args += (w_arg.as_string(), )
+                    elif spec is list:
+                        assert isinstance(w_arg, model.W_PointersObject)
+                        args += (interp.space.unwrap_array(w_arg), )
                     elif spec is char:
                         args += (unwrap_char(w_arg), )
                     else:
@@ -829,25 +832,20 @@
     frame.pop()
     finalize_block_ctx(interp, s_block_ctx, frame.w_self())
     
-@expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, object],
+@expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list],
                   no_result=True)
-def func(interp, w_block_ctx, w_args):
+def func(interp, w_block_ctx, args_w):
 
     assert isinstance(w_block_ctx, model.W_PointersObject)
     s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space)
     exp_arg_cnt = s_block_ctx.expected_argument_count()
 
-    # Check that our arguments have pointers format and the right size:
-    if not w_args.getclass(interp.space).is_same_object(
-            interp.space.w_Array):
-        raise PrimitiveFailedError()
-    if w_args.size() != exp_arg_cnt:
+    if len(args_w) != exp_arg_cnt:
         raise PrimitiveFailedError()
     
-    assert isinstance(w_args, model.W_PointersObject)
     # Push all the items from the array
     for i in range(exp_arg_cnt):
-        s_block_ctx.push(w_args.at0(interp.space, i))
+        s_block_ctx.push(args_w[i])
 
     # XXX Check original logic. Image does not test this anyway
     # because falls back to value + internal implementation
@@ -913,6 +911,80 @@
     return w_rcvr
 
 # ___________________________________________________________________________
+# BlockClosure Primitives
+
+CLOSURE_COPY_WITH_COPIED_VALUES = 200
+CLOSURE_VALUE = 201
+CLOSURE_VALUE_ = 202
+CLOSURE_VALUE_VALUE = 203
+CLOSURE_VALUE_VALUE_VALUE = 204
+CLOSURE_VALUE_VALUE_VALUE_VALUE = 205
+CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments:
+CLOSURE_VALUE_NO_CONTEXT_SWITCH = 221
+CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222
+
+@expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, 
list])
+def func(interp, outerContext, numArgs, copiedValues):
+    frame = interp.s_active_context()
+    w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), 
+                                                        numArgs, copiedValues)
+    frame.push(w_context)
+
+
+def activateClosure(w_block_closure, args_w, mayContextSwitch=True):
+    if not w_block_closure.getclass(interp.space).is_same_object(
+            interp.space.w_BlockClosure):
+        raise PrimitiveFailedError()
+    if not w_block_closure.numArgs == len(args_w):
+        raise PrimitiveFailedError()
+    if not w_block_closure.outerContext.getclass(interp.space).issubclass(
+            interp.space.w_ContextPart):
+        raise PrimitiveFailedError()
+    w_closureMethod = w_block_closure.w_method()
+    assert isinstance(w_closureMethod, W_CompiledMethod)
+    assert w_block_closure is not w_block_closure.outerContext
+    numCopied = w_block_closure.size()
+
+    s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space)
+    s_block_closure.push_all(args_w)
+
+    s_block_closure.store_pc(s_block_closure.initialip())
+    s_block_closure.store_w_sender(frame)
+
+
+@expose_primitive(CLOSURE_VALUE, unwrap_spec=[object])
+def func(interp, w_block_closure):
+    activateClosure(w_block_closure, [])
+
+@expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object])
+def func(interp, w_block_closure, w_a0):
+    activateClosure(w_block_closure, [w_a0])
+
+@expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object])
+def func(interp, w_block_closure, w_a0, w_a1):
+    activateClosure(w_block_closure, [w_a0, w_a1])
+
+@expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, 
object, object])
+def func(interp, w_block_closure, w_a0, w_a1, w_a2):
+    activateClosure(w_block_closure, [w_a0, w_a1, w_a2])
+
+@expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, 
object, object, object, object])
+def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3):
+    activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3])
+
+@expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list])
+def func(interp, w_block_closure, args_w):
+    activateClosure(w_block_closure, args_w)
+
+@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object])
+def func(interp, w_block_closure):
+    activateClosure(w_block_closure, [], mayContextSwitch=False)
+
+@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, 
object])
+def func(interp, w_block_closure, w_a0):
+    activateClosure(w_block_closure, [w_a0], mayContextSwitch=False)
+
+# ___________________________________________________________________________
 # PrimitiveLoadInstVar
 #
 # These are some wacky bytecodes in squeak.  They are defined to do
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
@@ -831,7 +831,7 @@
     option.bc_trace = bc_trace
 
 # Closure Bytecodes
-def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray):
+def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode):
     interp = new_interpreter(bytecode + chr(0x83))
     context = interp.s_active_context()
     context.push(fakeliterals(space, "egg"))
@@ -843,7 +843,7 @@
     assert array.at0(space, 1) == fakeliterals(space, "bar")
     assert array.at0(space, 2) == fakeliterals(space, "baz")
 
-def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray):
+def test_bc_pushNewArray(bytecode=pushNewArrayBytecode):
     interp = new_interpreter(bytecode + chr(0x07))
     context = interp.s_active_context()
     interp.step(interp.s_active_context())
@@ -851,7 +851,7 @@
     assert array.size() == 7
     assert array.at0(space, 0) == space.w_nil
 
-def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt):
+def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode):
     interp = new_interpreter(bytecode + chr(0) + chr(0))
     context = interp.s_active_context()
     context.push(fakeliterals(space, "jam"))
@@ -871,21 +871,21 @@
     interp.step(context)
     return context, temp_array
 
-def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt):
+def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode):
     context, _ = setupTempArrayAndContext(bytecode)
     assert context.top() == fakeliterals(space, "pub")
 
-def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt):
+def test_bc_storeRemoteTempLongBytecode(bytecode = 
storeRemoteTempLongBytecode):
     context, temp_array = setupTempArrayAndContext(bytecode)
     assert context.top() == fakeliterals(space, "bar")
     assert temp_array.at0(space, 2) == fakeliterals(space, "bar")
 
-def test_popAndStoreTempAtInTempVectorAt(bytecode = 
popAndStoreTempAtInTempVectorAt):
+def test_bc_storeAndPopRemoteTempLongBytecode(bytecode = 
storeAndPopRemoteTempLongBytecode):
     context, temp_array = setupTempArrayAndContext(bytecode)
     assert temp_array.at0(space, 2) == fakeliterals(space, "bar")
     assert context.top() == fakeliterals(space, "english")
 
-def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = 
pushClosureNumCopiedNumArgsBlockSize):
+def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = 
pushClosureCopyCopiedValuesBytecode):
     for i in (0, 0xF0, 0x0FF0, 0xFFF0):
         interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 
0xFF))
         context = interp.s_active_context()
@@ -897,7 +897,7 @@
         assert closure.startpc() == pc + 4
         assert closure.outerContext() is context._w_self
 
-def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = 
pushClosureNumCopiedNumArgsBlockSize):
+def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = 
pushClosureCopyCopiedValuesBytecode):
     interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0))
     context = interp.s_active_context()
     context.push("english")
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -30,6 +30,7 @@
     if isinstance(x, model.W_Object): return x
     if isinstance(x, str) and len(x) == 1: return space.wrap_char(x)
     if isinstance(x, str): return space.wrap_string(x)
+    if isinstance(x, list): return space.wrap_list(x)
     raise NotImplementedError
     
 def mock(stack):
diff --git a/spyvm/todo.txt b/spyvm/todo.txt
--- a/spyvm/todo.txt
+++ b/spyvm/todo.txt
@@ -22,5 +22,3 @@
 Shadows:
 [ ] Fix invalidation of methoddictshadow when the w_self of its values array 
changes
 
-Lars ToDo
-[ ] different image with BlockClosure instead of BlockContext
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to