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

tverwaes at codespeak.net tverwaes at codespeak.net
Tue May 20 15:54:49 CEST 2008


Author: tverwaes
Date: Tue May 20 15:54:47 2008
New Revision: 54997

Modified:
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/classtable.py
   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/objtable.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_model.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:
(cfbolz, tverwaes) making all current tests work with new style of
contextshadows


Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/classtable.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/classtable.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/classtable.py	Tue May 20 15:54:47 2008
@@ -1,21 +1,23 @@
 from pypy.lang.smalltalk import shadow, constants
 from pypy.lang.smalltalk import constants
+from pypy.rlib.objectmodel import instantiate
 
 def bootstrap_class(instsize, w_superclass=None, w_metaclass=None,
                     name='?', format=shadow.POINTERS, varsized=False):
     from pypy.lang.smalltalk import model
     w_class = model.W_PointersObject(w_metaclass, 0)
                                              # a dummy placeholder for testing
-    s = shadow.ClassShadow(w_class, True)
-    s.methoddict = {}
-    if w_superclass is not None:
-        s.w_superclass = w_superclass
+    # XXX
+    s = instantiate(shadow.ClassShadow)
+    s._w_self = w_class
+    s.w_superclass = w_superclass
     s.name = name
     s.instance_size = instsize
     s.instance_kind = format
+    s.w_methoddict = None
     s.instance_varsized = varsized or format != shadow.POINTERS
     s.invalid = False
-    w_class._shadow = s
+    w_class.store_shadow(s)
     return w_class
 
 # ___________________________________________________________________________
@@ -65,8 +67,11 @@
         define_core_cls(cls_nm, classtable[super_cls_nm], w_metacls)
     w_Class = classtable["w_Class"]
     w_Metaclass = classtable["w_Metaclass"]
-    w_ProtoObjectClass.as_class_get_shadow().w_superclass = \
-        w_Class
+    # XXX
+    proto_shadow = instantiate(shadow.ClassShadow)
+    proto_shadow.invalid = False
+    proto_shadow.w_superclass = w_Class
+    w_ProtoObjectClass.store_shadow(proto_shadow)
     # at this point, all classes that still lack a w_class are themselves
     # metaclasses
     for nm, w_cls_obj in classtable.items():

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	Tue May 20 15:54:47 2008
@@ -69,7 +69,7 @@
                         cnt += 1
                                                   # Do not update the context
                                                   # for this action.
-                        p = p.as_context_get_shadow(False).w_sender()
+                        p = p.as_context_get_shadow().w_sender()
                     self._last_indent = "  " * cnt
                     self._w_last_active_context = self.w_active_context()
 

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	Tue May 20 15:54:47 2008
@@ -262,20 +262,25 @@
 
     # XXX XXX
     # Find better way of overloading shadows...
-    def setshadow(self, shadow):
+    def store_shadow(self, shadow):
         self._shadow = shadow
 
     @objectmodel.specialize.arg(1)
-    def as_special_get_shadow(self, TheClass, invalid=True):
+    def attach_shadow_of_class(self, TheClass):
+        shadow = TheClass(self)
+        self._shadow = shadow
+        shadow.attach_shadow()
+        return shadow
+
+    @objectmodel.specialize.arg(1)
+    def as_special_get_shadow(self, TheClass):
         shadow = self._shadow
         if shadow is None:
-            shadow = TheClass(self, invalid)
-            self._shadow = shadow
+            shadow = self.attach_shadow_of_class(TheClass)
         elif not isinstance(shadow, TheClass):
             shadow.sync_w_self()
             shadow.invalidate_shadow()
-            shadow = TheClass(self, invalid)
-            self._shadow = shadow
+            shadow = self.attach_shadow_of_class(TheClass)
         shadow.sync_shadow()
         return shadow
 
@@ -287,19 +292,19 @@
         from pypy.lang.smalltalk.shadow import ClassShadow
         return self.as_special_get_shadow(ClassShadow)
 
-    def as_blockcontext_get_shadow(self, invalid=True):
+    def as_blockcontext_get_shadow(self):
         from pypy.lang.smalltalk.shadow import BlockContextShadow
-        return self.as_special_get_shadow(BlockContextShadow, invalid)
+        return self.as_special_get_shadow(BlockContextShadow)
 
-    def as_methodcontext_get_shadow(self, invalid=True):
+    def as_methodcontext_get_shadow(self):
         from pypy.lang.smalltalk.shadow import MethodContextShadow
-        return self.as_special_get_shadow(MethodContextShadow, invalid)
+        return self.as_special_get_shadow(MethodContextShadow)
 
-    def as_context_get_shadow(self, invalid=True):
+    def as_context_get_shadow(self):
         from pypy.lang.smalltalk.shadow import ContextPartShadow
         # XXX TODO should figure out itself if its method or block context
         assert self._shadow is not None
-        return self.as_special_get_shadow(ContextPartShadow, invalid)
+        return self.as_special_get_shadow(ContextPartShadow)
 
     def as_methoddict_get_shadow(self):
         from pypy.lang.smalltalk.shadow import MethodDictionaryShadow
@@ -554,34 +559,41 @@
 
 def W_BlockContext(w_home, w_sender, argcnt, initialip):
     from pypy.lang.smalltalk.classtable import w_BlockContext
+    from pypy.lang.smalltalk import shadow
+    # 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
     w_result = W_PointersObject(w_BlockContext, w_home.size())
-    # Only home-brewed shadows are not invalid from start.
-    s_result = w_result.as_blockcontext_get_shadow(invalid=False)
+    s_result = shadow.BlockContextShadow(w_result)
+    w_result._shadow = s_result
     s_result.store_expected_argument_count(argcnt)
     s_result.store_initialip(initialip)
     s_result.store_w_home(w_home)
-    s_result._stack = []
-    s_result._pc = initialip
+    s_result.store_pc(initialip)
     return w_result
 
 def W_MethodContext(w_method, w_receiver,
                     arguments, w_sender=None):
     from pypy.lang.smalltalk.classtable import w_MethodContext
+    from pypy.lang.smalltalk import objtable, shadow
     # 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)
     assert isinstance(w_result, W_PointersObject)
-    # Only home-brewed shadows are not invalid from start.
-    s_result = w_result.as_methodcontext_get_shadow(invalid=False)
+    # 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 = shadow.MethodContextShadow(w_result)
+    w_result._shadow = s_result
     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(0)
+    s_result._temps = [objtable.w_nil] * w_method.tempframesize()
     for i in range(len(arguments)):
         s_result.settemp(i, arguments[i])
-    s_result._stack = []
     return w_result
 
 # Use black magic to create w_nil without running the constructor,

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py	Tue May 20 15:54:47 2008
@@ -5,6 +5,7 @@
 # ___________________________________________________________________________
 # Global Data
 
+
 def wrap_char_table():
     global w_charactertable
     def bld_char(i):
@@ -18,12 +19,6 @@
 
 wrap_char_table()
 
-w_true  = classtable.classtable['w_True'].as_class_get_shadow().new()
-w_false = classtable.classtable['w_False'].as_class_get_shadow().new()
-w_minus_one = model.W_SmallInteger(-1)
-w_zero = model.W_SmallInteger(0)
-w_one = model.W_SmallInteger(1)
-w_two = model.W_SmallInteger(2)
 
 # Very special nil hack: in order to allow W_PointersObject's to
 # initialize their fields to nil, we have to create it in the model
@@ -31,6 +26,13 @@
 w_nil = model.w_nil
 w_nil.w_class = classtable.classtable['w_UndefinedObject']
 
+w_true  = classtable.classtable['w_True'].as_class_get_shadow().new()
+w_false = classtable.classtable['w_False'].as_class_get_shadow().new()
+w_minus_one = model.W_SmallInteger(-1)
+w_zero = model.W_SmallInteger(0)
+w_one = model.W_SmallInteger(1)
+w_two = model.W_SmallInteger(2)
+
 # We use indirection because translated globals are assumed to be constant
 class ObjectTableHolder(object):
     pass

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	Tue May 20 15:54:47 2008
@@ -16,8 +16,9 @@
         return self._w_self
     def getname(self):
         return repr(self)
-    def detach_shadow(self):
-        pass
+    def attach_shadow(self): pass
+    def detach_shadow(self): pass
+    def sync_shadow(self): pass
    
 class AbstractCachingShadow(AbstractShadow):
     def __init__(self, w_self):
@@ -35,7 +36,7 @@
             self.update_shadow()
 
     def update_shadow(self):
-        self.w_self().setshadow(self)
+        self.w_self().store_shadow(self)
         self.invalid = False
         self.sync_cache()
 
@@ -66,7 +67,7 @@
     (i.e. used as the class of another Smalltalk object).
     """
     def invalidate_shadow(self):
-        AbstractShadow.invalidate_shadow(self)
+        AbstractCachingShadow.invalidate_shadow(self)
         self.w_methoddict = None
         self.w_superclass = None
         self.name = None
@@ -75,10 +76,8 @@
         return "%s class" % (self.name or '?',)
 
     def sync_cache(self):
-        from pypy.lang.smalltalk import objtable
-
+        from pypy.lang.smalltalk.objtable import w_nil
         "Update the ClassShadow with data from the w_self class."
-        AbstractShadow.update_shadow(self)
 
         w_self = self.w_self()
         # read and painfully decode the format
@@ -124,13 +123,11 @@
         assert isinstance(self.w_methoddict, model.W_PointersObject)
 
         w_superclass = w_self._vars[constants.CLASS_SUPERCLASS_INDEX]
-        if w_superclass.is_same_object(objtable.w_nil):
+        if w_superclass.is_same_object(w_nil):
             self.w_superclass = None
         else:
             self.w_superclass = w_superclass
 
-        AbstractShadow.update_shadow(self)
-
     def guess_class_name(self):
         w_self = self.w_self()
         w_name = None
@@ -255,7 +252,8 @@
         w_values = self.w_self()._vars[constants.METHODDICT_VALUES_INDEX]
         assert isinstance(w_values, model.W_PointersObject)
         s_values = w_values.get_shadow()
-        s_values.notifyinvalid(self)
+        # XXX Should add!
+        # s_values.notifyinvalid(self)
         size = self.w_self().size() - constants.METHODDICT_NAMES_INDEX
         self.methoddict = {}
         for i in range(size):
@@ -280,64 +278,94 @@
     def store(self, n0, w_value):
         raise NotImplementedError()
 
+    def attach_shadow(self):
+        AbstractShadow.attach_shadow(self)
+        for i in range(self._w_self_size):
+            self.copy_from_w_self(i)
+
+    def detach_shadow(self):
+        self.w_self()._vars = [objtable.w_nil] * self._w_self_size
+        for i in range(self._w_self_size):
+            self.copy_to_w_self(i)
+        self.invalidate_shadow()
+
+    def copy_from_w_self(self, n0):
+        self.store(n0, self.w_self()._fetch(n0))
+    def copy_to_w_self(self, n0):
+        self.w_self()._store(n0, self.fetch(n0))
+ 
 class ContextPartShadow(AbstractRedirectingShadow):
 
     __metaclass__ = extendabletype
 
+    def __init__(self, w_self):
+        from pypy.lang.smalltalk import objtable
+        self._w_sender = objtable.w_nil
+        self._stack = []
+        AbstractRedirectingShadow.__init__(self, w_self)
+
+    # TODO test
     def fetch(self, n0):
         if n0 == constants.CTXPART_SENDER_INDEX:
             return self.w_sender()
         if n0 == constants.CTXPART_PC_INDEX:
             return self.wrap_pc()
         if n0 == constants.CTXPART_STACKP_INDEX:
-            return utility.wrap_int(self.stackpointer())
+            return self.wrap_stackpointer()
         if self.stackstart() <= n0 < self.stackpointer():
             return self._stack[n0-self.stackstart()]
         if self.stackpointer() <= n0 < self.stackend():
+            from pypy.lang.smalltalk import objtable
             return objtable.w_nil
         else:
             # XXX later should store tail out of known context part as well
             raise error.WrapperException("Index in context out of bounds")
 
+    # TODO test
     def store(self, n0, w_value):
         if n0 == constants.CTXPART_SENDER_INDEX:
             return self.store_w_sender(w_value)
         if n0 == constants.CTXPART_PC_INDEX:
             return self.store_unwrap_pc(w_value)
         if n0 == constants.CTXPART_STACKP_INDEX:
-            return self.store_stackpointer(utility.unwrap_int(w_value))
+            return self.unwrap_store_stackpointer(w_value)
         if self.stackstart() <= n0 < self.stackpointer():
-            return self._stack[n0-self.stackstart()] = w_value
+            self._stack[n0 - self.stackstart()] = w_value
+            return
         if self.stackpointer() <= n0 < self.stackend():
-            raise error.WrapperException(
-                "Trying to store within stack range, after actual stack")
+            return
         else:
             # XXX later should store tail out of known context part as well
             raise error.WrapperException("Index in context out of bounds")
 
-    def update_shadow(self):
-        # XXX We need the method before reading pc
-        #     and stack (islarge -> stack + args + locals size)
-        AbstractShadow.update_shadow(self)
-        for i in range(self._w_self_size):
-            self.store(i, self.w_self()._fetch(i))
+    def unwrap_store_stackpointer(self, w_sp1):
+        # the stackpointer in the W_PointersObject starts counting at the
+        # tempframe start
+        # Stackpointer from smalltalk world == stacksize in python world
+        self.store_stackpointer(utility.unwrap_int(w_sp1) -
+                                self.w_method().tempframesize())
 
-    def store_unwrap_pc(self, w_pc):
-        self._pc = utility.unwrap_int(w_pc)
-        self._pc -= self.w_method().bytecodeoffset()
-        self._pc -= 1
+    # TODO test
+    def store_stackpointer(self, size):
+        from pypy.lang.smalltalk import objtable
+        if size < len(self._stack):
+            self._stack = self._stack[:size]
+        else:
+            add = [objtable.w_nil] * (size - len(self._stack))
+            self._stack.extend(add)
 
-    def wrap_pc(self):
-        pc = self._pc
-        pc += 1
-        pc += self.w_method().bytecodeoffset()
-        return utility.wrap_int(pc)
+    def wrap_stackpointer(self):
+        return utility.wrap_int(self.stackpointer() + 1)
+
+    # TODO test
+    def stackpointer(self):
+        return self.stackstart() + len(self._stack)
 
     def w_home(self):
         raise NotImplementedError()
 
     def s_home(self):
-        raise NotImplementedError()
+        return self.w_home().as_methodcontext_get_shadow()
     
     def stackstart(self):
         raise NotImplementedError()
@@ -349,10 +377,12 @@
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
 
+    def store_w_sender(self, w_sender):
+        assert isinstance(w_sender, model.W_PointersObject)
+        self._w_sender = w_sender
+
     def w_sender(self):
-        w_v = self.w_self()._vars[constants.CTXPART_SENDER_INDEX]
-        assert isinstance(w_v, model.W_PointersObject)
-        return w_v
+        return self._w_sender
 
     def s_sender(self):
         from pypy.lang.smalltalk import objtable
@@ -362,8 +392,19 @@
         else:
             return w_sender.as_context_get_shadow()
 
-    def store_w_sender(self, w_sender):
-        self.w_self()._vars[constants.CTXPART_SENDER_INDEX] = w_sender
+    # TODO test
+    def store_unwrap_pc(self, w_pc):
+        pc = utility.unwrap_int(w_pc)
+        pc -= self.w_method().bytecodeoffset()
+        pc -= 1
+        self.store_pc(pc)
+
+    # TODO test
+    def wrap_pc(self):
+        pc = self.pc()
+        pc += 1
+        pc += self.w_method().bytecodeoffset()
+        return utility.wrap_int(pc)
 
     def pc(self):
         return self._pc
@@ -371,16 +412,9 @@
     def store_pc(self, newpc):
         self._pc = newpc
 
-    def stackpointer(self):
-        return (utility.unwrap_int(self.w_self()._vars[constants.CTXPART_STACKP_INDEX]) +
-                self.stackpointer_offset())
-
     def stackpointer_offset(self):
         raise NotImplementedError()
 
-    def store_stackpointer(self, pointer):
-        self.w_self()._vars[constants.CTXPART_STACKP_INDEX] = utility.wrap_int(pointer)
-
     # ______________________________________________________________________
     # Method that contains the bytecode for this method/block context
 
@@ -412,17 +446,13 @@
     # ______________________________________________________________________
     # Stack Manipulation
     def pop(self):
-        w_v = self._stack[-1]
-        self._stack = self._stack[:-1]
-        return w_v
+        return self._stack.pop()
 
     def push(self, w_v):
-        self._stack += [w_v]
+        self._stack.append(w_v)
 
     def push_all(self, lst):
-        #for x in lst:
-        #    self.push(x)
-        self._stack += lst
+        self._stack.extend(lst)
 
     def top(self):
         return self.peek(0)
@@ -450,27 +480,48 @@
 class BlockContextShadow(ContextPartShadow):
 
     def __init__(self, w_self):
-        self._s_home = None
         ContextPartShadow.__init__(self, w_self)
 
-    def invalidate_shadow(self):
-        if self._s_home is not None:
-            self._s_home.unnotify(self)
-            self._s_home = None
-        AbstractShadow.invalidate_shadow(self)
+    def fetch(self, n0):
+        if n0 == constants.BLKCTX_HOME_INDEX:
+            return self.w_home()
+        if n0 == constants.BLKCTX_INITIAL_IP_INDEX:
+            return self.wrap_initialip()
+        if n0 == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
+            return self.wrap_eargc()
+        else:
+            return ContextPartShadow.fetch(self, n0)
 
-    def update_shadow(self):
-        self.store_w_home(self.w_self()._vars[constants.BLKCTX_HOME_INDEX])
-        self._initialip = utility.unwrap_int(self.w_self()._vars[constants.BLKCTX_INITIAL_IP_INDEX])
-        self._initialip -= 1 + self.w_method().getliteralsize()
-        self._eargc = utility.unwrap_int(self.w_self()._vars[constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX])
+    def store(self, n0, w_value):
+        if n0 == constants.BLKCTX_HOME_INDEX:
+            return self.store_w_home(w_value)
+        if n0 == constants.BLKCTX_INITIAL_IP_INDEX:
+            return self.uwrap_store_initialip(w_value)
+        if n0 == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
+            return self.unwrap_store_eargc(w_value)
+        else:
+            return ContextPartShadow.fetch(self, n0)
+
+    def attach_shadow(self):
+        # Make sure the home context is updated first
+        self.copy_from_w_self(constants.BLKCTX_HOME_INDEX)
         ContextPartShadow.update_shadow(self)
 
-    def update_w_self(self):
-        ContextPartShadow.update_w_self(self)
-        self.w_self()._vars[constants.BLKCTX_INITIAL_IP_INDEX] = utility.wrap_int(self._initialip + 1 + self.w_method().getliteralsize())
-        self.w_self()._vars[constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX] = utility.wrap_int(self._eargc)
-        self.w_self()._vars[constants.BLKCTX_HOME_INDEX] = self._w_home
+    def store_unwrap_initialip(self, w_value):
+        initialip = utility.unwrap_int(w_value)
+        initialip -= 1 + self.w_method().getliteralsize()
+        self.store_initialip(initialip)
+
+    def wrap_initialip(self):
+        initialip = self.initialip()
+        initialip += 1 + self.w_method().getliteralsize()
+        return utility.wrap_int(initialip)
+
+    def unwrap_store_eargc(self, w_value):
+        self.store_expected_argument_count(utility.unwrap_int(w_value))
+    
+    def wrap_eargc(self):
+        return utility.wrap_int(self.expected_argument_count())
 
     def expected_argument_count(self):
         return self._eargc
@@ -485,21 +536,12 @@
         self._initialip = initialip
         
     def store_w_home(self, w_home):
-        if self._s_home is not None:
-            self._s_home.unnotify(self)
-            self._s_home = None
         assert isinstance(w_home, model.W_PointersObject)
         self._w_home = w_home
 
     def w_home(self):
         return self._w_home
 
-    def s_home(self):
-        if self._s_home is None:
-            self._s_home = self._w_home.as_methodcontext_get_shadow()
-            self._s_home.notifyinvalid(self)
-        return self._s_home
-
     def reset_stack(self):
         self._stack = []
 
@@ -510,17 +552,48 @@
         return constants.BLKCTX_STACK_START
 
 class MethodContextShadow(ContextPartShadow):
-    def __init__(self, w_self, invalid):
-        ContextPartShadow.__init__(self, w_self, invalid)
+    def __init__(self, w_self):
+        from pypy.lang.smalltalk import objtable
+        self.w_receiver_map = objtable.w_nil
+        self._w_receiver = None
+        ContextPartShadow.__init__(self, w_self)
 
-    def update_shadow(self):
-        # Make sure the method is updated first
-        self.store_w_method(self.w_self()._vars[constants.MTHDCTX_METHOD])
-        ContextPartShadow.update_shadow(self)
+    def fetch(self, n0):
+        if n0 == constants.MTHDCTX_METHOD:
+            return self.w_method()
+        if n0 == constants.MTHDCTX_RECEIVER_MAP:
+            return self.w_receiver_map
+        if n0 == constants.MTHDCTX_RECEIVER:
+            return self.w_receiver()
+        if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START <
+                 self.w_method().tempframesize()):
+            return self.gettemp(n0-constants.MTHDCTX_TEMP_FRAME_START)
+        else:
+            return ContextPartShadow.fetch(self, n0)
 
-    def update_w_self(self):
-        ContextPartShadow.update_w_self(self)
-        self.w_self()._vars[constants.MTHDCTX_METHOD] = self._w_method
+    def store(self, n0, w_value):
+        if n0 == constants.MTHDCTX_METHOD:
+            return self.store_w_method(w_value)
+        if n0 == constants.MTHDCTX_RECEIVER_MAP:
+            self.w_receiver_map = w_value
+            return
+        if n0 == constants.MTHDCTX_RECEIVER:
+            self.store_w_receiver(w_value)
+            return
+        if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START <
+                 self.w_method().tempframesize()):
+            return self.settemp(n0-constants.MTHDCTX_TEMP_FRAME_START,
+                                w_value)
+        else:
+            return ContextPartShadow.store(self, n0, w_value)
+    
+    def attach_shadow(self):
+        from pypy.lang.smalltalk import objtable
+        # Make sure the method is updated first
+        self.copy_from_w_self(constants.MTHDCTX_METHOD)
+        # And that there is space for the temps
+        self._temps = [objtable.w_nil] * self.w_method().tempframesize()
+        ContextPartShadow.attach_shadow(self)
 
     def w_method(self):
         return self._w_method
@@ -530,16 +603,16 @@
         self._w_method = w_method
 
     def w_receiver(self):
-        return self.w_self()._vars[constants.MTHDCTX_RECEIVER]
+        return self._w_receiver
 
     def store_w_receiver(self, w_receiver):
-        self.w_self()._vars[constants.MTHDCTX_RECEIVER] = w_receiver
+        self._w_receiver = w_receiver
 
     def gettemp(self, index0):
-        return self.w_self()._vars[constants.MTHDCTX_TEMP_FRAME_START + index0]
+        return self._temps[index0]
 
     def settemp(self, index0, w_value):
-        self.w_self()._vars[constants.MTHDCTX_TEMP_FRAME_START + index0] = w_value
+        self._temps[index0] = w_value
 
     def w_home(self):
         return self.w_self()
@@ -547,14 +620,13 @@
     def s_home(self):
         return self
 
-    def store_stackpointer(self, pointer):
-        ContextPartShadow.store_stackpointer(self,
-                                             pointer+self.w_method().tempframesize())
-
     def stackpointer_offset(self):
         return constants.MTHDCTX_TEMP_FRAME_START
 
     def stackstart(self):
-        w_method = self.w_method()
         return (constants.MTHDCTX_TEMP_FRAME_START +
-                w_method.tempframesize())
+                self.w_method().tempframesize())
+
+    def stackend(self):
+        # XXX this is incorrect when there is subclassing
+        return self._w_self_size

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_model.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_model.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_model.py	Tue May 20 15:54:47 2008
@@ -67,7 +67,6 @@
     assert shadow.lookup("foo") == 1
     assert shadow.lookup("bar") == 2
     py.test.raises(MethodNotFound, shadow.lookup, "zork")
-    print subshadow.methoddict
     assert subshadow.lookup("foo") == 3
     assert subshadow.lookup("bar") == 2
     py.test.raises(MethodNotFound, subshadow.lookup, "zork")

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	Tue May 20 15:54:47 2008
@@ -12,9 +12,12 @@
 class MockFrame(model.W_PointersObject):
     def __init__(self, stack):
         self._vars = [None] * 6 + stack
-        s_self = self.as_blockcontext_get_shadow(False)
+        s_self = self.as_blockcontext_get_shadow()
         s_self._stack = stack
         s_self.store_expected_argument_count(0)
+    def as_blockcontext_get_shadow(self):
+        self._shadow = shadow.BlockContextShadow(self)
+        return self._shadow
 
 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	Tue May 20 15:54:47 2008
@@ -96,6 +96,7 @@
     w_object = methodcontext(stackpointer=3, method=w_m)
     w_object2 = methodcontext(w_sender=w_object)
     s_object = w_object.as_methodcontext_get_shadow()
+    assert len(s_object.stack()) == 3
     s_object2 = w_object2.as_methodcontext_get_shadow()
     assert w_object2.fetch(constants.CTXPART_SENDER_INDEX) == w_object
     assert s_object.w_self() == w_object
@@ -112,7 +113,6 @@
     w_object.store(idx, 'f')
     w_object.store(idx + 1, 'g')
     w_object.store(idx + 2, 'h')
-    s_object.update_shadow()
     assert s_object.stack() == ['f', 'g', 'h' ]
     assert s_object.top() == 'h'
     s_object.push('i')
@@ -121,8 +121,6 @@
     assert s_object.pop() == 'i'
     assert s_object.pop_and_return_n(2) == ['g', 'h']
     assert s_object.pop() == 'f'
-    s_object.update_w_self()
-    s_object.update_shadow()
     assert s_object.stackpointer() == s_object.stackstart()
 
 def test_methodcontext():



More information about the Pypy-commit mailing list