[pypy-svn] r51867 - in pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk: . test

tverwaes at codespeak.net tverwaes at codespeak.net
Mon Feb 25 23:32:11 CET 2008


Author: tverwaes
Date: Mon Feb 25 23:32:10 2008
New Revision: 51867

Modified:
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py
Log:
slowed down the implementaton but made it more flexible by removing
W_*Context* and fully going in the direction of shadows.


Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py	Mon Feb 25 23:32:10 2008
@@ -1,7 +1,6 @@
 import py
 from pypy.lang.smalltalk import model, constants, primitives
 from pypy.lang.smalltalk import objtable
-from pypy.lang.smalltalk.model import W_ContextPart
 from pypy.lang.smalltalk.shadow import ContextPartShadow
 from pypy.lang.smalltalk.conftest import option
 from pypy.rlib import objectmodel, unroll
@@ -68,7 +67,7 @@
                     self._last_indent,
                     self.s_active_context().pc(),
                     next, bytecodeimpl.__name__,)
-            bytecodeimpl(self.w_active_context, self)
+            bytecodeimpl(self.s_active_context(), self)
         else:
             # this is a performance optimization: when translating the
             # interpreter, the bytecode dispatching is not implemented as a
@@ -76,7 +75,7 @@
             # below produces the switch (by being unrolled).
             for code, bytecodeimpl in unrolling_bytecode_table:
                 if code == next:
-                    bytecodeimpl(self.w_active_context, self)
+                    bytecodeimpl(self.s_active_context(), self)
                     break
 
         
@@ -87,10 +86,10 @@
 # ___________________________________________________________________________
 # Bytecode Implementations:
 #
-# "self" is always a W_ContextPart instance.  
+# "self" is always a ContextPartShadow instance.  
 
-# __extend__ adds new methods to the W_ContextPart class
-class __extend__(W_ContextPart):
+# __extend__ adds new methods to the ContextPartShadow class
+class __extend__(ContextPartShadow):
     # push bytecodes
     def pushReceiverVariableBytecode(self, interp):
         index = self.currentBytecode & 15
@@ -203,7 +202,7 @@
                         print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,)
                     pass # ignore this error and fall back to the Smalltalk version
         arguments = self.pop_and_return_n(argcount)
-        interp.w_active_context = method.create_frame(receiver, arguments, self) 
+        interp.w_active_context = method.create_frame(receiver, arguments, self.w_self()) 
         self.pop()
 
     def _return(self, object, interp, w_return_to):
@@ -513,77 +512,77 @@
 
 
 BYTECODE_RANGES = [
-            (  0,  15, W_ContextPart.pushReceiverVariableBytecode),
-            ( 16,  31, W_ContextPart.pushTemporaryVariableBytecode),
-            ( 32,  63, W_ContextPart.pushLiteralConstantBytecode),
-            ( 64,  95, W_ContextPart.pushLiteralVariableBytecode),
-            ( 96, 103, W_ContextPart.storeAndPopReceiverVariableBytecode),
-            (104, 111, W_ContextPart.storeAndPopTemporaryVariableBytecode),
-            (112, W_ContextPart.pushReceiverBytecode),
-            (113, W_ContextPart.pushConstantTrueBytecode),
-            (114, W_ContextPart.pushConstantFalseBytecode),
-            (115, W_ContextPart.pushConstantNilBytecode),
-            (116, W_ContextPart.pushConstantMinusOneBytecode),
-            (117, W_ContextPart.pushConstantZeroBytecode),
-            (118, W_ContextPart.pushConstantOneBytecode),
-            (119, W_ContextPart.pushConstantTwoBytecode),
-            (120, W_ContextPart.returnReceiver),
-            (121, W_ContextPart.returnTrue),
-            (122, W_ContextPart.returnFalse),
-            (123, W_ContextPart.returnNil),
-            (124, W_ContextPart.returnTopFromMethod),
-            (125, W_ContextPart.returnTopFromBlock),
-            (126, W_ContextPart.unknownBytecode),
-            (127, W_ContextPart.unknownBytecode),
-            (128, W_ContextPart.extendedPushBytecode),
-            (129, W_ContextPart.extendedStoreBytecode),
-            (130, W_ContextPart.extendedStoreAndPopBytecode),
-            (131, W_ContextPart.singleExtendedSendBytecode),
-            (132, W_ContextPart.doubleExtendedDoAnythingBytecode),
-            (133, W_ContextPart.singleExtendedSuperBytecode),
-            (134, W_ContextPart.secondExtendedSendBytecode),
-            (135, W_ContextPart.popStackBytecode),
-            (136, W_ContextPart.duplicateTopBytecode),
-            (137, W_ContextPart.pushActiveContextBytecode),
-            (138, 143, W_ContextPart.experimentalBytecode),
-            (144, 151, W_ContextPart.shortUnconditionalJump),
-            (152, 159, W_ContextPart.shortConditionalJump),
-            (160, 167, W_ContextPart.longUnconditionalJump),
-            (168, 171, W_ContextPart.longJumpIfTrue),
-            (172, 175, W_ContextPart.longJumpIfFalse),
-            (176, W_ContextPart.bytecodePrimAdd),
-            (177, W_ContextPart.bytecodePrimSubtract),
-            (178, W_ContextPart.bytecodePrimLessThan),
-            (179, W_ContextPart.bytecodePrimGreaterThan),
-            (180, W_ContextPart.bytecodePrimLessOrEqual),
-            (181, W_ContextPart.bytecodePrimGreaterOrEqual),
-            (182, W_ContextPart.bytecodePrimEqual),
-            (183, W_ContextPart.bytecodePrimNotEqual),
-            (184, W_ContextPart.bytecodePrimMultiply),
-            (185, W_ContextPart.bytecodePrimDivide),
-            (186, W_ContextPart.bytecodePrimMod),
-            (187, W_ContextPart.bytecodePrimMakePoint),
-            (188, W_ContextPart.bytecodePrimBitShift),
-            (189, W_ContextPart.bytecodePrimDiv),
-            (190, W_ContextPart.bytecodePrimBitAnd),
-            (191, W_ContextPart.bytecodePrimBitOr),
-            (192, W_ContextPart.bytecodePrimAt),
-            (193, W_ContextPart.bytecodePrimAtPut),
-            (194, W_ContextPart.bytecodePrimSize),
-            (195, W_ContextPart.bytecodePrimNext),
-            (196, W_ContextPart.bytecodePrimNextPut),
-            (197, W_ContextPart.bytecodePrimAtEnd),
-            (198, W_ContextPart.bytecodePrimEquivalent),
-            (199, W_ContextPart.bytecodePrimClass),
-            (200, W_ContextPart.bytecodePrimBlockCopy),
-            (201, W_ContextPart.bytecodePrimValue),
-            (202, W_ContextPart.bytecodePrimValueWithArg),
-            (203, W_ContextPart.bytecodePrimDo),
-            (204, W_ContextPart.bytecodePrimNew),
-            (205, W_ContextPart.bytecodePrimNewWithArg),
-            (206, W_ContextPart.bytecodePrimPointX),
-            (207, W_ContextPart.bytecodePrimPointY),
-            (208, 255, W_ContextPart.sendLiteralSelectorBytecode),
+            (  0,  15, ContextPartShadow.pushReceiverVariableBytecode),
+            ( 16,  31, ContextPartShadow.pushTemporaryVariableBytecode),
+            ( 32,  63, ContextPartShadow.pushLiteralConstantBytecode),
+            ( 64,  95, ContextPartShadow.pushLiteralVariableBytecode),
+            ( 96, 103, ContextPartShadow.storeAndPopReceiverVariableBytecode),
+            (104, 111, ContextPartShadow.storeAndPopTemporaryVariableBytecode),
+            (112, ContextPartShadow.pushReceiverBytecode),
+            (113, ContextPartShadow.pushConstantTrueBytecode),
+            (114, ContextPartShadow.pushConstantFalseBytecode),
+            (115, ContextPartShadow.pushConstantNilBytecode),
+            (116, ContextPartShadow.pushConstantMinusOneBytecode),
+            (117, ContextPartShadow.pushConstantZeroBytecode),
+            (118, ContextPartShadow.pushConstantOneBytecode),
+            (119, ContextPartShadow.pushConstantTwoBytecode),
+            (120, ContextPartShadow.returnReceiver),
+            (121, ContextPartShadow.returnTrue),
+            (122, ContextPartShadow.returnFalse),
+            (123, ContextPartShadow.returnNil),
+            (124, ContextPartShadow.returnTopFromMethod),
+            (125, ContextPartShadow.returnTopFromBlock),
+            (126, ContextPartShadow.unknownBytecode),
+            (127, ContextPartShadow.unknownBytecode),
+            (128, ContextPartShadow.extendedPushBytecode),
+            (129, ContextPartShadow.extendedStoreBytecode),
+            (130, ContextPartShadow.extendedStoreAndPopBytecode),
+            (131, ContextPartShadow.singleExtendedSendBytecode),
+            (132, ContextPartShadow.doubleExtendedDoAnythingBytecode),
+            (133, ContextPartShadow.singleExtendedSuperBytecode),
+            (134, ContextPartShadow.secondExtendedSendBytecode),
+            (135, ContextPartShadow.popStackBytecode),
+            (136, ContextPartShadow.duplicateTopBytecode),
+            (137, ContextPartShadow.pushActiveContextBytecode),
+            (138, 143, ContextPartShadow.experimentalBytecode),
+            (144, 151, ContextPartShadow.shortUnconditionalJump),
+            (152, 159, ContextPartShadow.shortConditionalJump),
+            (160, 167, ContextPartShadow.longUnconditionalJump),
+            (168, 171, ContextPartShadow.longJumpIfTrue),
+            (172, 175, ContextPartShadow.longJumpIfFalse),
+            (176, ContextPartShadow.bytecodePrimAdd),
+            (177, ContextPartShadow.bytecodePrimSubtract),
+            (178, ContextPartShadow.bytecodePrimLessThan),
+            (179, ContextPartShadow.bytecodePrimGreaterThan),
+            (180, ContextPartShadow.bytecodePrimLessOrEqual),
+            (181, ContextPartShadow.bytecodePrimGreaterOrEqual),
+            (182, ContextPartShadow.bytecodePrimEqual),
+            (183, ContextPartShadow.bytecodePrimNotEqual),
+            (184, ContextPartShadow.bytecodePrimMultiply),
+            (185, ContextPartShadow.bytecodePrimDivide),
+            (186, ContextPartShadow.bytecodePrimMod),
+            (187, ContextPartShadow.bytecodePrimMakePoint),
+            (188, ContextPartShadow.bytecodePrimBitShift),
+            (189, ContextPartShadow.bytecodePrimDiv),
+            (190, ContextPartShadow.bytecodePrimBitAnd),
+            (191, ContextPartShadow.bytecodePrimBitOr),
+            (192, ContextPartShadow.bytecodePrimAt),
+            (193, ContextPartShadow.bytecodePrimAtPut),
+            (194, ContextPartShadow.bytecodePrimSize),
+            (195, ContextPartShadow.bytecodePrimNext),
+            (196, ContextPartShadow.bytecodePrimNextPut),
+            (197, ContextPartShadow.bytecodePrimAtEnd),
+            (198, ContextPartShadow.bytecodePrimEquivalent),
+            (199, ContextPartShadow.bytecodePrimClass),
+            (200, ContextPartShadow.bytecodePrimBlockCopy),
+            (201, ContextPartShadow.bytecodePrimValue),
+            (202, ContextPartShadow.bytecodePrimValueWithArg),
+            (203, ContextPartShadow.bytecodePrimDo),
+            (204, ContextPartShadow.bytecodePrimNew),
+            (205, ContextPartShadow.bytecodePrimNewWithArg),
+            (206, ContextPartShadow.bytecodePrimPointX),
+            (207, ContextPartShadow.bytecodePrimPointY),
+            (208, 255, ContextPartShadow.sendLiteralSelectorBytecode),
             ]
 
 

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py	Mon Feb 25 23:32:10 2008
@@ -125,7 +125,7 @@
         return self.w_class
 
     def __repr__(self):
-        return "<%s %s at %r>" % (self.__class__.__name__, self, self.gethash())
+        return "<%s %s>" % (self.__class__.__name__, self)
 
     def __str__(self):
         if isinstance(self, W_PointersObject) and self._shadow is not None:
@@ -380,7 +380,6 @@
         from pypy.lang.smalltalk import objtable
         assert len(arguments) == self.argsize
         w_new = W_MethodContext(self, receiver, arguments, sender)
-        objtable.objects += [w_new]
         return w_new
 
     def __str__(self):
@@ -432,6 +431,7 @@
         self.tempsize = tempsize
         self.primitive = primitive
         self.w_compiledin = None
+        self.islarge = islarge
 
     def literalat0(self, index0):
         if index0 == 0:
@@ -486,313 +486,33 @@
         self.bytes = (self.bytes[:index0] + character +
                       self.bytes[index0 + 1:])
 
-class W_ContextPart(W_AbstractObjectWithIdentityHash):
-
-    __metaclass__ = extendabletype
-    
-    def __init__(self, w_home, w_sender):
-        self._stack = []
-        self._pc = 0
-        #assert isinstance(s_home, W_MethodContext)
-        self._w_home = w_home
-        #assert w_sender is None or isinstance(w_sender, W_ContextPart)
-        self._w_sender = w_sender
-
-    def as_context_get_shadow(self):
-        # Backward compatibility
-        return self
-
-    def w_self(self):
-        # Backward compatibility
-        return self
-
-    def pc(self):
-        return self._pc
-
-    def stack(self):
-        return self._stack
-
-    def store_pc(self, pc):
-        self._pc = pc
-
-    def w_receiver(self):
-        " Return self of the method, or the method that contains the block "
-        return self.s_home().w_receiver()
-
-    def w_home(self):
-        return self._w_home
-
-    def s_home(self):
-        return self.w_home().as_methodcontext_get_shadow()
-
-    def store_w_home(self, w_home):
-        self._w_home = w_home
-
-    def w_sender(self):
-        if self._w_sender is not None:
-            return self._w_sender    
-        else:    
-            from pypy.lang.smalltalk import objtable
-            return objtable.w_nil
-
-    def store_w_sender(self, w_sender):
-        self._w_sender = w_sender
-
-    def stackpointer(self):
-        return len(self.stack()) + self.stackstart() - 1
-    # ______________________________________________________________________
-    # Imitate the primitive accessors
-    
-    def fetch(self, index):
-        from pypy.lang.smalltalk import utility, objtable
-        if index == constants.CTXPART_SENDER_INDEX:
-            return self.w_sender()
-        elif index == constants.CTXPART_PC_INDEX:
-            return utility.wrap_int(self.pc())
-        elif index == constants.CTXPART_STACKP_INDEX:
-            return utility.wrap_int(self.stackpointer())
-        
-        # Invalid!
-        raise IndexError
-
-    def store(self, index, w_value):
-        # XXX Untested code...
-        from pypy.lang.smalltalk import utility, objtable
-        if index == constants.CTXPART_SENDER_INDEX:
-            if w_value != objtable.w_nil:
-                self.store_w_sender(w_value)
-        elif index == constants.CTXPART_PC_INDEX:
-            self._pc = utility.unwrap_int(w_value)
-        elif index == constants.CTXPART_STACKP_INDEX:
-            size = utility.unwrap_int(w_value)
-            size = 1 + size - self.stackstart()
-            self._stack = [objtable.w_nil] * size
-        else:
-            # Invalid!
-            raise IndexError
-
-    def become(self, w_old, w_new):
-        if self.w_sender() == w_old:
-            self.store_w_sender(w_new)
-        for i in range(len(self._stack)):
-            if self._stack[i] == w_old:
-                self._stack[i] = w_new
-        if self.w_home() == w_old:
-            self.store_w_home(w_new)
-
-    def stackstart(self):
-        return constants.MTHDCTX_TEMP_FRAME_START
-
-    # ______________________________________________________________________
-    # Method that contains the bytecode for this method/block context
-
-    def w_method(self):
-        return self.s_home().w_method()
-
-    def getbytecode(self):
-        pc = self.pc()
-        bytecode = self.w_method().bytes[pc]
-        currentBytecode = ord(bytecode)
-        self.store_pc(pc + 1)
-        return currentBytecode
-
-    def getNextBytecode(self):
-        self.currentBytecode = self.getbytecode()
-        return self.currentBytecode
-
-    # ______________________________________________________________________
-    # Temporary Variables
-    #
-    # Are always fetched relative to the home method context.
-    
-    def gettemp(self, index):
-        return self.s_home().gettemp(index)
-
-    def settemp(self, index, w_value):
-        self.s_home().settemp(index, w_value)
-
-    # ______________________________________________________________________
-    # Stack Manipulation
-
-    def pop(self):
-        return self.stack().pop()
-
-    def push(self, w_v):
-        assert w_v
-        self.stack().append(w_v)
-
-    def push_all(self, lst):
-        " Equivalent to 'for x in lst: self.push(x)' where x is a lst "
-        assert None not in lst
-        self._stack += lst
-
-    def top(self):
-        return self.peek(0)
-        
-    def peek(self, idx):
-        return self.stack()[-(idx+1)]
-
-    def pop_n(self, n):
-        assert n >= 0
-        start = len(self.stack()) - n
-        assert start >= 0          # XXX what if this fails?
-        del self.stack()[start:]
-
-    def pop_and_return_n(self, n):
-        assert n >= 0
-        start = len(self.stack()) - n
-        assert start >= 0          # XXX what if this fails?
-        res = self.stack()[start:]
-        del self.stack()[start:]
-        return res
-
-class W_BlockContext(W_ContextPart):
-
-    def __init__(self, w_home, w_sender, argcnt, initialip):
-        W_ContextPart.__init__(self, w_home, w_sender)
-        self.argcnt = argcnt
-        self._initialip = initialip
-
-    def initialip(self):
-        return self._initialip
-
-    def expected_argument_count(self):
-        return self.argcnt
-        
-    def getclass(self):
-        from pypy.lang.smalltalk.classtable import w_BlockContext
-        return w_BlockContext
-
-    def as_blockcontext_get_shadow(self):
-        # Backwards compatibility
-        return self
-    
-    def fetch(self, index):
-        from pypy.lang.smalltalk import utility
-        if index == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
-            return utility.wrap_int(self.argcnt)
-        elif index == constants.BLKCTX_INITIAL_IP_INDEX:
-            return utility.wrap_int(self.initialip)
-        elif index == constants.BLKCTX_HOME_INDEX:
-            return self.w_home()
-        elif index >= constants.BLKCTX_TEMP_FRAME_START:
-            stack_index = len(self.stack()) - index - 1
-            return self.stack()[stack_index]
-        else:
-            return W_ContextPart.fetch(self, index)
-
-    def store(self, index, value):
-        # THIS IS ALL UNTESTED CODE and we're a bit unhappy about it
-        # because it crashd the translation N+4 times :-(
-        from pypy.lang.smalltalk import utility
-        if index == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
-            self.argcnt = utility.unwrap_int(value)
-        elif index == constants.BLKCTX_INITIAL_IP_INDEX:
-            self.pc = utility.unwrap_int(value)
-        elif index == constants.BLKCTX_HOME_INDEX:
-            self.store_w_home(value)
-        elif index >= constants.BLKCTX_TEMP_FRAME_START:
-            stack_index = len(self.stack()) - index - 1
-            self.stack()[stack_index] = value
-        else:
-            W_ContextPart.store(self, index, value)
-
-    def stackstart(self):
-        return constants.BLKCTX_TEMP_FRAME_START
-
-class W_MethodContext(W_ContextPart):
-    def __init__(self, w_method, w_receiver,
-                 arguments, w_sender=None):
-        W_ContextPart.__init__(self, self, w_sender)
-        self._w_method = w_method
-        self._w_receiver = w_receiver
-        self.temps = arguments + [w_nil] * w_method.tempsize
-
-    def as_methodcontext_get_shadow(self):
-        # Backwards compatibility
-        return self
-
-    def getclass(self):
-        from pypy.lang.smalltalk.classtable import w_MethodContext
-        return w_MethodContext
-
-    def w_receiver(self):
-        return self._w_receiver
-
-    def store_w_receiver(self, w_receiver):
-        self._w_receiver = w_receiver
-
-    def become(self, w_old, w_new):
-        W_ContextPart.become(self, w_old, w_new)
-        for i in range(len(self.temps)):
-            if self.temps[i] == w_old:
-                self.temps[i] = w_new
-        if w_old == self._w_receiver:
-            self._w_receiver = w_new
-        if w_old == self._w_method:
-            self._w_method = w_new
-
-    def at0(self, index0):
-        # XXX to test
-        # Fetches in temppart (variable size)
-        return self.fetch(index0+constants.MTHDCTX_TEMP_FRAME_START)
-
-    def atput0(self, index0, w_v):
-        # XXX to test
-        # Stores in temppart (variable size)
-        return self.store(index0+constants.MTHDCTX_TEMP_FRAME_START, w_v)
-
-    def fetch(self, index):
-        if index == constants.MTHDCTX_METHOD:
-            return self.w_method()
-        elif index == constants.MTHDCTX_RECEIVER_MAP: # what is this thing?
-            return w_nil
-        elif index == constants.MTHDCTX_RECEIVER:
-            return self.w_receiver()
-        elif index >= constants.MTHDCTX_TEMP_FRAME_START:
-            # First set of indices are temporary variables:
-            offset = index - constants.MTHDCTX_TEMP_FRAME_START
-            if offset < len(self.temps):
-                return self.temps[offset]
-
-            # After that comes the stack:
-            offset -= len(self.temps)
-            stack_index = len(self.stack()) - offset - 1
-            return self.stack()[stack_index]
-        else:
-            return W_ContextPart.fetch(self, index)
-
-    def store(self, index, w_object):
-        if index == constants.MTHDCTX_METHOD:
-            self._w_method = w_object
-        elif index == constants.MTHDCTX_RECEIVER_MAP: # what is this thing?
-            pass
-        elif index == constants.MTHDCTX_RECEIVER:
-            self.store_w_receiver(w_object)
-        elif index >= constants.MTHDCTX_TEMP_FRAME_START:
-            # First set of indices are temporary variables:
-            offset = index - constants.MTHDCTX_TEMP_FRAME_START
-            if offset < len(self.temps):
-                self.temps[offset] = w_object
-
-            # After that comes the stack:
-            offset -= len(self.temps)
-            stack_index = len(self.stack()) - offset - 1
-            self.stack()[stack_index] = w_object
-        else:
-            W_ContextPart.store(self, index, w_object)
-
-    def gettemp(self, idx):
-        return self.temps[idx]
-
-    def settemp(self, idx, w_value):
-        self.temps[idx] = w_value
-
-    def w_method(self):
-        return self._w_method
-
-    def size(self):
-        return len(self.temps) + len(self.stack())
+def W_BlockContext(w_home, w_sender, argcnt, initialip):
+    from pypy.lang.smalltalk.classtable import w_BlockContext
+    w_result = W_PointersObject(w_BlockContext, w_home.size())
+    s_result = w_result.as_blockcontext_get_shadow()
+    s_result.store_expected_argument_count(argcnt)
+    s_result.store_initialip(initialip)
+    s_result.store_w_home(w_home)
+    s_result.store_stackpointer(s_result.stackstart())
+    return w_result
+
+def W_MethodContext(w_method, w_receiver,
+                    arguments, w_sender=None):
+    from pypy.lang.smalltalk.classtable import w_MethodContext
+    # From blue book: normal mc have place for 12 temps+maxstack
+    # mc for methods with islarge flag turned on 32
+    size = 12 + w_method.islarge * 20 + w_method.argsize
+    w_result = w_MethodContext.as_class_get_shadow().new(size)
+    s_result = w_result.as_methodcontext_get_shadow()
+    s_result.store_w_method(w_method)
+    if w_sender:
+        s_result.store_w_sender(w_sender)
+    s_result.store_w_receiver(w_receiver)
+    s_result.store_pc(w_method.getliteralsize()+1)
+    for i in range(len(arguments)):
+        s_result.settemp(i, arguments[i])
+    s_result.store_stackpointer(s_result.stackstart())
+    return w_result
 
 # Use black magic to create w_nil without running the constructor,
 # thus allowing it to be used even in the constructor of its own

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py	Mon Feb 25 23:32:10 2008
@@ -68,7 +68,7 @@
                 w_result = func(interp, argument_count_m1)
                 if not no_result:
                     assert w_result is not None
-                    interp.w_active_context.as_context_get_shadow().push(w_result)
+                    interp.s_active_context().push(w_result)
                 return w_result
         else:
             len_unwrap_spec = len(unwrap_spec)
@@ -104,7 +104,7 @@
                 w_result = func(interp, *args)
                 # After calling primitive, reload context-shadow in case it
                 # needs to be updated
-                new_s_frame = interp.w_active_context.as_context_get_shadow()
+                new_s_frame = interp.s_active_context()
                 frame.as_context_get_shadow().pop_n(len_unwrap_spec)   # only if no exception occurs!
                 if not no_result:
                     assert w_result is not None
@@ -397,7 +397,6 @@
     "Stores a value into a fixed field from the object, and fails otherwise"
     s_class = w_rcvr.shadow_of_my_class()
     assert_bounds(n0, 0, s_class.instsize())
-    # only pointers have non-0 size    
     # XXX Now MethodContext is still own format, leave
     #assert isinstance(w_rcvr, model.W_PointersObject)
     w_rcvr.store(n0, w_value)
@@ -622,21 +621,19 @@
 
 @expose_primitive(PRIMITIVE_BLOCK_COPY, unwrap_spec=[object, int])
 def func(interp, w_context, argcnt):
-    frame = interp.w_active_context.as_context_get_shadow()
+    frame = interp.s_active_context()
 
     # From B.B.: If receiver is a MethodContext, then it becomes
     # the new BlockContext's home context.  Otherwise, the home
     # context of the receiver is used for the new BlockContext.
     # Note that in our impl, MethodContext.w_home == self
-    if not isinstance(w_context, model.W_ContextPart):
-        raise PrimitiveFailedError()
     w_method_context = w_context.as_context_get_shadow().w_home()
 
     # The block bytecodes are stored inline: so we skip past the
     # byteodes to invoke this primitive to find them (hence +2)
     initialip = frame.pc() + 2
     w_new_context = model.W_BlockContext(
-        w_method_context, None, argcnt, initialip)
+        w_method_context, objtable.w_nil, argcnt, initialip)
     return w_new_context
 
 def finalize_block_ctx(interp, s_block_ctx, frame):
@@ -653,14 +650,16 @@
     #  Rcvr | Arg 0 | Arg1 | Arg 2
     #
     
-    frame = interp.w_active_context.as_context_get_shadow()
+    frame = interp.s_active_context()
     
     # Validate that we have a block on the stack and that it received
     # the proper number of arguments:
     w_block_ctx = frame.peek(argument_count)
     if w_block_ctx.getclass() != classtable.w_BlockContext:
         raise PrimitiveFailedError()
+
     s_block_ctx = w_block_ctx.as_blockcontext_get_shadow()
+
     exp_arg_cnt = s_block_ctx.expected_argument_count()
     if argument_count != exp_arg_cnt: # exp_arg_cnt doesn't count self
         raise PrimitiveFailedError()
@@ -668,6 +667,9 @@
     # Initialize the block stack with the arguments that were
     # pushed.  Also pop the receiver.
     block_args = frame.pop_and_return_n(exp_arg_cnt)
+
+    # Reset stack of blockcontext to []
+    s_block_ctx.store_stackpointer(s_block_ctx.stackstart())
     s_block_ctx.push_all(block_args)
 
     frame.pop()
@@ -710,7 +712,6 @@
     w_frame.as_context_get_shadow().store_w_sender(interp.w_active_context)
     interp.w_active_context = w_frame
 
-
 @expose_primitive(PRIMITIVE_SIGNAL, unwrap_spec=[object])
 def func(interp, w_rcvr):
     if w_rcvr.getclass() != classtable.classtable['w_Semaphore']:

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py	Mon Feb 25 23:32:10 2008
@@ -150,21 +150,6 @@
     def new(self, extrasize=0, store=True):
         from pypy.lang.smalltalk import classtable
         w_cls = self.w_self()
-        
-        if w_cls == classtable.w_BlockContext:
-            w_new = model.W_BlockContext(None, None, 0, 0)
-        elif w_cls == classtable.w_MethodContext:
-            # From slang: Contexts must only be created with newForMethod:
-            # raise error.PrimitiveFailedError
-            # XXX XXX XXX XXX
-            # The above text is bogous. This does not come from slang but a
-            # method implementation of ContextPart in Squeak3.9 which
-            # overwrites the default compiledmethod to give this error.
-            # The mini.image -however- doesn't overwrite this method, and as
-            # far as I was able to trace it back, it -does- call this method.
-            from pypy.rlib.objectmodel import instantiate
-            w_new = instantiate(model.W_MethodContext)
-            
         if self.instance_kind == POINTERS:
             w_new = model.W_PointersObject(w_cls, self.instance_size+extrasize)
         elif self.instance_kind == WORDS:
@@ -391,43 +376,16 @@
     def process_lists(self):
         return self.w_self().fetch(constants.SCHEDULER_PROCESS_LISTS_INDEX)
 
-# XXX This should be changed once everything works using contextshadows
-# current hack to make the class extension-system for bytecode lookup happy...
-# Should be AbstractShadow
-# XXX XXX
-class ContextPartShadow(model.W_ContextPart):
+class ContextPartShadow(AbstractShadow):
 
-    #__metaclass__ = extendabletype
+    __metaclass__ = extendabletype
     
     def __init__(self, w_self):
-        self._w_self = w_self
-        self.invalidate()
+        AbstractShadow.__init__(self, w_self)
 
     def s_home(self):
         raise NotImplementedError()
 
-    # XXX XXX Remove function when fixing superclass to AbstractShadow
-    def w_self(self):
-        return self._w_self
-
-    # XXX XXX Remove function when fixing superclass to AbstractShadow
-    def invalidate(self):
-        self.invalid = True
-
-    # XXX XXX Remove function when fixing superclass to AbstractShadow
-    def check_for_updates(self):
-        if self.invalid:
-            self.w_self().setshadow(self)
-            self.update_shadow()
-
-    # XXX XXX Remove function when fixing superclass to AbstractShadow
-    def update_shadow(self):
-        pass
-
-    # XXX XXX Remove function when fixing superclass to AbstractShadow
-    def getname(self):
-        return repr(self)
-
     def w_receiver(self):
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
@@ -443,7 +401,7 @@
         else:
             return w_sender.as_context_get_shadow()
 
-    def store_w_sender(self, s_sender):
+    def store_w_sender(self, w_sender):
         self.w_self().store(constants.CTXPART_SENDER_INDEX, w_sender)
 
     def pc(self):
@@ -516,7 +474,8 @@
         self.store_stackpointer(self.stackpointer() - n)
 
     def stack(self):
-        return [self.w_self().fetch(i) for i in range(self.stackstart(), self.stackpointer() + 1)]
+                                                      # fetch = 1-based
+        return [self.w_self().fetch(i) for i in range(self.stackstart() + 1, self.stackpointer() + 1)]
 
     def pop_and_return_n(self, n):
         self.pop_n(n)
@@ -538,6 +497,13 @@
     def initialip(self):
         return utility.unwrap_int(self.w_self().fetch(constants.BLKCTX_INITIAL_IP_INDEX))
         
+    def store_initialip(self, initialip):
+        self.w_self().store(constants.BLKCTX_INITIAL_IP_INDEX,
+                            utility.wrap_int(initialip))
+        
+    def store_w_home(self, w_home):
+        self.w_self().store(constants.BLKCTX_HOME_INDEX, w_home)
+
     def w_home(self):
         return self.w_self().fetch(constants.BLKCTX_HOME_INDEX)
 
@@ -545,7 +511,8 @@
         return self.w_home().as_methodcontext_get_shadow()
         
     def stackstart(self):
-        return constants.BLKCTX_TEMP_FRAME_START
+        return (constants.BLKCTX_TEMP_FRAME_START +
+                self.expected_argument_count())
 
 class MethodContextShadow(ContextPartShadow):
     def __init__(self, w_self):
@@ -554,6 +521,9 @@
     def w_method(self):
         return self.w_self().fetch(constants.MTHDCTX_METHOD)
 
+    def store_w_method(self, w_method):
+        return self.w_self().store(constants.MTHDCTX_METHOD, w_method)
+
     def w_receiver(self):
         return self.w_self().fetch(constants.MTHDCTX_RECEIVER)
 
@@ -573,4 +543,6 @@
         return self
 
     def stackstart(self):
-        return constants.MTHDCTX_TEMP_FRAME_START
+        return (constants.MTHDCTX_TEMP_FRAME_START +
+                self.w_method().argsize +
+                self.w_method().tempsize)

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py	Mon Feb 25 23:32:10 2008
@@ -69,9 +69,10 @@
 def new_interpreter(bytes, receiver=objtable.w_nil):
     assert isinstance(bytes, str)
     w_method = model.W_CompiledMethod(len(bytes))
+    w_method.islarge = 1
     w_method.bytes = bytes
     w_method.argsize=2
-    w_method.tempsize=1
+    w_method.tempsize=8
     w_frame = w_method.create_frame(receiver, ["foo", "bar"])
     interp = interpreter.Interpreter()
     interp.w_active_context = w_frame
@@ -80,18 +81,20 @@
 def test_create_frame():
     w_method = model.W_CompiledMethod(len("hello"))
     w_method.bytes="hello"
+    w_method.islarge = 1
     w_method.argsize=2
-    w_method.tempsize=1
+    w_method.tempsize=8
     w_frame = w_method.create_frame("receiver", ["foo", "bar"])
-    assert w_frame.w_receiver() == "receiver"
-    assert w_frame.gettemp(0) == "foo"
-    assert w_frame.gettemp(1) == "bar"
-    assert w_frame.gettemp(2) is objtable.w_nil
-    w_frame.settemp(2, "spam")
-    assert w_frame.gettemp(2) == "spam"
-    assert w_frame.getNextBytecode() == ord("h")
-    assert w_frame.getNextBytecode() == ord("e")
-    assert w_frame.getNextBytecode() == ord("l")
+    s_frame = w_frame.as_context_get_shadow()
+    assert s_frame.w_receiver() == "receiver"
+    assert s_frame.gettemp(0) == "foo"
+    assert s_frame.gettemp(1) == "bar"
+    assert s_frame.gettemp(2) is objtable.w_nil
+    s_frame.settemp(2, "spam")
+    assert s_frame.gettemp(2) == "spam"
+    assert s_frame.getNextBytecode() == ord("h")
+    assert s_frame.getNextBytecode() == ord("e")
+    assert s_frame.getNextBytecode() == ord("l")
 
 def test_push_pop():
     interp = new_interpreter("")
@@ -185,15 +188,17 @@
 def test_storeAndPopTemporaryVariableBytecode(bytecode=storeAndPopTemporaryVariableBytecode):
     for index in range(8):
         interp = new_interpreter(pushConstantTrueBytecode + bytecode(index))
-        interp.w_active_context.as_methodcontext_get_shadow().temps = [None] * 8
+        #interp.w_active_context.as_methodcontext_get_shadow().temps = [None] * 8
         interp.step()
         interp.step()
         assert interp.s_active_context().stack() == []
+        interp.w_active_context.as_methodcontext_get_shadow()
         for test_index in range(8):
+            print interp.w_active_context._vars
             if test_index == index:
-                assert interp.w_active_context.as_methodcontext_get_shadow().temps[test_index] == interp.TRUE
+                assert interp.s_active_context().gettemp(test_index) == interp.TRUE
             else:
-                assert interp.w_active_context.as_methodcontext_get_shadow().temps[test_index] == None
+                assert interp.s_active_context().gettemp(test_index) != interp.TRUE
 
 def test_pushConstantTrueBytecode():
     interp = new_interpreter(pushConstantTrueBytecode)
@@ -398,7 +403,7 @@
         assert interp.s_active_context().stack() == []
         assert interp.w_active_context.as_methodcontext_get_shadow().w_receiver() == w_object
         assert interp.w_active_context.as_methodcontext_get_shadow().w_method() == shadow.methoddict["foo"]
-        assert callerContext.stack() == []
+        assert callerContext.as_context_get_shadow().stack() == []
         interp.step()
         interp.step()
         assert interp.w_active_context == callerContext
@@ -448,7 +453,7 @@
 def test_longJumpIfTrue():
     interp = new_interpreter(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15))
     interp.s_active_context().push(interp.FALSE)
-    pc = interp.w_active_context.pc() + 2
+    pc = interp.s_active_context().pc() + 2
     interp.step()
     assert interp.s_active_context().pc() == pc
     interp.s_active_context().push(interp.TRUE)
@@ -605,7 +610,7 @@
         assert interp.w_active_context.as_methodcontext_get_shadow().w_receiver() == w_object
         meth = w_specificclass.as_class_get_shadow().methoddict["foo"]
         assert interp.w_active_context.as_methodcontext_get_shadow().w_method() == meth
-        assert callerContext.stack() == []
+        assert callerContext.as_context_get_shadow().stack() == []
 
 def test_secondExtendedSendBytecode():
     w_class = mockclass(0)

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py	Mon Feb 25 23:32:10 2008
@@ -204,12 +204,9 @@
     w_frame = w_method.create_frame(w_object, [])
     interp.w_active_context = w_frame
 
-    print w_method
-
     while True:
         try:
             interp.step()
-            print interp.s_active_context().stack()
         except interpreter.ReturnFromTopLevel, e:
             assert e.object.value == abs(int)
             return

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py	Mon Feb 25 23:32:10 2008
@@ -9,9 +9,12 @@
 
 mockclass = classtable.bootstrap_class
 
-class MockFrame(model.W_MethodContext):
+class MockFrame(model.W_PointersObject):
     def __init__(self, stack):
-        self._stack = stack
+        self._vars = [None] * 6 + stack
+        s_self = self.as_blockcontext_get_shadow()
+        s_self.store_expected_argument_count(0)
+        s_self.store_stackpointer(s_self.stackstart()+len(stack)-1) 
 
 def wrap(x):
     if isinstance(x, int): return utility.wrap_int(x)

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py	Mon Feb 25 23:32:10 2008
@@ -88,7 +88,7 @@
 
 def methodcontext(w_sender=objtable.w_nil, pc=1, stackpointer=0, stacksize=5,
                   method=method()):
-    stackstart = 7 # (len notation, not idx notation)
+    stackstart = 6+method.argsize+method.tempsize # (len notation, not idx notation)
     w_object = model.W_PointersObject(classtable.w_MethodContext, stackstart+stacksize)
     w_object.store(constants.CTXPART_SENDER_INDEX, w_sender)
     w_object.store(constants.CTXPART_PC_INDEX, utility.wrap_int(pc))
@@ -98,20 +98,12 @@
     w_object.store(constants.MTHDCTX_RECEIVER_MAP, '???')
     w_object.store(constants.MTHDCTX_RECEIVER, 'receiver')
 
-    # XXX Might want to check the realness of the next assumption,
-    # XXX made by hooking into the suspended thread of the image.
-    # XXX it seems the only possibility, and using this assumption
-    # XXX it actually runs...
-    # Weirdly enough, undependant from the size of the tempsize and
-    # argsize, the stackpointer can point to anything starting from
-    # the temp_frame_start. That's why stacks always print all elements
-    # including possible "temps or args"
     w_object.store(constants.MTHDCTX_TEMP_FRAME_START, 'el')
     return w_object
 
 def test_context():
     w_m = method()
-    w_object = methodcontext(stackpointer=2, method=w_m)
+    w_object = methodcontext(stackpointer=3, method=w_m)
     w_object2 = methodcontext(w_sender=w_object)
     s_object = w_object.as_methodcontext_get_shadow()
     s_object2 = w_object2.as_methodcontext_get_shadow()
@@ -131,7 +123,7 @@
     w_object.store(idx + 2, 'g')
     w_object.store(idx + 3, 'h')
     assert s_object.top() == 'h'
-    assert s_object.stack() == ['el', 'f', 'g', 'h' ]
+    assert s_object.stack() == ['f', 'g', 'h' ]
     s_object.push('i')
     assert s_object.top() == 'i'
     assert s_object.peek(1) == 'h'



More information about the Pypy-commit mailing list