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

tverwaes at codespeak.net tverwaes at codespeak.net
Mon Feb 18 12:33:05 CET 2008


Author: tverwaes
Date: Mon Feb 18 12:33:05 2008
New Revision: 51579

Modified:
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/classtable.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/constants.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/primitives.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
Log:
fiddling with shadows



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	Mon Feb 18 12:33:05 2008
@@ -75,7 +75,7 @@
 create_classtable()
 
 def copy_in_globals_classes_known_to_the_vm():
-    for name in constants.classes_in_special_object_table:
+    for name in constants.classes_needed_boot_vm:
         name = 'w_' + name
         globals()[name] = classtable[name]
 

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/constants.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/constants.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/constants.py	Mon Feb 18 12:33:05 2008
@@ -13,7 +13,20 @@
 CLASS_SUPERCLASS_INDEX = 0
 CLASS_METHODDICT_INDEX = 1
 CLASS_FORMAT_INDEX = 2
-CLASS_NAME_INDEX = 6             # in the mini.image, at least
+CLASS_NAME_INDEX = 6                # in the mini.image, at least
+
+NEXT_LINK_INDEX = 0                 # "
+
+PROCESS_SUSPENDED_CONTEXT_INDEX = 1 # "
+PROCESS_PRIORITY_INDEX = 2          # "
+PROCESS_MY_LIST_INDEX = 3           # "
+
+FIRST_LINK_INDEX = 0                # "
+LAST_LINK_INDEX = 1                 # "
+EXCESS_SIGNALS_INDEX = 2            # "
+
+SCHEDULER_PROCESS_LISTS_INDEX = 0   # "
+SCHEDULER_ACTIVE_PROCESS_INDEX = 1  # "
 
 METHODDICT_TALLY_INDEX = 0
 METHODDICT_VALUES_INDEX = 1
@@ -99,23 +112,52 @@
 SO_FINALIZATION_SEMPAHORE = 41
 SO_LARGENEGATIVEINTEGER_CLASS = 42
 
+classes_needed_boot_vm = [
+    "SmallInteger",
+    "String",
+    "Array",
+    "Float",
+    "MethodContext",
+    "BlockContext",
+    "CompiledMethod",
+    "Character",
+    "ByteArray",
+]
+
 # XXX more missing?
 classes_in_special_object_table = {
-    "SmallInteger": SO_SMALLINTEGER_CLASS,
-    "Array": SO_ARRAY_CLASS,
-    "String": SO_STRING_CLASS,
-    "Float": SO_FLOAT_CLASS,
-    "BlockContext": SO_BLOCKCONTEXT_CLASS,
-    "MethodContext": SO_METHODCONTEXT_CLASS,
-    "Character": SO_CHARACTER_CLASS,
-    "ByteArray": SO_BYTEARRAY_CLASS,
-    "CompiledMethod": SO_COMPILEDMETHOD_CLASS,
+    "Bitmap" : SO_BITMAP_CLASS,
+    "SmallInteger" : SO_SMALLINTEGER_CLASS,
+    "String" : SO_STRING_CLASS,
+    "Array" : SO_ARRAY_CLASS,
+    "Float" : SO_FLOAT_CLASS,
+    "MethodContext" : SO_METHODCONTEXT_CLASS,
+    "BlockContext" : SO_BLOCKCONTEXT_CLASS,
+    "Point" : SO_POINT_CLASS,
+    "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS,
+    "Display" : SO_DISPLAY_CLASS,
+    "Message" : SO_MESSAGE_CLASS,
+    "CompiledMethod" : SO_COMPILEDMETHOD_CLASS,
+    "Semaphore" : SO_SEMAPHORE_CLASS,
+    "Character" : SO_CHARACTER_CLASS,
+    "ByteArray" : SO_BYTEARRAY_CLASS,
+    "Process" : SO_PROCESS_CLASS,
+    "PseudoContext" : SO_PSEUDOCONTEXT_CLASS,
+    "TranslatedMethod" : SO_TRANSLATEDMETHOD_CLASS,
+    # "LargeNegativeInteger" : SO_LARGENEGATIVEINTEGER_CLASS, # Not available in mini.image
 }
 
+objects_needed_boot_vm = [
+    "nil",
+    "true",
+    "false",
+]
+
 objects_in_special_object_table = {
     "nil": SO_NIL,
     "true": SO_TRUE,
     "false": SO_FALSE,
+    "schedulerassociationpointer" : SO_SCHEDULERASSOCIATIONPOINTER,
 }
 
 TAGGED_MAXINT = 2 ** (LONG_BIT - 2) - 1

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 18 12:33:05 2008
@@ -29,6 +29,7 @@
     
     def __init__(self):
         self.w_active_context = None
+        self.cnt = 0
 
     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 Feb 18 12:33:05 2008
@@ -125,7 +125,8 @@
         return "<%s %s>" % (self.__class__.__name__, self)
 
     def __str__(self):
-        if isinstance(self, W_PointersObject) and self._shadow is not None:
+        from pypy.lang.smalltalk.shadow import ClassShadow
+        if isinstance(self, W_PointersObject) and isinstance(self._shadow,ClassShadow):
             return "%s class" % (self.as_class_get_shadow().name or '?',)
         else:
             return "a %s" % (self.shadow_of_my_class().name or '?',)
@@ -180,15 +181,44 @@
         return (W_AbstractObjectWithClassReference.invariant(self) and
                 isinstance(self._vars, list))
 
-    def as_class_get_shadow(self):
-        from pypy.lang.smalltalk.shadow import ClassShadow
+    def as_special_get_shadow(self, TheClass):
         shadow = self._shadow
         if shadow is None:
-            self._shadow = shadow = ClassShadow(self)
-        assert isinstance(shadow, ClassShadow)      # for now, the only kind
+            self._shadow = shadow = TheClass(self)
+        assert isinstance(shadow, TheClass)
+        return shadow
+
+    def as_class_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import ClassShadow
+        shadow = self.as_special_get_shadow(ClassShadow)
         shadow.check_for_updates()
         return shadow
 
+    def as_semaphore_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import SemaphoreShadow
+        from pypy.lang.smalltalk import classtable
+        assert self.getclass() == classtable.classtable["w_Semaphore"]
+        return self.as_special_get_shadow(SemaphoreShadow)
+
+    def as_linkedlist_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import LinkedListShadow
+        from pypy.lang.smalltalk import classtable
+        return self.as_special_get_shadow(LinkedListShadow)
+
+    def as_process_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import ProcessShadow
+        from pypy.lang.smalltalk import classtable
+        assert self.getclass() == classtable.classtable["w_Process"]
+        return self.as_special_get_shadow(ProcessShadow)
+
+    def as_scheduler_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import SchedulerShadow
+        return self.as_special_get_shadow(SchedulerShadow)
+
+    def as_association_get_shadow(self):
+        from pypy.lang.smalltalk.shadow import AssociationShadow
+        return self.as_special_get_shadow(AssociationShadow)
+
     def equals(self, other):
         if not isinstance(other, W_PointersObject):
             return False
@@ -398,14 +428,23 @@
 
     def at0(self, index0):
         from pypy.lang.smalltalk import utility
+        # XXX Not tested
+        index0 -= self.headersize()
         if index0 < self.getliteralsize():
             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
             return utility.wrap_int(ord(self.bytes[index0]))
         
     def atput0(self, index0, w_value):
         from pypy.lang.smalltalk import utility
+        # XXX Not tested
+        index0 -= self.headersize()
         if index0 < self.getliteralsize():
             self.literalatput0(index0, w_value)
         else:
@@ -452,8 +491,19 @@
         # Invalid!
         raise IndexError
 
-    def store(self, index, value):
-        raise NotImplementedError
+    def store(self, index, w_value):
+        # XXX Untested code...
+
+        from pypy.lang.smalltalk import utility, objtable
+        if index == constants.CTXPART_SENDER_INDEX:
+            self.w_sender = w_value
+        elif index == constants.CTXPART_PC_INDEX:
+            self.pc = utility.unwrap_int(w_value)
+        elif index == constants.CTXPART_STACKP_INDEX:
+            self.stack = [objtable.w_nil] * utility.unwrap_int(w_value)
+        else:
+            # Invalid!
+            raise IndexError
 
     # ______________________________________________________________________
     # Method that contains the bytecode for this method/block context
@@ -594,6 +644,27 @@
         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.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)
+
+
 # Use black magic to create w_nil without running the constructor,
 # thus allowing it to be used even in the constructor of its own
 # class.  Note that we patch its class in objtable.

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	Mon Feb 18 12:33:05 2008
@@ -30,5 +30,5 @@
 
 objtable = {}
 
-for name in constants.objects_in_special_object_table:
+for name in constants.objects_needed_boot_vm:
     objtable["w_" + name] = globals()["w_" + name]

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 18 12:33:05 2008
@@ -15,7 +15,7 @@
         raise PrimitiveFailedError()
 
 def assert_valid_index(n0, w_obj):
-    if not 0 <= n0 < w_obj.size():
+    if not 0 <= n0 < w_obj.primsize():
         raise PrimitiveFailedError()
     # return the index, since from here on the annotator knows that
     # n0 cannot be negative
@@ -276,6 +276,10 @@
     w_res = utility.wrap_float(math.exp(f))
     return w_res
 
+# ___________________________________________________________________________
+# Failure
+
+FAIL = 18
 
 # ___________________________________________________________________________
 # Subscript and Stream Primitives
@@ -380,7 +384,8 @@
     s_class = w_rcvr.shadow_of_my_class()
     assert_bounds(n0, 0, s_class.instsize())
     # only pointers have non-0 size
-    assert isinstance(w_rcvr, model.W_PointersObject)
+    # XXX Now MethodContext is still own format, leave
+    #assert isinstance(w_rcvr, model.W_PointersObject)
     return w_rcvr.fetch(n0)
 
 @expose_primitive(INST_VAR_AT_PUT, unwrap_spec=[object, index1_0, object])
@@ -389,7 +394,8 @@
     s_class = w_rcvr.shadow_of_my_class()
     assert_bounds(n0, 0, s_class.instsize())
     # only pointers have non-0 size    
-    assert isinstance(w_rcvr, model.W_PointersObject)
+    # XXX Now MethodContext is still own format, leave
+    #assert isinstance(w_rcvr, model.W_PointersObject)
     w_rcvr.store(n0, w_value)
     return w_value
 
@@ -694,9 +700,13 @@
     w_frame.w_sender = interp.w_active_context
     interp.w_active_context = w_frame
 
+
 @expose_primitive(PRIMITIVE_SIGNAL, unwrap_spec=[object])
 def func(interp, w_rcvr):
-    raise PrimitiveNotYetWrittenError()
+    if w_rcvr.getclass() != classtable.classtable['w_Semaphore']:
+        raise PrimitiveFailedError()
+    w_rcvr.as_semaphore_get_shadow().synchronous_signal(interp)
+    return w_rcvr
     
 @expose_primitive(PRIMITIVE_WAIT, unwrap_spec=[object])
 def func(interp, w_rcvr):
@@ -712,7 +722,9 @@
 
 @expose_primitive(PRIMITIVE_FLUSH_CACHE, unwrap_spec=[object])
 def func(interp, w_rcvr):
-    raise PrimitiveNotYetWrittenError()
+    # XXX we currently don't care about bad flushes :) XXX
+    # raise PrimitiveNotYetWrittenError()
+    return w_rcvr
 
 # ___________________________________________________________________________
 # PrimitiveLoadInstVar

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 18 12:33:05 2008
@@ -43,9 +43,10 @@
             self.update_shadow()
 
     def update_shadow(self):
-        "Update the ClassShadow with data from the w_self class."
         from pypy.lang.smalltalk import objtable
 
+        "Update the ClassShadow with data from the w_self class."
+
         w_self = self.w_self
         # read and painfully decode the format
         classformat = utility.unwrap_int(
@@ -85,8 +86,18 @@
         # read the name
         if w_self.size() > constants.CLASS_NAME_INDEX:
             w_name = w_self.fetch(constants.CLASS_NAME_INDEX)
-            if isinstance(w_name, model.W_BytesObject):
-                self.name = w_name.as_string()
+
+        # XXX This is highly experimental XXX
+        # if the name-pos of class is not bytesobject,
+        # we are probably holding a metaclass instead of a class.
+        # metaclasses hold a pointer to the real class in the last
+        # slot. This is pos 6 in mini.image and higher in squeak3.9
+        if not isinstance(w_name, model.W_BytesObject):
+            w_realclass = w_self.fetch(w_self.size() - 1)
+            if w_realclass.size() > constants.CLASS_NAME_INDEX:
+                w_name = w_realclass.fetch(constants.CLASS_NAME_INDEX)
+        if isinstance(w_name, model.W_BytesObject):
+            self.name = w_name.as_string()
         # read the methoddict
         w_methoddict = w_self.fetch(constants.CLASS_METHODDICT_INDEX)
         w_values = w_methoddict.fetch(constants.METHODDICT_VALUES_INDEX)
@@ -121,8 +132,16 @@
             return 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
-        
+            # 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
+            return instantiate(model.W_MethodContext)
+            
         if self.instance_kind == POINTERS:
             return model.W_PointersObject(w_cls, self.instance_size+extrasize)
         elif self.instance_kind == WORDS:
@@ -194,3 +213,149 @@
         assert isinstance(method, model.W_CompiledMethod)
         self.methoddict[selector] = method
         method.w_compiledin = self.w_self
+
+class LinkedListShadow(AbstractShadow):
+    def __init__(self, w_self):
+        self.w_self = w_self
+
+    def firstlink(self):
+        return self.w_self.at0(constants.FIRST_LINK_INDEX)
+
+    def store_firstlink(self, w_object):
+        return self.w_self.atput0(constants.FIRST_LINK_INDEX, w_object)
+
+    def lastlink(self):
+        return self.w_self.at0(constants.LAST_LINK_INDEX)
+
+    def store_lastlink(self, w_object):
+        return self.w_self.atput0(constants.LAST_LINK_INDEX, w_object)
+
+    def is_empty_list(self):
+        from pypy.lang.smalltalk import objtable
+        return self.firstlink() == objtable.w_nil
+
+    def add_last_link(self, w_object):
+        if self.is_empty_list():
+            self.store_firstlink(w_object)
+        else:
+            self.lastlink().store_next(w_object)
+        # XXX Slang version stores list in process here...
+        self.store_lastlink(w_object)
+
+    def remove_first_link_of_list(self):
+        from pypy.lang.smalltalk import objtable
+        first = self.firstlink()
+        last = self.lastlink()
+        if first == last:
+            self.store_firstlink(objtable.w_nil)
+            self.store_lastlink(objtable.w_nil)
+        else:
+            next = first.as_process_get_shadow().next()
+            self.store_firstlink(next)
+        first.as_process_get_shadow().store_next(objtable.w_nil)
+        return first
+
+class SemaphoreShadow(LinkedListShadow):
+    """A shadow for Smalltalk objects that are semaphores
+    """
+    def __init__(self, w_self):
+        self.w_self = w_self
+
+    def put_to_sleep(self, s_process):
+        priority = s_process.priority()
+        s_scheduler = self.scheduler()
+        w_process_lists = s_scheduler.process_lists()
+        w_process_list = w_process_lists.at0(priority)
+        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):
+        from pypy.lang.smalltalk import objtable
+        s_scheduler = self.scheduler()
+        s_old_process = s_scheduler.active_process()
+        s_scheduler.store_active_process(s_process)
+        s_old_process.store_suspended_context(interp.w_active_context)
+        interp.w_active_context = s_process.suspended_context()
+        s_process.store_suspended_context(objtable.w_nil)
+        #reclaimableContextCount := 0
+
+    def scheduler(self):
+        from pypy.lang.smalltalk import objtable
+        w_association = objtable.objtable["w_schedulerassociationpointer"]
+        w_scheduler = w_association.as_association_get_shadow().value()
+        return w_scheduler.as_scheduler_get_shadow()
+
+    def resume(self, w_process, interp):
+        s_process = w_process.as_process_get_shadow()
+        s_scheduler = self.scheduler()
+        s_active_process = s_scheduler.active_process()
+        active_priority = s_active_process.priority()
+        new_priority = s_process.priority()
+        if new_priority > active_priority:
+            self.put_to_sleep(s_active_process)
+            self.transfer_to(s_process, interp)
+        else:
+            self.put_to_sleep(s_process)
+
+    def synchronous_signal(self, interp):
+        print "SYNCHRONOUS SIGNAL"
+        if self.is_empty_list():
+            w_value = self.w_self.at0(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)
+        else:
+            self.resume(self.remove_first_link_of_list(), interp)
+
+class LinkShadow(AbstractShadow):
+    def __init__(self, w_self):
+        self.w_self = self
+
+    def next(self):
+        return self.w_self.at0(constants.NEXT_LINK_INDEX)
+
+    def store_next(self, w_object):
+        self.w_self.atput0(constants.NEXT_LINK_INDEX, w_object)
+
+class ProcessShadow(LinkShadow):
+    """A shadow for Smalltalk objects that are processes
+    """
+    def __init__(self, w_self):
+        self.w_self = w_self
+
+    def priority(self):
+        return utility.unwrap_int(self.w_self.at0(constants.PROCESS_PRIORITY_INDEX))
+
+    def my_list(self):
+        return self.w_self.at0(constants.PROCESS_MY_LIST_INDEX)
+
+    def store_my_list(self, w_object):
+        self.w_self.atput0(constants.PROCESS_MY_LIST_INDEX, w_object)
+
+    def suspended_context(self):
+        return self.w_self.at0(constants.PROCESS_SUSPENDED_CONTEXT_INDEX)
+
+    def store_suspended_context(self, w_object):
+        self.w_self.atput0(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.at0(constants.ASSOCIATION_KEY_INDEX)
+
+    def value(self):
+        return self.w_self.at0(constants.ASSOCIATION_VALUE_INDEX)
+
+class SchedulerShadow(AbstractShadow):
+    def __init__(self, w_self):
+        self.w_self = w_self
+
+    def active_process(self):
+        return self.w_self.at0(constants.SCHEDULER_ACTIVE_PROCESS_INDEX).as_process_get_shadow()
+
+    def store_active_process(self, w_object):
+        self.w_self.atput0(constants.SCHEDULER_ACTIVE_PROCESS_INDEX, w_object)
+    
+    def process_lists(self):
+        return self.w_self.at0(constants.SCHEDULER_PROCESS_LISTS_INDEX)

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py	Mon Feb 18 12:33:05 2008
@@ -123,15 +123,25 @@
         for chunk in self.chunks.itervalues():
             chunk.g_object.init_w_object()
 
+    def class_indxs(self):
+        from pypy.lang.smalltalk import constants
+        return map(lambda key: (key, constants.classes_in_special_object_table[key]),
+                                     constants.classes_needed_boot_vm)
+
+    def object_indxs(self):
+        from pypy.lang.smalltalk import constants
+        return map(lambda key: (key, constants.objects_in_special_object_table[key]),
+                                     constants.objects_needed_boot_vm)
+
     def assign_prebuilt_constants(self):
         from pypy.lang.smalltalk import classtable, constants, objtable
         # assign w_objects for objects that are already in classtable
-        for name, so_index in constants.classes_in_special_object_table.items():
+        for name, so_index in self.class_indxs():
             # w_object = getattr(classtable, "w_" + name)
             w_object = classtable.classtable["w_" + name]
             self.special_object(so_index).w_object = w_object
         # assign w_objects for objects that are already in objtable
-        for name, so_index in constants.objects_in_special_object_table.items():
+        for name, so_index in self.object_indxs():
             # w_object = getattr(objtable, "w_" + name)
             w_object = objtable.objtable["w_" + name]
             self.special_object(so_index).w_object = w_object
@@ -197,10 +207,18 @@
 class SqueakImage(object):
 
     def from_reader(self, reader):
+        from pypy.lang.smalltalk import constants, classtable
         self.special_objects = [g_object.w_object for g_object in
                                 reader.chunks[reader.specialobjectspointer]
                                 .g_object.pointers]
+        # After loading we know of more classes than before. Copy back.
+        for name, so_index in constants.classes_in_special_object_table.items():
+            classtable.classtable["w_" + name] = self.special(so_index)
+
+        # After loading we know of more objects than before. Copy back.
         self.objects = [chunk.g_object.w_object for chunk in reader.chunklist]
+        for name, so_index in constants.objects_in_special_object_table.items():
+            objtable.objtable["w_" + name] = self.special(so_index)
 
     def special(self, index):
         return self.special_objects[index]

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 18 12:33:05 2008
@@ -227,7 +227,7 @@
     assert w_false is objtable.w_false
     
 def test_compile_method():
-    py.test.skip("Not working yet.")
+    # py.test.skip("Not working yet.")
     sourcecode = """fib 
                         ^self < 2 
                             ifTrue: [ 1 ] 



More information about the Pypy-commit mailing list