[pypy-svn] r54954 - pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk

tverwaes at codespeak.net tverwaes at codespeak.net
Mon May 19 18:44:10 CEST 2008


Author: tverwaes
Date: Mon May 19 18:44:10 2008
New Revision: 54954

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/shadow.py
Log:
(cfbolz, tverwaes) broken import, in progress (fixing shadows to work
redirecting)


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 May 19 18:44:10 2008
@@ -1,5 +1,4 @@
 import py
-from pypy.lang.smalltalk.shadow import Invalidateable
 from pypy.lang.smalltalk.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow
 from pypy.lang.smalltalk import model, constants, primitives
 from pypy.lang.smalltalk import objtable
@@ -18,7 +17,7 @@
 class IllegalStoreError(Exception):
     """Illegal Store."""
 
-class Interpreter(Invalidateable):
+class Interpreter(object):
 
     TRUE = objtable.w_true
     FALSE = objtable.w_false
@@ -32,31 +31,17 @@
     
     def __init__(self):
         self._w_active_context = None
-        self._s_active_context = None
         self.cnt = 0
 
     def w_active_context(self):
         return self._w_active_context
 
     def store_w_active_context(self, w_context):
-        # We can only interpret contexts of which we know the type already
-        #s_ctx = w_context.as_context_get_shadow()
-        #assert (isinstance(s_ctx, MethodContextShadow) or 
-        #        isinstance(s_ctx, BlockContextShadow))
-        if self._s_active_context is not None:
-            self._s_active_context.unnotify(self)
-            self._s_active_context = None
         assert isinstance(w_context, model.W_PointersObject)
         self._w_active_context = w_context
 
-    def invalidate(self):
-        self._s_active_context = None
-
     def s_active_context(self):
-        if self._s_active_context is None:
-            self._s_active_context = self.w_active_context().as_context_get_shadow()
-            self._s_active_context.notifyinvalid(self)
-        return self._s_active_context
+        return self.w_active_context().as_context_get_shadow()
 
     def interpret(self):
         try:

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 May 19 18:44:10 2008
@@ -224,13 +224,18 @@
 
     def fetch(self, n0):
         if self._shadow is not None:
-            self._shadow.sync_w_self()
+            return self._shadow.fetch(n0)
+        return self._fetch(n0)
+
+    def _fetch(self, n0):
         return self._vars[n0]
         
     def store(self, n0, w_value):    
         if self._shadow is not None:
-            self._shadow.sync_w_self()
-            self._shadow.invalidate_shadow()
+            return self._shadow.store(n0, w_value)
+        return self._store(n0, w_value)
+
+    def _store(self, n0, w_value):
         self._vars[n0] = w_value
 
     # def fetchvarpointer(self, idx):
@@ -557,7 +562,6 @@
     s_result.store_w_home(w_home)
     s_result._stack = []
     s_result._pc = initialip
-    s_result.invalidate_w_self()
     return w_result
 
 def W_MethodContext(w_method, w_receiver,
@@ -578,7 +582,6 @@
     for i in range(len(arguments)):
         s_result.settemp(i, arguments[i])
     s_result._stack = []
-    s_result.invalidate_w_self()
     return w_result
 
 # Use black magic to create w_nil without running the constructor,

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 May 19 18:44:10 2008
@@ -2,54 +2,33 @@
 from pypy.lang.smalltalk import model, constants, utility, error
 from pypy.tool.pairtype import extendabletype
 
-class Invalidateable(object):
-    def invalidate_shadow(self):
-        pass
-
-class AbstractShadow(Invalidateable):
+class AbstractShadow(object):
     """A shadow is an optional extra bit of information that
     can be attached at run-time to any Smalltalk object.
     """
-    
-    def __init__(self, w_self, invalid):
+    def __init__(self, w_self):
         self._w_self = w_self
-        self._notifyinvalid = []
-        self.invalid = invalid
-        self.w_invalid = False
-        if invalid:
-            self.invalidate_shadow()
-
-    def notifyinvalid(self, other):
-        self._notifyinvalid += [other]
-
-    def unnotify(self, other):
-        if other in self._notifyinvalid:
-            self._notifyinvalid.remove(other)
-
+    def fetch(self, n0):
+        return self.w_self()._fetch(n0)
+    def store(self, n0, w_value):
+        return self.w_self()._store(n0, w_value)
+    def w_self(self):
+        return self._w_self
     def getname(self):
         return repr(self)
+    def detach_shadow(self):
+        pass
+   
+class AbstractCachingShadow(AbstractShadow):
+    def __init__(self, w_self):
+        AbstractShadow.__init__(self, w_self)
+        self.update_shadow()
 
     def invalidate_shadow(self):
-        """XXX This should get called whenever the base Smalltalk
+        """This should get called whenever the base Smalltalk
         object changes."""
         if not self.invalid:
             self.invalid = True
-            for listener in self._notifyinvalid:
-                listener.invalidate_shadow()
-            self._notifyinvalid = []
-
-    def invalidate_w_self(self):
-        """XXX This should get called whenever the shadow
-        object changes.
-        (current shortcut, whenever the shadow is used)"""
-        self.w_invalid = True
-
-    def w_self(self):
-        return self._w_self
-
-    def sync_w_self(self):
-        if self.w_invalid:
-            self.update_w_self()
 
     def sync_shadow(self):
         if self.invalid:
@@ -58,9 +37,14 @@
     def update_shadow(self):
         self.w_self().setshadow(self)
         self.invalid = False
+        self.sync_cache()
 
-    def update_w_self(self):
-        self.w_invalid = False
+    def sync_cache(self):
+        raise NotImplementedError()
+
+    def store(self, n0, w_value):
+        self.invalidate_shadow()
+        AbstractShadow.store(self, n0, w_value)
 
 # ____________________________________________________________ 
 
@@ -77,13 +61,10 @@
 class ClassShadowError(error.SmalltalkException):
     pass
 
-class ClassShadow(AbstractShadow):
+class ClassShadow(AbstractCachingShadow):
     """A shadow for Smalltalk objects that are classes
     (i.e. used as the class of another Smalltalk object).
     """
-    def __init__(self, w_self, invalid):
-        AbstractShadow.__init__(self, w_self, invalid)
-
     def invalidate_shadow(self):
         AbstractShadow.invalidate_shadow(self)
         self.w_methoddict = None
@@ -93,7 +74,7 @@
     def getname(self):
         return "%s class" % (self.name or '?',)
 
-    def update_shadow(self):
+    def sync_cache(self):
         from pypy.lang.smalltalk import objtable
 
         "Update the ClassShadow with data from the w_self class."
@@ -263,14 +244,13 @@
         if isinstance(method, model.W_CompiledMethod):
             method.w_compiledin = self.w_self()
 
-class MethodDictionaryShadow(AbstractShadow):
-    def __init__(self, w_self, invalid):
-        AbstractShadow.__init__(self, w_self, invalid)
+class MethodDictionaryShadow(AbstractCachingShadow):
 
     def invalidate_shadow(self):
+        AbstractCachingShadow.invalidate_shadow(self)
         self.methoddict = None
 
-    def update_shadow(self):
+    def sync_cache(self):
         from pypy.lang.smalltalk import objtable
         w_values = self.w_self()._vars[constants.METHODDICT_VALUES_INDEX]
         assert isinstance(w_values, model.W_PointersObject)
@@ -290,39 +270,68 @@
                                            "CompiledMethods only for now")
                 self.methoddict[selector] = w_compiledmethod
 
-class ContextPartShadow(AbstractShadow):
+
+class AbstractRedirectingShadow(AbstractShadow):
+    def __init__(self, w_self):
+        AbstractShadow.__init__(self, w_self)
+        self._w_self_size = len(self.w_self()._vars)
+    def fetch(self, n0):
+        raise NotImplementedError()
+    def store(self, n0, w_value):
+        raise NotImplementedError()
+
+class ContextPartShadow(AbstractRedirectingShadow):
 
     __metaclass__ = extendabletype
 
+    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())
+        if self.stackstart() <= n0 < self.stackpointer():
+            return self._stack[n0-self.stackstart()]
+        if self.stackpointer() <= n0 < self.stackend():
+            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")
+
+    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))
+        if self.stackstart() <= n0 < self.stackpointer():
+            return self._stack[n0-self.stackstart()] = w_value
+        if self.stackpointer() <= n0 < self.stackend():
+            raise error.WrapperException(
+                "Trying to store within stack range, after actual stack")
+        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)
-        self._stack = [self.w_self()._vars[i]
-                        for i in range(self.stackstart(),
-                                       self.stackpointer())]
-        self.init_pc()
-        # Using a shadow most likely results in an invalid state for w_self
-        self.invalidate_w_self()
+        for i in range(self._w_self_size):
+            self.store(i, self.w_self()._fetch(i))
 
-    def init_pc(self):
-        self._pc = utility.unwrap_int(self.w_self()._vars[constants.CTXPART_PC_INDEX])
+    def store_unwrap_pc(self, w_pc):
+        self._pc = utility.unwrap_int(w_pc)
         self._pc -= self.w_method().bytecodeoffset()
         self._pc -= 1
 
-    def save_back_pc(self):
+    def wrap_pc(self):
         pc = self._pc
         pc += 1
         pc += self.w_method().bytecodeoffset()
-        self.w_self()._vars[constants.CTXPART_PC_INDEX] = utility.wrap_int(pc)
-
-    def update_w_self(self):
-        AbstractShadow.update_w_self(self)
-        for i in range(len(self._stack)):
-            self.w_self()._vars[self.stackstart() + i] = self._stack[i]
-        self.store_stackpointer(len(self._stack))
-        self.save_back_pc()
-
-    def __init__(self, w_self, invalid):
-        AbstractShadow.__init__(self, w_self, invalid)
+        return utility.wrap_int(pc)
 
     def w_home(self):
         raise NotImplementedError()
@@ -440,9 +449,9 @@
 
 class BlockContextShadow(ContextPartShadow):
 
-    def __init__(self, w_self, invalid):
+    def __init__(self, w_self):
         self._s_home = None
-        ContextPartShadow.__init__(self, w_self, invalid)
+        ContextPartShadow.__init__(self, w_self)
 
     def invalidate_shadow(self):
         if self._s_home is not None:



More information about the Pypy-commit mailing list