Author: Tobias Pape <tob...@netshed.de>
Branch: 
Changeset: r76:77ba2d81ffc9
Date: 2013-02-20 16:09 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/77ba2d81ffc9/

Log:    merge

diff --git a/spyvm/fixedstack.py b/spyvm/fixedstack.py
deleted file mode 100644
--- a/spyvm/fixedstack.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-A Fixed stack for SPy.
-"""
-
-import types
-
-from rpython.rlib import jit
-from rpython.rlib.rarithmetic import r_uint
-
-class FixedStack(object):
-    # _annspecialcase_ = "specialize:ctr_location" # polymorphic
-    
-    def __init__(self):
-        pass
-    
-    def setup(self, stacksize):
-        self.ptr = r_uint(0) # we point after the last element
-        self.items = [None] * stacksize
-    
-    def clone(self):
-        # this is only needed if we support flow space
-        s = self.__class__()
-        s.setup(len(self.items))
-        for item in self.items[:self.ptr]:
-            try:
-                item = item.clone()
-            except AttributeError:
-                pass
-            s.push(item)
-        return s
-    
-    def push(self, item):
-        ptr = jit.promote(self.ptr)
-        self.items[ptr] = item
-        self.ptr = ptr + 1
-    
-    def pop(self):
-        ptr = jit.promote(self.ptr) - 1
-        ret = self.items[ptr]   # you get OverflowError if the stack is empty
-        self.items[ptr] = None
-        self.ptr = ptr
-        return ret
-
-    @jit.unroll_safe
-    def drop(self, n):
-        jit.promote(self.ptr)
-        while n > 0:
-            n -= 1
-            self.ptr -= 1
-            self.items[self.ptr] = None
-    
-    def top(self, position=0):
-        # for a fixed stack, we assume correct indices
-        rpos = r_uint(position)
-        return self.items[self.ptr + ~rpos]
-    
-    def set_top(self, value, position=0):
-        # for a fixed stack, we assume correct indices
-        rpos = r_uint(position)
-        self.items[self.ptr + ~rpos] = value
-    
-    def depth(self):
-        return self.ptr
-    
-    def empty(self):
-        return not self.ptr
-    
-
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/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -308,10 +308,9 @@
     @objectmodel.specialize.arg(2)
     def as_special_get_shadow(self, space, TheClass):
         shadow = self._shadow
-        if shadow is None:
-            shadow = self.attach_shadow_of_class(space, TheClass)
-        elif not isinstance(shadow, TheClass):
-            shadow.detach_shadow()
+        if not isinstance(shadow, TheClass):
+            if shadow is not None:
+                shadow.detach_shadow()
             shadow = self.attach_shadow_of_class(space, TheClass)
         shadow.sync_shadow()
         return shadow
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/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -317,10 +317,8 @@
     __metaclass__ = extendabletype
 
     def __init__(self, space, w_self):
-        from spyvm.fixedstack import FixedStack
 
         self._w_sender = space.w_nil
-        self._stack = FixedStack()
         self.currentBytecode = -1
         AbstractRedirectingShadow.__init__(self, space, w_self)
 
@@ -339,7 +337,7 @@
         if n0 == constants.CTXPART_STACKP_INDEX:
             return self.wrap_stackpointer()
         if self.stackstart() <= n0 < self.external_stackpointer():
-            return self._stack.top(self.stackdepth() - (n0-self.stackstart()) 
- 1)
+            return self.peek(self.stackdepth() - (n0-self.stackstart()) - 1)
         if self.external_stackpointer() <= n0 < self.stackend():
             return self.space.w_nil
         else:
@@ -354,7 +352,7 @@
         if n0 == constants.CTXPART_STACKP_INDEX:
             return self.unwrap_store_stackpointer(w_value)
         if self.stackstart() <= n0 < self.external_stackpointer():
-            return self._stack.set_top(w_value,
+            return self.set_top(w_value,
                                        self.stackdepth() - 
(n0-self.stackstart()) - 1)
             return
         if self.external_stackpointer() <= n0 < self.stackend():
@@ -375,10 +373,10 @@
         if size < depth:
             # TODO Warn back to user
             assert size >= 0
-            self._stack.drop(depth - size)
+            self.pop_n(depth - size)
         else:
             for i in range(depth, size):
-                self._stack.push(self.space.w_nil)
+                self.push(self.space.w_nil)
 
     def wrap_stackpointer(self):
         return self.space.wrap_int(self.stackdepth() + 
@@ -475,20 +473,32 @@
     def settemp(self, index, w_value):
         self.s_home().settemp(index, w_value)
 
+    @jit.unroll_safe
+    def init_stack_and_temps(self):
+        stacksize = self.stackend() - self.stackstart()
+        tempsize = self.tempsize()
+        self._temps_and_stack = [None] * (stacksize + tempsize)
+        for i in range(tempsize):
+            self._temps_and_stack[i] = self.space.w_nil
+        self._stack_ptr = rarithmetic.r_uint(tempsize) # we point after the 
last element
+
     # ______________________________________________________________________
     # Stack Manipulation
-    def init_stack(self):
-        self._stack.setup(self.stackend() - self.stackstart())
-
     def stack(self):
         """NOT_RPYTHON""" # purely for testing
-        return self._stack.items[:self.stackdepth()]
+        return self._temps_and_stack[self.tempsize():self._stack_ptr]
 
     def pop(self):
-        return self._stack.pop()
+        ptr = jit.promote(self._stack_ptr) - 1
+        ret = self._temps_and_stack[ptr]   # you get OverflowError if the 
stack is empty
+        self._temps_and_stack[ptr] = None
+        self._stack_ptr = ptr
+        return ret
 
     def push(self, w_v):
-        self._stack.push(w_v)
+        ptr = jit.promote(self._stack_ptr)
+        self._temps_and_stack[ptr] = w_v
+        self._stack_ptr = ptr + 1
 
     def push_all(self, lst):
         for elt in lst:
@@ -496,18 +506,29 @@
 
     def top(self):
         return self.peek(0)
-        
+
+    def set_top(self, value, position=0):
+        rpos = rarithmetic.r_uint(position)
+        self._temps_and_stack[self._stack_ptr + ~rpos] = value
+
     def peek(self, idx):
-        return self._stack.top(idx)
+        rpos = rarithmetic.r_uint(idx)
+        return self._temps_and_stack[self._stack_ptr + ~rpos]
 
+    @jit.unroll_safe
     def pop_n(self, n):
-        self._stack.drop(n)
+        jit.promote(self._stack_ptr)
+        while n > 0:
+            n -= 1
+            self._stack_ptr -= 1
+            self._temps_and_stack[self._stack_ptr] = None
 
     def stackdepth(self):
-        return rarithmetic.intmask(self._stack.depth())
+        return rarithmetic.intmask(self._stack_ptr - self.tempsize())
 
+    @jit.unroll_safe
     def pop_and_return_n(self, n):
-        result = [self._stack.top(i) for i in range(n - 1, -1, -1)]
+        result = [self.peek(i) for i in range(n - 1, -1, -1)]
         self.pop_n(n)
         return result
 
@@ -533,7 +554,7 @@
         s_result.store_initialip(initialip)
         s_result.store_w_home(w_home)
         s_result.store_pc(initialip)
-        s_result.init_stack()
+        s_result.init_stack_and_temps()
         return w_result
 
     def fetch(self, n0):
@@ -559,7 +580,7 @@
     def attach_shadow(self):
         # Make sure the home context is updated first
         self.copy_from_w_self(constants.BLKCTX_HOME_INDEX)
-        self.init_stack()
+        self.init_stack_and_temps()
         ContextPartShadow.attach_shadow(self)
 
     def unwrap_store_initialip(self, w_value):
@@ -617,6 +638,7 @@
         ContextPartShadow.__init__(self, space, w_self)
 
     @staticmethod
+    @jit.unroll_safe
     def make_context(space, w_method, w_receiver,
                      arguments, w_sender=None):
         # From blue book: normal mc have place for 12 temps+maxstack
@@ -634,10 +656,9 @@
             s_result.store_w_sender(w_sender)
         s_result.store_w_receiver(w_receiver)
         s_result.store_pc(0)
-        s_result._temps = [space.w_nil] * w_method.tempsize
+        s_result.init_stack_and_temps()
         for i in range(len(arguments)):
             s_result.settemp(i, arguments[i])
-        s_result.init_stack()
         return w_result
 
     def fetch(self, n0):
@@ -672,9 +693,7 @@
     def attach_shadow(self):
         # Make sure the method is updated first
         self.copy_from_w_self(constants.MTHDCTX_METHOD)
-        self.init_stack()
-        # And that there is space for the temps
-        self._temps = [self.space.w_nil] * self.tempsize()
+        self.init_stack_and_temps()
         ContextPartShadow.attach_shadow(self)
 
     def tempsize(self):
@@ -694,10 +713,10 @@
         self._w_receiver = w_receiver
 
     def gettemp(self, index0):
-        return self._temps[index0]
+        return self._temps_and_stack[index0]
 
     def settemp(self, index0, w_value):
-        self._temps[index0] = w_value
+        self._temps_and_stack[index0] = w_value
 
     def w_home(self):
         return self.w_self()
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
@@ -16,7 +16,7 @@
     def __init__(self, stack):
         self._vars = [None] * 6 + stack
         s_self = self.as_blockcontext_get_shadow()
-        s_self.init_stack()
+        s_self.init_stack_and_temps()
         s_self.reset_stack()
         s_self.push_all(stack)
         s_self.store_expected_argument_count(0)
@@ -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