[pypy-commit] lang-smalltalk default: changed from a mixed stack of w_PointerObjects and MethodContextShadows to only MethodContextShadows

lwassermann noreply at buildbot.pypy.org
Tue Mar 5 15:51:31 CET 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r120:d939a6f9d3d7
Date: 2013-03-05 15:50 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/d939a6f9d3d7/

Log:	changed from a mixed stack of w_PointerObjects and
	MethodContextShadows to only MethodContextShadows renamed
	ContextPart>>method() to s_method()

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -28,7 +28,7 @@
     _last_indent = ""
     jit_driver = jit.JitDriver(
         greens=['pc', 'self', 'method'],
-        reds=['s_active_context', 'w_active_context'],
+        reds=['s_active_context'],
         #virtualizables=['s_active_context'],
         get_printable_location=get_printable_location
     )
@@ -57,39 +57,38 @@
     def loop(self, w_active_context):
         # just a trampoline for the actual loop implemented in c_loop
         self._loop = True
-        w_new_context = w_active_context
+        s_new_context = w_active_context.as_context_get_shadow(self.space)
         while True:
             try:
-                w_new_context = self.c_loop(w_new_context)
+                s_new_context = self.c_loop(s_new_context)
             except StackOverflow, e:
                 self.remaining_stack_depth = self.max_stack_depth
-                w_new_context = e.w_context
+                s_new_context = e.s_context
 
-    def c_loop(self, w_active_context):
-        s_active_context = w_active_context.as_context_get_shadow(self.space)
+    def c_loop(self, s_context):
+        s_active_context = s_context
         while True:
             pc = s_active_context._pc
-            method = s_active_context.method()
+            method = s_active_context.s_method()
 
             self.jit_driver.jit_merge_point(
                 pc=pc, self=self, method=method,
-                s_active_context=s_active_context,
-                w_active_context=w_active_context)
-            w_return_to_context = self.step(s_active_context)
-            if (w_return_to_context is not None
-                    and not w_return_to_context.is_same_object(w_active_context)):
-                w_active_context.as_context_get_shadow(self.space).mark_returned()
-                return w_return_to_context
+                s_active_context=s_active_context)
+            s_return_to_context = self.step(s_active_context)
+            if (s_return_to_context is not None
+                    and s_return_to_context is not s_context):
+                s_active_context.mark_returned()
+                return s_return_to_context
 
-    def stack_frame(self, w_new_frame):
+    def stack_frame(self, s_new_frame):
         if not self._loop:
-            return w_new_frame # this test is done to not loop in test,
+            return s_new_frame # this test is done to not loop in test,
                                # but rather step just once where wanted
         if self.remaining_stack_depth == 1:
-            raise StackOverflow(w_new_frame)
+            raise StackOverflow(s_new_frame)
 
         self.remaining_stack_depth -= 1
-        retval = self.c_loop(w_new_frame)
+        retval = self.c_loop(s_new_frame)
         self.remaining_stack_depth += 1
         return retval
 
@@ -106,16 +105,16 @@
         w_method.setbytes([chr(124)]) #returnTopFromMethod
         s_method = w_method.as_compiledmethod_get_shadow(self.space)
         s_frame = MethodContextShadow.make_context(
-                self.space, s_method, w_receiver, [], None).get_shadow(self.space)
+                self.space, s_method, w_receiver, [], None)
         s_frame.push(w_receiver)
         s_frame.push_all(list(arguments_w))
         try:
-            w_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self)
-            if w_new_frame == None:
+            s_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self)
+            if s_new_frame == None:
                 # which means that we tried to call a primitive method
                 return s_frame.pop()
             else:
-                self.loop(w_new_frame)
+                self.loop(s_new_frame.w_self())
         except ReturnFromTopLevel, e:
             return e.object
 
@@ -124,8 +123,8 @@
         self.object = object
 
 class StackOverflow(Exception):
-    def __init__(self, w_top_context):
-        self.w_context = w_top_context
+    def __init__(self, s_top_context):
+        self.s_context = s_top_context
 
 def make_call_primitive_bytecode(primitive, selector, argcount):
     def callPrimitive(self, interp, current_bytecode):
@@ -179,14 +178,14 @@
 
     def pushLiteralConstantBytecode(self, interp, current_bytecode):
         index = current_bytecode & 31
-        self.push(self.method().getliteral(index))
+        self.push(self.s_method().getliteral(index))
 
     def pushLiteralVariableBytecode(self, interp, current_bytecode):
         # this bytecode assumes that literals[index] is an Association
         # which is an object with two named vars, and fetches the second
         # named var (the value).
         index = current_bytecode & 31
-        w_association = self.method().getliteral(index)
+        w_association = self.s_method().getliteral(index)
         association = wrapper.AssociationWrapper(self.space, w_association)
         self.push(association.value())
 
@@ -231,7 +230,7 @@
 
     # send, return bytecodes
     def sendLiteralSelectorBytecode(self, interp, current_bytecode):
-        w_selector = self.method().getliteral(current_bytecode & 15)
+        w_selector = self.s_method().getliteral(current_bytecode & 15)
         argcount = ((current_bytecode >> 4) & 3) - 1
         return self._sendSelfSelector(w_selector, argcount, interp)
 
@@ -241,7 +240,7 @@
                                   receiver, receiver.shadow_of_my_class(self.space))
 
     def _sendSuperSelector(self, w_selector, argcount, interp):
-        w_compiledin = self.method().w_compiledin
+        w_compiledin = self.s_method().w_compiledin
         assert isinstance(w_compiledin, model.W_PointersObject)
         s_compiledin = w_compiledin.as_class_get_shadow(self.space)
         return self._sendSelector(w_selector, argcount, interp, self.w_receiver(),
@@ -271,39 +270,41 @@
                     print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, w_selector.as_string(),)
                 pass # ignore this error and fall back to the Smalltalk version
         arguments = self.pop_and_return_n(argcount)
-        w_frame = s_method.create_frame(self.space, receiver, arguments,
-                                      self.w_self())
+        s_frame = s_method.create_frame(self.space, receiver, arguments, self)
         self.pop()
-        return interp.stack_frame(w_frame)
+        return interp.stack_frame(s_frame)
 
-    def _return(self, return_value, interp, w_return_to):
+    def _return(self, return_value, interp, s_return_to):
         # for tests, when returning from the top-level context
-        if w_return_to.is_same_object(self.space.w_nil):
+        if s_return_to is None:
             raise ReturnFromTopLevel(return_value)
+        # unfortunately, the assert below is not true for some tests
+        # assert self._stack_ptr == self.tempsize()
+        
         # make this context a returned one
         self.mark_returned()
 
-        w_return_to.as_context_get_shadow(self.space).push(return_value)
-        return w_return_to
+        s_return_to.push(return_value)
+        return s_return_to
 
     def returnReceiver(self, interp, current_bytecode):
-        return self._return(self.w_receiver(), interp, self.s_home().w_sender())
+        return self._return(self.w_receiver(), interp, self.s_home().s_sender())
 
     def returnTrue(self, interp, current_bytecode):
-        return self._return(interp.space.w_true, interp, self.s_home().w_sender())
+        return self._return(interp.space.w_true, interp, self.s_home().s_sender())
 
     def returnFalse(self, interp, current_bytecode):
-        return self._return(interp.space.w_false, interp, self.s_home().w_sender())
+        return self._return(interp.space.w_false, interp, self.s_home().s_sender())
 
     def returnNil(self, interp, current_bytecode):
-        return self._return(interp.space.w_nil, interp, self.s_home().w_sender())
+        return self._return(interp.space.w_nil, interp, self.s_home().s_sender())
 
     def returnTopFromMethod(self, interp, current_bytecode):
         # overwritten in MethodContextShadow
-        return self._return(self.top(), interp, self.s_home().w_sender())
+        return self._return(self.pop(), interp, self.s_home().s_sender())
 
     def returnTopFromBlock(self, interp, current_bytecode):
-        return self._return(self.top(), interp, self.w_sender())
+        return self._return(self.pop(), interp, self.s_sender())
 
     def unknownBytecode(self, interp, current_bytecode):
         raise MissingBytecode("unknownBytecode")
@@ -320,9 +321,9 @@
         elif variableType == 1:
             self.push(self.gettemp(variableIndex))
         elif variableType == 2:
-            self.push(self.method().getliteral(variableIndex))
+            self.push(self.s_method().getliteral(variableIndex))
         elif variableType == 3:
-            w_association = self.method().getliteral(variableIndex)
+            w_association = self.s_method().getliteral(variableIndex)
             association = wrapper.AssociationWrapper(self.space, w_association)
             self.push(association.value())
         else:
@@ -337,7 +338,7 @@
         elif variableType == 2:
             raise IllegalStoreError
         elif variableType == 3:
-            w_association = self.method().getliteral(variableIndex)
+            w_association = self.s_method().getliteral(variableIndex)
             association = wrapper.AssociationWrapper(self.space, w_association)
             association.store_value(self.top())
 
@@ -347,7 +348,7 @@
 
     def getExtendedSelectorArgcount(self):
         descriptor = self.getbytecode()
-        return ((self.method().getliteral(descriptor & 31)),
+        return ((self.s_method().getliteral(descriptor & 31)),
                 (descriptor >> 5))
 
     def singleExtendedSendBytecode(self, interp, current_bytecode):
@@ -360,21 +361,21 @@
         opType = second >> 5
         if opType == 0:
             # selfsend
-            return self._sendSelfSelector(self.method().getliteral(third),
+            return self._sendSelfSelector(self.s_method().getliteral(third),
                                           second & 31, interp)
         elif opType == 1:
             # supersend
-            return self._sendSuperSelector(self.method().getliteral(third),
+            return self._sendSuperSelector(self.s_method().getliteral(third),
                                            second & 31, interp)
         elif opType == 2:
             # pushReceiver
             self.push(self.w_receiver().fetch(self.space, third))
         elif opType == 3:
             # pushLiteralConstant
-            self.push(self.method().getliteral(third))
+            self.push(self.s_method().getliteral(third))
         elif opType == 4:
             # pushLiteralVariable
-            w_association = self.method().getliteral(third)
+            w_association = self.s_method().getliteral(third)
             association = wrapper.AssociationWrapper(self.space, w_association)
             self.push(association.value())
         elif opType == 5:
@@ -382,7 +383,7 @@
         elif opType == 6:
             self.w_receiver().store(self.space, third, self.pop())
         elif opType == 7:
-            w_association = self.method().getliteral(third)
+            w_association = self.s_method().getliteral(third)
             association = wrapper.AssociationWrapper(self.space, w_association)
             association.store_value(self.top())
 
@@ -392,7 +393,7 @@
 
     def secondExtendedSendBytecode(self, interp, current_bytecode):
         descriptor = self.getbytecode()
-        w_selector = self.method().getliteral(descriptor & 63)
+        w_selector = self.s_method().getliteral(descriptor & 63)
         argcount = descriptor >> 6
         return self._sendSelfSelector(w_selector, argcount, interp)
 
@@ -457,7 +458,7 @@
         i = self.getbytecode()
         blockSize = (j << 8) | i
         #create new instance of BlockClosure
-        w_closure = space.newClosure(self._w_self, self.pc(), numArgs, 
+        w_closure = space.newClosure(self.w_self(), self.pc(), numArgs, 
                                             self.pop_and_return_n(numCopied))
         self.push(w_closure)
         self.jump(blockSize)
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -105,15 +105,21 @@
                     else:
                         raise NotImplementedError(
                             "unknown unwrap_spec %s" % (spec, ))
-                w_result = func(interp, s_frame, *args)
-                # After calling primitive, reload context-shadow in case it
-                # needs to be updated
-                s_frame.pop_n(len_unwrap_spec)   # only if no exception occurs!
                 if result_is_new_frame:
-                    return interp.stack_frame(w_result)
-                elif not no_result:
-                    assert w_result is not None
-                    s_frame.push(w_result)
+                    s_new_frame = func(interp, s_frame, *args)
+                    # After calling primitive, reload context-shadow in case it
+                    # needs to be updated
+                    s_frame.pop_n(len_unwrap_spec)   # only if no exception occurs!
+                    return interp.stack_frame(s_new_frame)
+                else:
+                    w_result = func(interp, s_frame, *args)
+                    # After calling primitive, reload context-shadow in case it
+                    # needs to be updated
+                    s_frame.pop_n(len_unwrap_spec)   # only if no exception occurs!
+                    if not no_result:
+                        assert w_result is not None
+                        assert isinstance(w_result, model.W_Object)
+                        s_frame.push(w_result)
         wrapped.func_name = "wrap_prim_" + name
         prim_table[code] = wrapped
         prim_table_implemented_only.append((code, wrapped))
@@ -849,16 +855,16 @@
     # The block bytecodes are stored inline: so we skip past the
     # byteodes to invoke this primitive to find them (hence +2)
     initialip = s_frame.pc() + 2
-    w_new_context = shadow.BlockContextShadow.make_context(
+    s_new_context = shadow.BlockContextShadow.make_context(
         interp.space,
         w_method_context, interp.space.w_nil, argcnt, initialip)
-    return w_new_context
+    return s_new_context.w_self()
 
-def finalize_block_ctx(interp, s_block_ctx, w_frame):
+def finalize_block_ctx(interp, s_block_ctx, s_frame):
     # Set some fields
     s_block_ctx.store_pc(s_block_ctx.initialip())
-    s_block_ctx.store_w_sender(w_frame)
-    return s_block_ctx.w_self()
+    s_block_ctx.store_s_sender(s_frame)
+    return s_block_ctx
 
 @expose_primitive(VALUE, result_is_new_frame=True)
 def func(interp, s_frame, argument_count):
@@ -893,7 +899,7 @@
     s_block_ctx.push_all(block_args)
 
     s_frame.pop()
-    return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self())
+    return finalize_block_ctx(interp, s_block_ctx, s_frame)
 
 @expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list],
                   result_is_new_frame=True)
@@ -912,7 +918,7 @@
 
     # XXX Check original logic. Image does not test this anyway
     # because falls back to value + internal implementation
-    return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self())
+    return finalize_block_ctx(interp, s_block_ctx, s_frame)
 
 @expose_primitive(PERFORM)
 def func(interp, s_frame, argcount):
@@ -925,12 +931,12 @@
     s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel)
     assert s_method
 
-    w_frame = s_method.create_frame(
+    s_new_frame = s_method.create_frame(
         interp.space, w_rcvr,
         [w_args.fetch(interp.space, i) for i in range(w_args.size())])
 
-    w_frame.as_context_get_shadow(interp.space).store_w_sender(s_frame.w_self())
-    return w_frame
+    s_new_frame.store_w_sender(s_frame.w_self())
+    return s_new_frame
 
 @expose_primitive(SIGNAL, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
@@ -957,7 +963,7 @@
         interp.space.w_Process):
         raise PrimitiveFailedError()
     s_frame.push(w_rcvr) # w_rcvr is the result in the old frame
-    return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self())
+    return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()).as_context_get_shadow(interp.space)
 
 @expose_primitive(SUSPEND, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr, result_is_new_frame=True):
@@ -966,7 +972,7 @@
         interp.space.w_Process):
         raise PrimitiveFailedError()
     s_frame.push(w_rcvr) # w_rcvr is the result in the old frame
-    return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self())
+    return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()).as_context_get_shadow(interp.space)
 
 @expose_primitive(FLUSH_CACHE, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
@@ -1010,14 +1016,13 @@
     
     # additionally to the smalltalk implementation, this also pushes
     # args and copiedValues
-    w_new_frame = block.asContextWithSender(
-                            s_frame.w_self(), args_w)
-    w_closureMethod = w_new_frame.get_shadow(space).w_method()
+    s_new_frame = block.asContextWithSender(s_frame.w_self(), args_w)
+    w_closureMethod = s_new_frame.w_method()
 
     assert isinstance(w_closureMethod, model.W_CompiledMethod)
     assert w_block is not block.outerContext()
 
-    return w_new_frame
+    return s_new_frame
 
 
 @expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], result_is_new_frame=True)
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -284,7 +284,11 @@
 class AbstractRedirectingShadow(AbstractShadow):
     def __init__(self, space, w_self):
         AbstractShadow.__init__(self, space, w_self)
-        self._w_self_size = self.w_self().size()
+        if w_self is not None:
+            self._w_self_size = w_self.size()
+        else:
+            self._w_self_size = 0
+
     def fetch(self, n0):
         raise NotImplementedError()
     def store(self, n0, w_value):
@@ -313,14 +317,13 @@
     __metaclass__ = extendabletype
 
     # _virtualizable2_ = [
-    #     "_w_sender", "_pc", "_w_sender",
+    #     "_s_sender", "_pc",
     #     "_temps_and_stack[*]", "_stack_ptr",
     #     "_w_self", "_w_self_size"
     # ]
 
     def __init__(self, space, w_self):
-
-        self._w_sender = space.w_nil
+        self._s_sender = None
         AbstractRedirectingShadow.__init__(self, space, w_self)
 
     @staticmethod
@@ -403,32 +406,37 @@
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
 
+    def store_s_sender(self, s_sender):
+        assert s_sender is None or isinstance(s_sender, ContextPartShadow)
+        self._s_sender = s_sender
+
     def store_w_sender(self, w_sender):
         assert isinstance(w_sender, model.W_PointersObject)
-        self._w_sender = w_sender
+        if w_sender.is_same_object(self.space.w_nil):
+            self._s_sender = None
+        else:
+            self._s_sender = w_sender.as_context_get_shadow(self.space)
 
     def w_sender(self):
-        return self._w_sender
+        if self._s_sender is None:
+            return self.space.w_nil
+        return self._s_sender.w_self()
 
     def s_sender(self):
-        w_sender = self.w_sender()
-        if w_sender.is_same_object(self.space.w_nil):
-            return None
-        else:
-            return w_sender.as_context_get_shadow(self.space)
+        return self._s_sender
 
     def store_unwrap_pc(self, w_pc):
         if w_pc.is_same_object(self.space.w_nil):
             return
         pc = self.space.unwrap_int(w_pc)
-        pc -= self.method().bytecodeoffset
+        pc -= self.s_method().bytecodeoffset
         pc -= 1
         self.store_pc(pc)
 
     def wrap_pc(self):
         pc = self.pc()
         pc += 1
-        pc += self.method().bytecodeoffset
+        pc += self.s_method().bytecodeoffset
         return self.space.wrap_int(pc)
 
     def pc(self):
@@ -442,7 +450,7 @@
 
     def mark_returned(self):
         self.store_pc(-1)
-        self.store_w_sender(self.space.w_nil)
+        self.store_s_sender(None)
 
     def is_returned(self):
         return self.pc() == -1 and self.w_sender is self.space.w_nil
@@ -453,7 +461,7 @@
     def w_method(self):
         return self.s_home().w_method()
 
-    def method(self):
+    def s_method(self):
         w_method = jit.promote(self.w_method())
         return jit.promote(
             w_method.as_compiledmethod_get_shadow(self.space)
@@ -462,7 +470,7 @@
     def getbytecode(self):
         jit.promote(self._pc)
         assert self._pc >= 0
-        bytecode = self.method().bytecode[self._pc]
+        bytecode = self.s_method().bytecode[self._pc]
         currentBytecode = ord(bytecode)
         self._pc += 1
         return currentBytecode
@@ -489,11 +497,13 @@
 
     # ______________________________________________________________________
     # Stack Manipulation
+    
     def stack(self):
         """NOT_RPYTHON""" # purely for testing
         return self._temps_and_stack[self.tempsize():self._stack_ptr]
 
     def pop(self):
+        #assert self._stack_ptr > self.tempsize()
         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
@@ -501,6 +511,8 @@
         return ret
 
     def push(self, w_v):
+        #assert self._stack_ptr >= self.tempsize()
+        #assert self._stack_ptr < self.stackend() - self.stackstart() + self.tempsize()
         ptr = jit.promote(self._stack_ptr)
         self._temps_and_stack[ptr] = w_v
         self._stack_ptr = ptr + 1
@@ -522,6 +534,7 @@
 
     @jit.unroll_safe
     def pop_n(self, n):
+        #assert n == 0 or self._stack_ptr - n >= self.tempsize()
         jit.promote(self._stack_ptr)
         while n > 0:
             n -= 1
@@ -543,6 +556,20 @@
 
     def tempsize(self):
         raise NotImplementedError()
+    # ______________________________________________________________________
+    # Marriage of Context Shadows with PointerObjects only when required
+    
+    def w_self(self):
+        if self._w_self is not None:
+            return self._w_self
+        else:
+            size = self.size() - self.space.w_MethodContext.as_class_get_shadow(self.space).instance_size
+            space = self.space
+            w_self = space.w_MethodContext.as_class_get_shadow(space).new(size)
+            w_self.store_shadow(self)
+            self._w_self = w_self
+            self._w_self_size = w_self.size()
+            return w_self
 
     def store_instances_array(self, list_w):
         # used for primitives 77 & 78
@@ -551,10 +578,11 @@
     def instances_array(self):
         return self.instances_w
 
+
 class BlockContextShadow(ContextPartShadow):
 
     @staticmethod
-    def make_context(space, w_home, w_sender, argcnt, initialip):
+    def make_context(space, w_home, s_sender, argcnt, initialip):
         # create and attach a shadow manually, to not have to carefully put things
         # into the right places in the W_PointersObject
         # XXX could hack some more to never have to create the _vars of w_result
@@ -568,7 +596,7 @@
         s_result.store_w_home(w_home)
         s_result.store_pc(initialip)
         s_result.init_stack_and_temps()
-        return w_result
+        return s_result
 
     def fetch(self, n0):
         if n0 == constants.BLKCTX_HOME_INDEX:
@@ -599,12 +627,12 @@
 
     def unwrap_store_initialip(self, w_value):
         initialip = self.space.unwrap_int(w_value)
-        initialip -= 1 + self.method().literalsize
+        initialip -= 1 + self.s_method().literalsize
         self.store_initialip(initialip)
 
     def wrap_initialip(self):
         initialip = self.initialip()
-        initialip += 1 + self.method().literalsize
+        initialip += 1 + self.s_method().literalsize
         return self.space.wrap_int(initialip)
 
     def unwrap_store_eargc(self, w_value):
@@ -656,36 +684,34 @@
     @staticmethod
     @jit.unroll_safe
     def make_context(space, s_method, w_receiver,
-                     arguments, w_sender=None, closure=None, pc=0):
+                     arguments, s_sender=None, closure=None, pc=0):
         # From blue book: normal mc have place for 12 temps+maxstack
         # mc for methods with islarge flag turned on 32
-        size = 12 + s_method.islarge * 20 + s_method.argsize
-        w_result = space.w_MethodContext.as_class_get_shadow(space).new(size)
-        assert isinstance(w_result, model.W_PointersObject)
-        # create and attach a shadow manually, to not have to carefully put things
-        # into the right places in the W_PointersObject
-        # XXX could hack some more to never have to create the _vars of w_result
-        s_result = MethodContextShadow(space, w_result)
-        s_result = jit.hint(s_result, access_directly=True, fresh_virtualizable=True)
+        size = (12 + s_method.islarge * 20 + s_method.argsize 
+            + space.w_MethodContext.as_class_get_shadow(space).instance_size)
+        # The last summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self.
+
+        s_new_context = MethodContextShadow(space, None)
+        s_new_context._w_self_size = size
+        s_new_context = jit.hint(s_new_context, access_directly=True, fresh_virtualizable=True)
         
-        w_result.store_shadow(s_result)
         if closure is not None: 
-            s_result.w_closure_or_nil = closure._w_self
+            s_new_context.w_closure_or_nil = closure._w_self
         
-        s_result.store_w_method(s_method.w_self())
-        if w_sender:
-            s_result.store_w_sender(w_sender)
-        s_result.store_w_receiver(w_receiver)
-        s_result.store_pc(pc)
-        s_result.init_stack_and_temps()
+        s_new_context.store_w_method(s_method.w_self())
+        if s_sender:
+            s_new_context.store_s_sender(s_sender)
+        s_new_context.store_w_receiver(w_receiver)
+        s_new_context.store_pc(pc)
+        s_new_context.init_stack_and_temps()
         
         argc = len(arguments)
         for i0 in range(argc):
-            s_result.settemp(i0, arguments[i0])
+            s_new_context.settemp(i0, arguments[i0])
         if closure is not None: 
             for i0 in range(closure.size()):
-                s_result.settemp(i0+argc, closure.at0(i0))
-        return w_result
+                s_new_context.settemp(i0+argc, closure.at0(i0))
+        return s_new_context
 
     def fetch(self, n0):
         if n0 == constants.MTHDCTX_METHOD:
@@ -724,7 +750,7 @@
 
     def tempsize(self):
         if not self.is_closure_context():
-            return self.method().tempsize
+            return self.s_method().tempsize
         else:
             return wrapper.BlockClosureWrapper(self.space, 
                                 self.w_closure_or_nil).tempsize()
@@ -772,10 +798,10 @@
             # XXX check whether we can actually return from that context
             if s_outerContext.pc() == -1:
                 raise error.BlockCannotReturnError()
-            return_to_context = s_outerContext.s_home().w_sender()
+            return_to_context = s_outerContext.s_home().s_sender()
         else:
-            return_to_context = self.s_home().w_sender()
-        return self._return(self.top(), interp, return_to_context)
+            return_to_context = self.s_home().s_sender()
+        return self._return(self.pop(), interp, return_to_context)
 
     def is_closure_context(self):
         return self.w_closure_or_nil is not self.space.w_nil
@@ -783,7 +809,7 @@
     def __str__(self):
         retval = '\nMethodContext of:'
         retval += self.w_method().as_string(markBytecode=self.pc() + 1)
-        retval += "Stackptr: %i" % self._stack_ptr
+        retval += "Stackptr: %i (this is an empty ascending stack)" % (self._stack_ptr - self.tempsize())
         retval += "\nStack   : " + str(self.stack())
         return retval
 
@@ -831,6 +857,6 @@
 
     def create_frame(self, space, receiver, arguments, sender = None):
         assert len(arguments) == self.argsize
-        w_new = MethodContextShadow.make_context(
+        s_new = MethodContextShadow.make_context(
                 space, self, receiver, arguments, sender)
-        return w_new
+        return s_new
diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py
--- a/spyvm/test/jit.py
+++ b/spyvm/test/jit.py
@@ -64,9 +64,9 @@
         w_object = model.W_SmallInteger(0)
         s_class = w_object.shadow_of_my_class(space)
         s_method = s_class.lookup(w_selector)
-        w_frame = s_method.create_frame(space, w_object, [])
+        s_frame = s_method.create_frame(space, w_object, [])
 
         def interp_w():
-            interp.loop(w_frame)
+            interp.loop(s_frame.w_self())
 
         self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True, inline=True)
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
@@ -17,14 +17,16 @@
                         w_class.shadow_of_my_class(tools.space))
     perform(w_class, initialize_symbol)
 
-#initialize String class, because equality testing requires a class var set.
-initialize_class(w("string").getclass(tools.space))
+def test_initialize_string_class():
+    #initialize String class, because equality testing requires a class var set.
+    initialize_class(w("string").getclass(tools.space))
 
 def test_symbol_asSymbol():
     w_result = perform(tools.image.w_asSymbol, "asSymbol")
     assert w_result is tools.image.w_asSymbol
 
 def test_create_new_symbol():
+    py.test.skip("This test takes quite long and is actually included in test_retrieve_symbol.")
     w_result = perform(w("someString"), "asSymbol")
     assert w_result is not None
     assert w_result.as_string() == "someString"
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
@@ -8,7 +8,10 @@
 interp = interpreter.Interpreter(space)
 def step_in_interp(ctxt): # due to missing resets in between tests
     interp._loop = False
-    return interp.step(ctxt)
+    return_value = interp.step(ctxt)
+    if return_value is not None:
+        return return_value.w_self()
+    return None
 
 # expose the bytecode's values as global constants.
 # Bytecodes that have a whole range are exposed as global functions:
@@ -88,8 +91,8 @@
     w_method.argsize=2
     w_method.tempsize=8
     w_method.setliterals([model.W_PointersObject(None, 2)])
-    w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"])
-    return w_frame, w_frame.as_context_get_shadow(space)
+    s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"])
+    return s_frame.w_self(), s_frame
 
 def test_create_frame():
     w_method = model.W_CompiledMethod(len("hello"))
@@ -97,8 +100,8 @@
     w_method.islarge = 1
     w_method.argsize=2
     w_method.tempsize=8
-    w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, "receiver", ["foo", "bar"])
-    s_frame = w_frame.as_context_get_shadow(space)
+    s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, "receiver", ["foo", "bar"])
+    w_frame = s_frame.w_self()
     assert s_frame.w_receiver() == "receiver"
     assert s_frame.gettemp(0) == "foo"
     assert s_frame.gettemp(1) == "bar"
@@ -976,7 +979,7 @@
     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), [])
+    w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []).w_self()
     try:
         interp.loop(w_frame)
     except interpreter.ReturnFromTopLevel, e:
@@ -1023,7 +1026,7 @@
     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), [])
+    w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, space.wrap_int(0), []).w_self()
     try:
         interp.loop(w_frame)
     except interpreter.ReturnFromTopLevel, e:
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
@@ -190,8 +190,9 @@
 
 def test_at():
     w_obj = mockclass(space, 0, varsized=True).as_class_get_shadow(space).new(1)
-    w_obj.store(space, 0, "foo")
-    assert prim(primitives.AT, [w_obj, 1]) == "foo"
+    foo = wrap("foo")
+    w_obj.store(space, 0, foo)
+    assert prim(primitives.AT, [w_obj, 1]) is foo
 
 def test_invalid_at():
     w_obj = mockclass(space, 0).as_class_get_shadow(space).new()
@@ -480,8 +481,8 @@
                                 size_arguments, copiedValues)
     s_initial_context.push_all([closure] + args)
     interp = interpreter.Interpreter(space)
-    w_active_context = prim_table[primitives.CLOSURE_VALUE + size_arguments](interp, s_initial_context, size_arguments)
-    return s_initial_context, closure, w_active_context.as_context_get_shadow(space)
+    s_active_context = prim_table[primitives.CLOSURE_VALUE + size_arguments](interp, s_initial_context, size_arguments)
+    return s_initial_context, closure, s_active_context
 
 def test_primitive_closure_value():
     s_initial_context, closure, s_new_context = build_up_closure_environment([])
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -230,7 +230,8 @@
         s_method = s_outerContext.w_method().as_compiledmethod_get_shadow(self.space)
         w_receiver = s_outerContext.w_receiver()
         w_new_frame = shadow.MethodContextShadow.make_context(self.space, s_method, w_receiver,
-                     arguments, w_sender=w_aContext, pc=self.startpc(), closure=self)
+                     arguments, s_sender=w_aContext.get_shadow(self.space), 
+                     pc=self.startpc(), closure=self)
         return w_new_frame
 
     def tempsize(self):


More information about the pypy-commit mailing list