Commits

An...@Anton-Vaio.hpi.uni-potsdam.de  committed d86d9bd

Fixed more things. Compiling now.

  • Participants
  • Parent commits 3437e35
  • Branches strategies

Comments (0)

Files changed (4)

File spyvm/fieldtypes.py

 
     def __init__(self):
         pass
+    def fetch_needs_objspace(self):
+        # Return True, if fetching operations use the space parameter.
+        # If not, the space-parameter can be passed in as None (probably).
+        return False
+        
     def fetch(self, space, w_obj, n0):
         raise NotImplementedError("Abstract base class")
     def store(self, space, w_obj, n0, w_val):
             # Default: reuse storage_for_list() but create intermediate list.
             # Ignore reuse_storage flag - never reuse old storage.
             # Should be overridden & optimized.
-            return self.storage_for_list(old_strategy.fetch_all(space, w_obj))
+            return self.storage_for_list(space, old_strategy.fetch_all(space, w_obj))
 
 class SingletonMeta(type):
     def __new__(cls, name, bases, dct):
         result.singleton = result()
         return result
 
+# This is a container for an int-value to be used with a rerased-pair
+class SizeStorage(object):
+    _attrs_ = ['size']
+    _settled_ = True
+    def __init__(self, size):
+        self.size = size
+
 # this is the typical "initial" storage strategy, for when every slot
 # in a var-sized object is still nil. No storage is allocated except for
 # holding the size of the object.
     def fetch_all(self, space, w_obj):
         return [model.w_nil] * self.size_of(w_obj)
     def size_of(self, w_obj):
-        return self.unerase(w_obj.storage)
+        return self.unerase(w_obj.storage).size
     def initial_storage(self, space, size):
-        return self.erase(size)
+        return self.erase(SizeStorage(size))
     def storage_for_list(self, space, collection):
-        return self.erase(len(collection))
+        return self.erase(SizeStorage(len(collection)))
     def copy_storage_from(self, space, w_obj, old_strategy, reuse_storage):
-        return self.erase(old_strategy.size_of(w_obj))
+        return self.erase(SizeStorage(old_strategy.size_of(w_obj)))
 
 # This is the regular storage strategy that does not result in any
 # optimizations but can handle every case. Applicable for both
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
     
+    def fetch_needs_objspace(self):
+        return True
     def fetch(self, space, w_obj, n0):
         store = self.unerase(w_obj.storage)
         if n0 < store._from or n0 >= store._to:
         return len(self.unerase(w_obj.storage).arr)
     def initial_storage(self, space, size):
         return self.erase(DenseSmallIntegerStorage(0, 0, size))
-    def storage_for_list(self, collection):
+    def storage_for_list(self, space, collection):
         _from = 0
         while _from < len(collection) and collection[_from] == model.w_nil:
             _from = _from+1
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
     
+    def fetch_needs_objspace(self):
+        return True
     def fetch(self, space, w_obj, n0):
         store = self.unerase(w_obj.storage)
         if store.nil_flags[n0]:
             return model.w_nil
-        return store.arr[n0]
+        return space.wrap_int(store.arr[n0])
     def store(self, space, w_obj, n0, w_val):
         store = self.unerase(w_obj.storage)
         if not isinstance(w_val, model.W_SmallInteger):
         # This is a weird and rare special case for w_nil
         return ListStorageStrategy.singleton
     if s_containing_class.isvariable():
+        # A newly allocated var-sized object contains only nils.
         return AllNilStorageStrategy.singleton
     else:
         # TODO -- use strategy-concept for fixed-size classes also.
         # This is a weird and rare special case for w_nil
         return ListStorageStrategy.singleton
     if s_containing_class.isvariable():
-        return AllNilStorageStrategy.singleton
+        is_all_nils = True
+        is_dense = True
+        for w_obj in vars:
+            if w_obj == model.w_nil:
+                if not is_all_nils:
+                    is_dense = False
+                continue
+            is_all_nils = False
+            elif not instanceof(w_obj, model.W_SmallInteger):
+                # TODO -- here we can still optimize if there is only
+                # one single type in the collection.
+                return ListStorageStrategy.singleton
+        if is_all_nils:
+            return AllNilStorageStrategy.singleton
+        if is_dense:
+            return DenseSmallIntegerStorageStrategy.singleton
+        else:
+            return SparseSmallIntegerStorageStrategy.singleton
     else:
         size = len(vars)
         typer = FixedSizeFieldTypes.of_size(size)

File spyvm/model.py

             if isinstance(w_candidate, W_PointersObject):
                 c_shadow = w_candidate._shadow
                 if c_shadow is None and w_candidate.size() >= 2:
-                    if self._shadow is not None:
-                        w_class = w_candidate._fetch(self._shadow.space, 1)
+                    if not w_candidate.strategy.fetch_needs_objspace():
+                        # We can fetch without having an object space at hand.
+                        # XXX How to get an object space from a CompiledMethodShadow, anyways?
+                        w_class = w_candidate._fetch(None, 1)
                         if isinstance(w_class, W_PointersObject):
                             d_shadow = w_class._shadow
                             if isinstance(d_shadow, shadow.ClassShadow):

File spyvm/primitives.py

         print ("%s" % w_message).replace('\r', '\n')
         print ("%s" % s_frame.peek(1)).replace('\r', '\n')
         if isinstance(w_message, model.W_PointersObject):
-            print ('%s' % w_message.fetch_all()).replace('\r', '\n')
+            print ('%s' % w_message.fetch_all(s_frame.space)).replace('\r', '\n')
         # raise Exit('Probably Debugger called...')
     raise PrimitiveFailedError()
 

File spyvm/test/test_interpreter.py

         step_in_interp(s_frame)
         assert s_frame.stack() == []
         for test_index in range(8):
-            print w_frame.fetch_all()
+            print w_frame.fetch_all(s_frame.space)
             if test_index == index:
                 assert s_frame.gettemp(test_index) == space.w_true
             else: