Author: Lars Wassermann <[email protected]>
Branch: 
Changeset: r56:a18d2886e28e
Date: 2013-02-18 20:00 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/a18d2886e28e/

Log:    added schematic/test for the last new bytecode: push block closure

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -403,10 +403,35 @@
         indirectTemps.atput0(self, k, context.pop())
 
     def pushClosureNumCopiedNumArgsBlockSize(self, interp):
-        l, k = splitter[4, 4](self.getbytecode())
+        """ 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
+         new BlockClosure for the following code"
+        | copiedValues |
+        numCopied > 0
+                 ifTrue:
+                          [copiedValues := Array new: numCopied.
+                           numCopied to: 1 by: -1 do:
+                                   [:i|
+                                   copiedValues at: i put: self pop]]
+                 ifFalse:
+                          [copiedValues := nil].
+        self push: (BlockClosure new
+                                   outerContext: self
+                                   startpc: pc
+                                   numArgs: numArgs
+                                   copiedValues: copiedValues).
+        self jump: blockSize
+        """
+        numArgs, numCopied = splitter[4, 4](self.getbytecode())
         j = self.getbytecode()
         i = self.getbytecode()
-        raise MissingBytecode("not yet implemented: pushClosureNumCopied l 
numArgs k blockSize ij")
+        blockSize = (j << 8) | i
+        copiedValues = interp.space.w_nil
+        if numCopied > 0:
+            copiedValues = 
interp.space.wrap_list(self.pop_and_return_n(numCopied))
+        self.push(interp.space.w_nil)
+        self.jump(blockSize)
 
     def jump(self,offset):
         self.store_pc(self.pc() + offset)
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
@@ -885,3 +885,12 @@
     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
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to