[pypy-commit] lang-smalltalk default: added short access to bytes/words-objects (primitives 143, 144)

lwassermann noreply at buildbot.pypy.org
Fri May 24 18:31:38 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r415:8646558cfea0
Date: 2013-05-24 13:56 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/8646558cfea0/

Log:	added short access to bytes/words-objects (primitives 143, 144)

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -728,6 +728,26 @@
         assert len(character) == 1
         self.bytes[n0] = character
 
+    def short_at0(self, space, index0):
+        from rpython.rlib.rarithmetic import intmask
+        byte_index0 = index0 * 2
+        byte0 = ord(self.getchar(byte_index0))
+        byte1 = ord(self.getchar(byte_index0 + 1)) << 8
+        if byte1 & 0x8000 != 0:
+            byte1 = intmask(0xffff0000 | byte1)
+        return space.wrap_int(byte1 | byte0)
+
+    def short_atput0(self, space, index0, w_value):
+        from rpython.rlib.rarithmetic import int_between
+        i_value = space.unwrap_int(w_value)
+        if not int_between(-32768, i_value, 0x8000):
+            raise error.PrimitiveFailedError
+        byte_index0 = index0 * 2
+        byte0 = i_value & 0xff
+        byte1 = (i_value & 0xff00) >> 8
+        self.setchar(byte_index0, chr(byte0))
+        self.setchar(byte_index0 + 1, chr(byte1))
+
     def size(self):
         return len(self.bytes)
 
@@ -797,6 +817,29 @@
     def setword(self, n, word):
         self.words[n] = r_uint(word)
 
+    def short_at0(self, space, index0):
+        word = self.getword(index0 / 2)
+        if index0 % 2 == 0:
+            short = word & 0xffff
+        else:
+            short = (word >> 16) & 0xffff
+        if short & 0x8000 != 0:
+            short = 0xffff0000 | short
+        return space.wrap_int(intmask(short))
+
+    def short_atput0(self, space, index0, w_value):
+        from rpython.rlib.rarithmetic import int_between
+        i_value = space.unwrap_int(w_value)
+        if not int_between(-32768, i_value, 0x8000):
+            raise error.PrimitiveFailedError
+        word_index0 = index0 / 2
+        word = self.getword(word_index0)
+        if index0 % 2 == 0:
+            word = (word & 0xffff0000) | (i_value & 0xffff)
+        else:
+            word = (i_value << 16) | (word & 0xffff)
+        self.setword(word_index0, word)
+
     def size(self):
         return len(self.words)
 
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -975,12 +975,27 @@
 #____________________________________________________________________________
 # Misc Primitives (138 - 149)
 VM_PATH = 142
+SHORT_AT = 143
+SHORT_AT_PUT = 144
 CLONE = 148
 
 @expose_primitive(VM_PATH, unwrap_spec=[object])
 def func(interp, s_frame, w_receiver):
     return interp.space.wrap_string(os.path.join(os.getcwd(), ''))
 
+ at expose_primitive(SHORT_AT, unwrap_spec=[object, index1_0])
+def func(interp, s_frame, w_receiver, n0):
+    if not isinstance(w_receiver, (model.W_BytesObject, model.W_WordsObject)):
+        raise PrimitiveFailedError
+    return w_receiver.short_at0(interp.space, n0)
+
+ at expose_primitive(SHORT_AT_PUT, unwrap_spec=[object, index1_0, object])
+def func(interp, s_frame, w_receiver, n0, w_value):
+    if not isinstance(w_receiver, (model.W_BytesObject, model.W_WordsObject)):
+        raise PrimitiveFailedError
+    return w_receiver.short_atput0(interp.space, n0)
+
+
 @expose_primitive(CLONE, unwrap_spec=[object])
 def func(interp, s_frame, w_arg):
     return w_arg.clone(interp.space)
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
@@ -288,6 +288,42 @@
         assert target.at0(space, i) == source.at0(space, i)
     assert hex(r_uint(target.value)) == hex(r_uint(source.value))
 
+def test_BytesObject_short_at():
+    target = model.W_BytesObject(space, None, 4)
+    target.setchar(0, chr(0x00))
+    target.setchar(1, chr(0x01))
+    target.setchar(2, chr(0x10))
+    target.setchar(3, chr(0x81))
+    assert target.short_at0(space, 0).value == 0x0100
+    assert target.short_at0(space, 1).value == intmask(0xffff8110)
+
+def test_BytesObject_short_atput():
+    target = model.W_BytesObject(space, None, 4)
+    target.short_atput0(space, 0, space.wrap_int(0x0100))
+    target.short_atput0(space, 1, space.wrap_int(intmask(0xffff8110)))
+    assert target.getchar(0) == chr(0x00)
+    assert target.getchar(1) == chr(0x01)
+    assert target.getchar(2) == chr(0x10)
+    assert target.getchar(3) == chr(0x81)
+
+def test_WordsObject_short_at():
+    target = model.W_WordsObject(space, None, 2)
+    target.setword(0, r_uint(0x00018000))
+    target.setword(1, r_uint(0x80010111))
+    assert target.short_at0(space, 0).value == intmask(0xffff8000)
+    assert target.short_at0(space, 1).value == intmask(0x0001)
+    assert target.short_at0(space, 2).value == intmask(0x0111)
+    assert target.short_at0(space, 3).value == intmask(0xffff8001)
+
+def test_WordsObject_short_atput():
+    target = model.W_WordsObject(space, None, 2)
+    target.short_atput0(space, 0, space.wrap_int(0x0100))
+    target.short_atput0(space, 1, space.wrap_int(-1))
+    target.short_atput0(space, 2, space.wrap_int(intmask(0xffff8000)))
+    target.short_atput0(space, 3, space.wrap_int(0x7fff))
+    assert target.getword(0) == 0xffff0100
+    assert target.getword(1) == 0x7fff8000
+
 @py.test.mark.skipif("socket.gethostname() == 'precise32'")
 def test_display_bitmap():
     # XXX: Patch SDLDisplay -> get_pixelbuffer() to circumvent


More information about the pypy-commit mailing list