[pypy-commit] lang-smalltalk default: added firstIndexableField

lwassermann noreply at buildbot.pypy.org
Thu Jun 20 13:05:25 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r465:299db1bfe2dc
Date: 2013-06-19 12:53 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/299db1bfe2dc/

Log:	added firstIndexableField added secondary layout to
	WordsObjects which reads/writes from/into a heap-c-array

diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -65,8 +65,10 @@
                     assert isinstance(result, model.W_Object)
                     return IProxy.object_to_oop(result)
                 elif result_type is list:
-                    assert isinstance(result, list)
-                    return IProxy.list_to_carray(result)
+                    if isinstance(result, list):
+                        return IProxy.list_to_carray(result)
+                    else:
+                        return result
                 elif result_type in (int, float):
                     assert isinstance(result, result_type)
                     return result
@@ -239,7 +241,10 @@
 @expose_on_virtual_machine_proxy([oop], list)
 def firstIndexableField(w_object):
     # return a list with values (?) of w_objects variable-parts
-    raise ProxyFunctionFailed
+    if isinstance(w_object, model.W_WordsObject):
+        return w_object.convert_to_c_layout()
+    else:
+        raise ProxyFunctionFailed
 
 @expose_on_virtual_machine_proxy([int, oop], oop)
 def literalofMethod(offset, w_method):
@@ -542,8 +547,20 @@
     raise ProxyFunctionFailed
 
 @expose_on_virtual_machine_proxy([oop, int, int, int, int], int)
-def showDisplayBitsLeftTopRightBottom(w_form, l, t, r, b):
-    raise ProxyFunctionFailed
+def showDisplayBitsLeftTopRightBottom(w_dest_form, l, t, r, b):
+    # "Repaint the portion of the Smalltalk screen bounded by the affected
+    # rectangle. Used to synchronize the screen after a Bitblt to the Smalltalk
+    # Display object."
+    # We don't need to copy, because we let the stuf directly write into the
+    # display memory
+    space = IProxy.space
+    if w_dest_form.is_same_object(space.objtable['w_display']):
+        w_bitmap = w_dest_form.fetch(space, 0)
+        assert isinstance(w_bitmap, model.W_DisplayBitmap)
+        w_bitmap.flush_to_screen()
+    else:
+        print 'Drawn, but not flashed',
+    return 0
 
 @expose_on_virtual_machine_proxy([int], int)
 def signalSemaphoreWithIndex(n):
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -800,14 +800,16 @@
         return True
 
 class W_WordsObject(W_AbstractObjectWithClassReference):
-    _attrs_ = ['words']
+    _attrs_ = ['words', 'c_words', '_size']
 
     def __init__(self, space, w_class, size):
         W_AbstractObjectWithClassReference.__init__(self, space, w_class)
         self.words = [r_uint(0)] * size
+        self._size = size
 
     def fillin(self, space, g_self):
         self.words = g_self.get_ruints()
+        self._size = len(self.words)
         self.s_class = g_self.get_class().as_class_get_penumbra(space)
         self.hash = g_self.get_hash()
         self.space = space
@@ -821,10 +823,16 @@
         self.setword(index0, word)
 
     def getword(self, n):
-        return self.words[n]
+        if self.words is not None:
+            return self.words[n]
+        else:
+            return self.c_words[n]
 
     def setword(self, n, word):
-        self.words[n] = r_uint(word)
+        if self.words is not None:
+            self.words[n] = r_uint(word)
+        else:
+            self.c_words[n] = intmask(word)
 
     def short_at0(self, space, index0):
         word = intmask(self.getword(index0 / 2))
@@ -851,15 +859,19 @@
         self.setword(word_index0, value)
 
     def size(self):
-        return len(self.words)
+        return self._size
 
     def invariant(self):
         return (W_AbstractObjectWithClassReference.invariant(self) and
                 isinstance(self.words, list))
 
     def clone(self, space):
-        w_result = W_WordsObject(self.space, self.getclass(space), len(self.words))
-        w_result.words = list(self.words)
+        size = self.size()
+        w_result = W_WordsObject(self.space, self.getclass(space), size)
+        if self.words is not None:
+            w_result.words = list(self.words)
+        else:
+            w_result.words = [self.c_words[i] for i in range(size)]
         return w_result
 
     def as_repr_string(self):
@@ -869,6 +881,24 @@
     def is_array_object(self):
         return True
 
+    def convert_to_c_layout(self):
+        if self.words is None:
+            return self.c_words
+        else:
+            from spyvm.interpreter_proxy import sqIntArrayPtr
+            size = self.size()
+            old_words = self.words
+            c_words = self.c_words = lltype.malloc(sqIntArrayPtr.TO, size, flavor='raw')
+            for i in range(size):
+                c_words[i] = intmask(old_words[i])
+            self.words = None
+            return c_words
+
+    def __del__(self):
+        if self.words is None:
+            lltype.free(self.c_words, 'raw')
+
+
 NATIVE_DEPTH = 32
 
 class W_DisplayBitmap(W_AbstractObjectWithClassReference):
diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py
--- a/spyvm/test/test_model.py
+++ b/spyvm/test/test_model.py
@@ -61,6 +61,19 @@
     assert w_bytes.getword(0) == 0
     py.test.raises(IndexError, lambda: w_bytes.getword(20))
 
+def test_c_word_object():
+    w_class = mockclass(space, 0, format=shadow.WORDS)
+    w_bytes = w_class.as_class_get_shadow(space).new(20)
+    w_bytes.convert_to_c_layout()
+    assert w_bytes.getclass(space).is_same_object(w_class)
+    assert w_bytes.size() == 20
+    assert w_class.as_class_get_shadow(space).instsize() == 0
+    assert w_bytes.getword(3) == 0
+    w_bytes.setword(3, 42)
+    assert w_bytes.getword(3) == 42
+    assert w_bytes.getword(0) == 0
+    py.test.raises(IndexError, lambda: w_bytes.getword(20))
+
 def test_method_lookup():
     class mockmethod(object):
         def __init__(self, val):


More information about the pypy-commit mailing list