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

tverwaes at codespeak.net tverwaes at codespeak.net
Fri Feb 22 02:21:50 CET 2008


Author: tverwaes
Date: Fri Feb 22 02:21:49 2008
New Revision: 51766

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_miniimage.py
Log:
making shadows and oldstyle methodcontexts more polymorph


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	Fri Feb 22 02:21:49 2008
@@ -2,6 +2,7 @@
 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
 
@@ -106,10 +107,9 @@
         # which is an object with two named vars, and fetches the second
         # named var (the value).
         index = self.currentBytecode & 31
-        association = self.w_method().getliteral(index)
-        assert isinstance(association, model.W_PointersObject)
-        assert association.size() == 2
-        self.push(association.fetch(constants.ASSOCIATION_VALUE_INDEX))
+        w_association = self.w_method().getliteral(index)
+        s_association = w_association.as_association_get_shadow()
+        self.push(s_association.value())
 
     def storeAndPopReceiverVariableBytecode(self, interp):
         index = self.currentBytecode & 7
@@ -200,11 +200,9 @@
                     if interp.should_trace():
                         print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,)
                     pass # ignore this error and fall back to the Smalltalk version
-        start = len(self.stack) - argcount
-        assert start >= 0  # XXX check in the Blue Book what to do in this case
-        arguments = self.stack[start:]
+        arguments = self.pop_and_return_n(argcount)
         interp.s_active_context = method.create_frame(receiver, arguments, self) 
-        self.pop_n(argcount + 1) 
+        self.pop()
 
     def _return(self, object, interp, s_return_to):
         # for tests, when returning from the top-level context
@@ -248,9 +246,9 @@
         elif variableType == 2:
             self.push(self.w_method().getliteral(variableIndex))
         elif variableType == 3:
-            association = self.w_method().getliteral(variableIndex)
-            assert isinstance(association, model.W_PointersObject)
-            self.push(association.fetch(constants.ASSOCIATION_VALUE_INDEX))
+            w_association = self.w_method().getliteral(variableIndex)
+            s_association = w_association.as_association_get_shadow()
+            self.push(s_association.value())
         else:
             assert 0
         
@@ -263,9 +261,9 @@
         elif variableType == 2:
             raise IllegalStoreError
         elif variableType == 3:
-            association = self.w_method().getliteral(variableIndex)
-            assert isinstance(association, model.W_PointersObject)
-            association.store(constants.ASSOCIATION_VALUE_INDEX, self.top())
+            w_association = self.w_method().getliteral(variableIndex)
+            s_association = w_association.as_association_get_shadow()
+            s_association.store_value(self.top())
 
     def extendedStoreAndPopBytecode(self, interp):
         self.extendedStoreBytecode(interp)
@@ -300,17 +298,17 @@
             self.push(self.w_method().getliteral(third))
         elif opType == 4:
             # pushLiteralVariable
-            association = self.w_method().getliteral(third)
-            assert isinstance(association, model.W_PointersObject)
-            self.push(association.fetch(constants.ASSOCIATION_VALUE_INDEX))
+            w_association = self.w_method().getliteral(third)
+            s_association = w_association.as_association_get_shadow()
+            self.push(s_association.value())
         elif opType == 5:
             self.w_receiver().store(third, self.top())
         elif opType == 6:
             self.w_receiver().store(third, self.pop())
         elif opType == 7:
-            association = self.w_method().getliteral(third)
-            assert isinstance(association, model.W_PointersObject)
-            association.store(constants.ASSOCIATION_VALUE_INDEX, self.top())
+            w_association = self.w_method().getliteral(third)
+            s_association = w_association.as_association_get_shadow()
+            s_association.store_value(self.top())
 
     def singleExtendedSuperBytecode(self, interp):
         selector, argcount = self.getExtendedSelectorArgcount()

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	Fri Feb 22 02:21:49 2008
@@ -364,9 +364,9 @@
             # (Blue book, p 607) All CompiledMethods that contain extended-super bytecodes have the clain which they are found as their last literal variable.   
             # Last of the literals is an association with compiledin
             # as a class
-            association = self.literals[-1]
-            assert isinstance(association, W_PointersObject)
-            self.w_compiledin = association.fetch(constants.ASSOCIATION_VALUE_INDEX)
+            w_association = self.literals[-1]
+            s_association = w_association.as_association_get_shadow()
+            self.w_compiledin = s_association.value()
         return self.w_compiledin
 
     def getclass(self):
@@ -451,6 +451,16 @@
         else:
             self.literals[index0-1] = w_value
 
+    def fetchbyte(self, index1):
+        index0 = index1 - 1
+        index0 -= self.headersize()
+        index0 -= self.getliteralsize()
+        assert index0 < len(self.bytes)
+        return self.bytes[index0]
+
+    def store(self, index0, w_v):
+        self.atput0(index0, w_v)
+
     def at0(self, index0):
         from pypy.lang.smalltalk import utility
         # XXX Not tested
@@ -459,11 +469,7 @@
             self.literalat0(index0)
         else:
             index0 = index0 - self.getliteralsize()
-            if index0 > len(self.bytes):
-                print "ERROR"
-                print self.getliteralsize()
-                print len(self.bytes)
-                print self.bytes
+            assert index0 < len(self.bytes)
             return utility.wrap_int(ord(self.bytes[index0]))
         
     def atput0(self, index0, w_value):
@@ -522,41 +528,43 @@
     def store_s_sender(self, s_sender):
         self._s_sender = s_sender
 
+    def stackpointer(self):
+        return len(self.stack) + self.stackstart()
     # ______________________________________________________________________
     # Imitate the primitive accessors
     
-    def fetch(self, index):
-        from pypy.lang.smalltalk import utility, objtable
-        if index == constants.CTXPART_SENDER_INDEX:
-            sender = self.s_sender()
-            if sender is None:
-                return objtable.w_nil
-            else:
-                return sender.w_self()
-        elif index == constants.CTXPART_PC_INDEX:
-            return utility.wrap_int(self.pc())
-        elif index == constants.CTXPART_STACKP_INDEX:
-            return utility.wrap_int(len(self.stack)+self.stackstart())
-        
-        # Invalid!
-        raise IndexError
-
-    def store(self, index, w_value):
-        # XXX Untested code...
+    #def fetch(self, index):
+    #    from pypy.lang.smalltalk import utility, objtable
+    #    if index == constants.CTXPART_SENDER_INDEX:
+    #        sender = self.s_sender()
+    #        if sender is None:
+    #            return objtable.w_nil
+    #        else:
+    #            return sender.w_self()
+    #    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
 
-        from pypy.lang.smalltalk import utility, objtable
-        if index == constants.CTXPART_SENDER_INDEX:
-            if w_value != objtable.w_nil:
-                self._s_sender = w_value.as_context_get_shadow()
-        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 = size - self.stackstart()
-            self.stack = [objtable.w_nil] * size
-        else:
-            # 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._s_sender = w_value.as_context_get_shadow()
+    #    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 = size - self.stackstart()
+    #        self.stack = [objtable.w_nil] * size
+    #    else:
+    #        # Invalid!
+    #        raise IndexError
 
     def stackstart(self):
         return self.w_method().argsize + self.w_method().tempsize + constants.MTHDCTX_TEMP_FRAME_START

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	Fri Feb 22 02:21:49 2008
@@ -79,7 +79,7 @@
                 argument_count = argument_count_m1 + 1 # to account for the rcvr
                 frame = interp.s_active_context
                 assert argument_count == len_unwrap_spec
-                if len(frame.stack) < len_unwrap_spec:
+                if frame.stackpointer() - frame.stackstart() < len_unwrap_spec:
                     raise PrimitiveFailedError()
                 args = ()
                 for i, spec in unrolling_unwrap_spec:

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	Fri Feb 22 02:21:49 2008
@@ -1,5 +1,6 @@
 import weakref
 from pypy.lang.smalltalk import model, constants, utility, error
+from pypy.tool.pairtype import extendabletype
 
 class AbstractShadow(object):
     """A shadow is an optional extra bit of information that
@@ -50,7 +51,7 @@
 
         "Update the ClassShadow with data from the w_self class."
 
-        w_self = self._w_self
+        w_self = self.w_self()
         # read and painfully decode the format
         classformat = utility.unwrap_int(
             w_self.fetch(constants.CLASS_FORMAT_INDEX))
@@ -129,7 +130,7 @@
 
     def new(self, extrasize=0):
         from pypy.lang.smalltalk import classtable
-        w_cls = self._w_self
+        w_cls = self.w_self()
         
         if w_cls == classtable.w_BlockContext:
             return model.W_BlockContext(None, None, 0, 0)
@@ -215,23 +216,23 @@
         "NOT_RPYTHON"     # this is only for testing.
         assert isinstance(method, model.W_CompiledMethod)
         self.methoddict[selector] = method
-        method.w_compiledin = self._w_self
+        method.w_compiledin = self.w_self()
 
 class LinkedListShadow(AbstractShadow):
     def __init__(self, w_self):
         self._w_self = w_self
 
     def w_firstlink(self):
-        return self._w_self.fetch(constants.FIRST_LINK_INDEX)
+        return self.w_self().fetch(constants.FIRST_LINK_INDEX)
 
     def store_w_firstlink(self, w_object):
-        return self._w_self.atput0(constants.FIRST_LINK_INDEX, w_object)
+        return self.w_self().store(constants.FIRST_LINK_INDEX, w_object)
 
     def w_lastlink(self):
-        return self._w_self.fetch(constants.LAST_LINK_INDEX)
+        return self.w_self().fetch(constants.LAST_LINK_INDEX)
 
     def store_w_lastlink(self, w_object):
-        return self._w_self.atput0(constants.LAST_LINK_INDEX, w_object)
+        return self.w_self().store(constants.LAST_LINK_INDEX, w_object)
 
     def is_empty_list(self):
         from pypy.lang.smalltalk import objtable
@@ -269,7 +270,7 @@
         s_scheduler = self.s_scheduler()
         w_process_lists = s_scheduler.process_lists()
         w_process_list = w_process_lists.fetch(priority)
-        w_process_list.as_linkedlist_get_shadow().add_last_link(s_process._w_self)
+        w_process_list.as_linkedlist_get_shadow().add_last_link(s_process.w_self())
         s_process.store_my_list(w_process_list)
         
     def transfer_to(self, s_process, interp):
@@ -301,11 +302,10 @@
             self.put_to_sleep(s_process)
 
     def synchronous_signal(self, interp):
-        print "SYNCHRONOUS SIGNAL"
         if self.is_empty_list():
-            w_value = self._w_self.fetch(constants.EXCESS_SIGNALS_INDEX)
+            w_value = self.w_self().fetch(constants.EXCESS_SIGNALS_INDEX)
             w_value = utility.wrap_int(utility.unwrap_int(w_value) + 1)
-            self._w_self.atput0(constants.EXCESS_SIGNALS_INDEX, w_value)
+            self.w_self().store(constants.EXCESS_SIGNALS_INDEX, w_value)
         else:
             self.resume(self.remove_first_link_of_list(), interp)
 
@@ -314,10 +314,10 @@
         self._w_self = w_self
 
     def next(self):
-        return self._w_self.fetch(constants.NEXT_LINK_INDEX)
+        return self.w_self().fetch(constants.NEXT_LINK_INDEX)
 
     def store_next(self, w_object):
-        self._w_self.atput0(constants.NEXT_LINK_INDEX, w_object)
+        self.w_self().store(constants.NEXT_LINK_INDEX, w_object)
 
 class ProcessShadow(LinkShadow):
     """A shadow for Smalltalk objects that are processes
@@ -326,44 +326,51 @@
         self._w_self = w_self
 
     def priority(self):
-        return utility.unwrap_int(self._w_self.fetch(constants.PROCESS_PRIORITY_INDEX))
+        return utility.unwrap_int(self.w_self().fetch(constants.PROCESS_PRIORITY_INDEX))
 
     def my_list(self):
-        return self._w_self.fetch(constants.PROCESS_MY_LIST_INDEX)
+        return self.w_self().fetch(constants.PROCESS_MY_LIST_INDEX)
 
     def store_my_list(self, w_object):
-        self._w_self.atput0(constants.PROCESS_MY_LIST_INDEX, w_object)
+        self.w_self().store(constants.PROCESS_MY_LIST_INDEX, w_object)
 
     def s_suspended_context(self):
-        return self._w_self.fetch(constants.PROCESS_SUSPENDED_CONTEXT_INDEX).as_context_get_shadow()
+        return self.w_self().fetch(constants.PROCESS_SUSPENDED_CONTEXT_INDEX).as_context_get_shadow()
 
     def store_w_suspended_context(self, w_object):
-        self._w_self.atput0(constants.PROCESS_SUSPENDED_CONTEXT_INDEX, w_object)
+        self.w_self().store(constants.PROCESS_SUSPENDED_CONTEXT_INDEX, w_object)
 
 class AssociationShadow(AbstractShadow):
     def __init__(self, w_self):
         self._w_self = w_self
 
     def key(self):
-        return self._w_self.fetch(constants.ASSOCIATION_KEY_INDEX)
+        return self.w_self().fetch(constants.ASSOCIATION_KEY_INDEX)
 
     def value(self):
-        return self._w_self.fetch(constants.ASSOCIATION_VALUE_INDEX)
+        return self.w_self().fetch(constants.ASSOCIATION_VALUE_INDEX)
+
+    def store_value(self, w_value):
+        self.w_self().store(constants.ASSOCIATION_VALUE_INDEX, w_value)
 
 class SchedulerShadow(AbstractShadow):
     def __init__(self, w_self):
         self._w_self = w_self
 
     def s_active_process(self):
-        return self._w_self.fetch(constants.SCHEDULER_ACTIVE_PROCESS_INDEX).as_process_get_shadow()
+        return self.w_self().fetch(constants.SCHEDULER_ACTIVE_PROCESS_INDEX).as_process_get_shadow()
 
     def store_w_active_process(self, w_object):
-        self._w_self.store(constants.SCHEDULER_ACTIVE_PROCESS_INDEX, w_object)
+        self.w_self().store(constants.SCHEDULER_ACTIVE_PROCESS_INDEX, w_object)
     
     def process_lists(self):
-        return self._w_self.fetch(constants.SCHEDULER_PROCESS_LISTS_INDEX)
+        return self.w_self().fetch(constants.SCHEDULER_PROCESS_LISTS_INDEX)
 
-class ContextPartShadow(AbstractShadow):
+# 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):
 
     #__metaclass__ = extendabletype
     
@@ -373,6 +380,14 @@
     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):
+        pass
+
     def w_receiver(self):
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
@@ -387,19 +402,19 @@
             return w_sender.as_context_get_shadow()
 
     def store_s_sender(self, s_sender):
-        self._w_self.store(constants.CTXPART_SENDER_INDEX, s_sender.w_self())
+        self.w_self().store(constants.CTXPART_SENDER_INDEX, s_sender.w_self())
 
     def pc(self):
-        return utility.unwrap_int(self._w_self.fetch(constants.CTXPART_PC_INDEX))
+        return utility.unwrap_int(self.w_self().fetch(constants.CTXPART_PC_INDEX))
 
     def store_pc(self, newpc):
-        self._w_self.store(constants.CTXPART_PC_INDEX, utility.wrap_int(newpc))
+        self.w_self().store(constants.CTXPART_PC_INDEX, utility.wrap_int(newpc))
 
     def stackpointer(self):
-        return utility.unwrap_int(self._w_self.fetch(constants.CTXPART_STACKP_INDEX))
+        return utility.unwrap_int(self.w_self().fetch(constants.CTXPART_STACKP_INDEX))
 
     def store_stackpointer(self, pointer):
-        self._w_self.store(constants.CTXPART_STACKP_INDEX,
+        self.w_self().store(constants.CTXPART_STACKP_INDEX,
                           utility.wrap_int(pointer))
 
     # ______________________________________________________________________
@@ -410,7 +425,7 @@
 
     def getbytecode(self):
         pc = self.pc()
-        bytecode = self.w_method().bytes[pc]
+        bytecode = self.w_method().fetchbyte(pc)
         currentBytecode = ord(bytecode)
         self.store_pc(pc + 1)
         return currentBytecode
@@ -469,17 +484,17 @@
         self._w_self = w_self
 
     def expected_argument_count(self):
-        return utility.unwrap_int(self._w_self.fetch(constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX))
+        return utility.unwrap_int(self.w_self().fetch(constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX))
 
     def store_expected_argument_count(self, argc):
-        return self._w_self.store(constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX,
+        return self.w_self().store(constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX,
                                  utility.wrap_int(argc))
 
     def initialip(self):
-        return utility.unwrap_int(self._w_self.fetch(constants.BLKCTX_INITIAL_IP_INDEX))
+        return utility.unwrap_int(self.w_self().fetch(constants.BLKCTX_INITIAL_IP_INDEX))
         
     def s_home(self):
-        return self._w_self.fetch(constants.BLKCTX_HOME_INDEX).as_methodcontext_get_shadow()
+        return self.w_self().fetch(constants.BLKCTX_HOME_INDEX).as_methodcontext_get_shadow()
 
     def stackstart(self):
         return constants.BLKCTX_TEMP_FRAME_START
@@ -489,19 +504,19 @@
         self._w_self = w_self
 
     def w_method(self):
-        return self._w_self.fetch(constants.MTHDCTX_METHOD)
+        return self.w_self().fetch(constants.MTHDCTX_METHOD)
 
     def w_receiver(self):
-        return self._w_self.fetch(constants.MTHDCTX_RECEIVER)
+        return self.w_self().fetch(constants.MTHDCTX_RECEIVER)
 
     def store_w_receiver(self, w_receiver):
-        self._w_self.store(constants.MTHDCTX_RECEIVER, w_receiver)
+        self.w_self().store(constants.MTHDCTX_RECEIVER, w_receiver)
 
     def gettemp(self, index):
-        return self._w_self.fetch(constants.MTHDCTX_TEMP_FRAME_START + index)
+        return self.w_self().fetch(constants.MTHDCTX_TEMP_FRAME_START + index)
 
     def settemp(self, index, w_value):
-        self._w_self.store(constants.MTHDCTX_TEMP_FRAME_START + index, w_value) 
+        self.w_self().store(constants.MTHDCTX_TEMP_FRAME_START + index, w_value) 
 
     def s_home(self):
         return self

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	Fri Feb 22 02:21:49 2008
@@ -226,10 +226,16 @@
     w_false = image.special(constants.SO_FALSE)
     assert w_false is objtable.w_false
     
-def test_scheduler():
+def test_runimage():
     from pypy.lang.smalltalk.shadow import SemaphoreShadow
     s_semaphore = SemaphoreShadow(None)
     s_scheduler = s_semaphore.s_scheduler()
+    s_ap = s_scheduler.s_active_process()
+    s_ctx = s_ap.s_suspended_context()
+    s_ap.store_w_suspended_context(objtable.w_nil)
+    interp = interpreter.Interpreter()
+    interp.s_active_context = s_ctx
+    interp.interpret()
     
 def test_compile_method():
     # py.test.skip("Not working yet.")



More information about the Pypy-commit mailing list