[pypy-commit] pypy dynamic-specialized-tuple: Added support for strings. This is probably enough types for now.

alex_gaynor noreply at buildbot.pypy.org
Wed Mar 14 19:29:58 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53563:fbd62cc44b7e
Date: 2012-03-14 11:29 -0700
http://bitbucket.org/pypy/pypy/changeset/fbd62cc44b7e/

Log:	Added support for strings. This is probably enough types for now.

diff --git a/pypy/objspace/std/tupletype.py b/pypy/objspace/std/tupletype.py
--- a/pypy/objspace/std/tupletype.py
+++ b/pypy/objspace/std/tupletype.py
@@ -4,7 +4,7 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.rlib.rerased_raw import UntypedStorage, INT, BOOL, INSTANCE
+from pypy.rlib.rerased_raw import UntypedStorage, INT, BOOL, INSTANCE, STRING
 from pypy.rlib.unroll import unrolling_iterable
 
 
@@ -31,6 +31,13 @@
 def _get_bool(space, storage, idx):
     return space.wrap(storage.getbool(idx))
 
+def _check_str(space, w_obj):
+    return space.is_w(space.type(w_obj), space.w_str)
+def _store_str(space, storage, idx, w_obj):
+    storage.setstr(idx, space.str_w(w_obj))
+def _get_str(space, storage, idx):
+    return space.wrap(storage.getstr(idx))
+
 def _check_instance(space, w_obj):
     return True
 def _store_instance(space, storage, idx, w_obj):
@@ -41,6 +48,7 @@
 SPECIALIZED_TYPES = unrolling_iterable([
     (INT, _check_int, _store_int, _get_int),
     (BOOL, _check_bool, _store_bool, _get_bool),
+    (STRING, _check_str, _store_str, _get_str),
     (INSTANCE, _check_instance, _store_instance, _get_instance)
 ])
 
diff --git a/pypy/rlib/rerased_raw.py b/pypy/rlib/rerased_raw.py
--- a/pypy/rlib/rerased_raw.py
+++ b/pypy/rlib/rerased_raw.py
@@ -20,6 +20,7 @@
 BOOL = "b"
 FLOAT = "f"
 INSTANCE = "o"
+STRING = "s"
 
 class UntypedStorage(object):
     def __init__(self, shape):
@@ -75,6 +76,17 @@
         assert self.shape[idx] == INSTANCE
         self.storage[idx] = obj
 
+    def getstr(self, idx):
+        assert self.shape[idx] == STRING
+        s = self.storage[idx]
+        assert isinstance(s, str)
+        return s
+
+    def setstr(self, idx, s):
+        assert self.shape[idx] == STRING
+        assert isinstance(s, str)
+        self.storage[idx] = s
+
 class UntypedStorageEntry(ExtRegistryEntry):
     _about_ = UntypedStorage
 
@@ -139,6 +151,15 @@
         self._check_idx(s_idx)
         assert isinstance(s_obj, annmodel.SomeInstance)
 
+    def method_getstr(self, s_idx):
+        self._check_idx(s_idx)
+        return annmodel.SomeString()
+
+    def method_setstr(self, s_idx, s_s):
+        self._check_idx(s_idx)
+        assert annmodel.SomeString().contains(s_s)
+
+
 class __extend__(pairtype(SomeUntypedStorage, SomeUntypedStorage)):
     def union((self, other)):
         return SomeUntypedStorage()
@@ -189,8 +210,8 @@
         char = (shape + llmemory.offsetof(STR, "chars") +
                 llmemory.itemoffsetof(STR.chars, 0) +
                 (llmemory.sizeof(STR.chars.OF) * i)).char[0]
-        # If it's an instance then we've found a GC pointer.
-        if char == INSTANCE:
+        # If it's an instance or string then we've found a GC pointer.
+        if char == INSTANCE or char == STRING:
             return data_ptr
         i += 1
     # If we've gotten to here, there are no GC-pointers left, return NULL to
@@ -220,6 +241,14 @@
         c_name = hop.inputconst(lltype.Void, "data")
         hop.genop("setinteriorfield", [v_arr, c_name, v_idx, v_value])
 
+    def _write_index_gc(self, hop, v_value):
+        v_arr = hop.inputarg(self, arg=0)
+        hop.genop("gc_writebarrier", [v_value, v_arr])
+        v_addr = hop.genop("cast_ptr_to_adr", [v_value],
+                           resulttype=llmemory.Address)
+
+        self._write_index(hop, v_addr)
+
     def convert_const(self, value):
         storage = self.ll_new(llstr(value.shape))
         for idx, (char, obj) in enumerate(zip(value.shape, value.storage)):
@@ -282,13 +311,18 @@
         return hop.genop("cast_adr_to_ptr", [v_addr], resulttype=hop.r_result.lowleveltype)
 
     def rtype_method_setinstance(self, hop):
-        v_arr = hop.inputarg(self, arg=0)
         v_instance = hop.inputarg(hop.args_r[2], arg=2)
-        hop.genop("gc_writebarrier", [v_instance, v_arr])
 
-        v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
-                           resulttype=llmemory.Address)
-        self._write_index(hop, v_addr)
+        self._write_index_gc(hop, v_instance)
+
+    def rtype_method_getstr(self, hop):
+        v_addr = self._read_index(hop)
+        return hop.genop("cast_adr_to_ptr", [v_addr], resulttype=string_repr)
+
+    def rtype_method_setstr(self, hop):
+        v_value = hop.inputarg(string_repr, arg=2)
+
+        self._write_index_gc(hop, v_value)
 
     @classmethod
     def ll_new(cls, shape):
diff --git a/pypy/rlib/test/test_rerased_raw.py b/pypy/rlib/test/test_rerased_raw.py
--- a/pypy/rlib/test/test_rerased_raw.py
+++ b/pypy/rlib/test/test_rerased_raw.py
@@ -5,47 +5,53 @@
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
 
 
-def test_direct_int():
-    storage = rerased_raw.UntypedStorage("ii")
+class TestUntypedStorageDirect(object):
+    def test_int(self):
+        storage = rerased_raw.UntypedStorage("ii")
 
-    storage.setint(0, 2)
-    assert storage.getint(0) == 2
+        storage.setint(0, 2)
+        assert storage.getint(0) == 2
 
-    storage.setint(1, 5)
-    assert storage.getint(1) == 5
+        storage.setint(1, 5)
+        assert storage.getint(1) == 5
 
-def test_direct_float():
-    storage = rerased_raw.UntypedStorage("f")
-    storage.setfloat(0, 5.5)
+    def test_float(self):
+        storage = rerased_raw.UntypedStorage("f")
+        storage.setfloat(0, 5.5)
 
-    assert storage.getfloat(0) == 5.5
+        assert storage.getfloat(0) == 5.5
 
-def test_direct_bool():
-    storage = rerased_raw.UntypedStorage("bi")
-    storage.setbool(0, True)
+    def test_bool(self):
+        storage = rerased_raw.UntypedStorage("bi")
+        storage.setbool(0, True)
 
-    assert storage.getbool(0) is True
+        assert storage.getbool(0) is True
 
-def test_direct_instance():
-    class A(object):
-        def __init__(self, value):
-            self.value = value
+    def test_instance(self):
+        class A(object):
+            def __init__(self, value):
+                self.value = value
 
-    storage = rerased_raw.UntypedStorage("o")
-    storage.setinstance(0, A(4))
+        storage = rerased_raw.UntypedStorage("o")
+        storage.setinstance(0, A(4))
 
-    assert storage.getinstance(0, A).value == 4
+        assert storage.getinstance(0, A).value == 4
 
-def test_direct_getlength():
-    storage = rerased_raw.UntypedStorage("ooi")
-    assert storage.getlength() == 3
+    def test_str(self):
+        storage = rerased_raw.UntypedStorage("s")
+        storage.setstr(0, "abc")
 
-def test_direct_getshape():
-    storage = rerased_raw.UntypedStorage("ooi")
-    assert storage.getshape() == "ooi"
+        assert storage.getstr(0) == "abc"
 
+    def test_getlength(self):
+        storage = rerased_raw.UntypedStorage("ooi")
+        assert storage.getlength() == 3
 
-class TestRerasedRawLLType(LLRtypeMixin, BaseRtypingTest):
+    def test_getshape(self):
+        storage = rerased_raw.UntypedStorage("ooi")
+        assert storage.getshape() == "ooi"
+
+class TestUntypedStorageLLType(LLRtypeMixin, BaseRtypingTest):
     def test_int(self):
         def f(x):
             storage = rerased_raw.UntypedStorage("i")
@@ -64,6 +70,16 @@
         res = self.interpret(f, [True])
         assert res == True
 
+    def test_float(self):
+        py.test.skip("no float support yet")
+        def f(x):
+            storage = rerased_raw.UntypedStorage("f")
+            storage.setfloat(0, x)
+            return storage.getfloat(0)
+
+        res = self.interpret(f, [12.3])
+        assert res == 12.3
+
     def test_instance(self):
         class A(object):
             def __init__(self, v):
@@ -77,14 +93,15 @@
         res = self.interpret(f, [27])
         assert res == 27
 
-    # def test_float(self):
-    #     def f(x):
-    #         storage = rerased_raw.UntypedStorage("f")
-    #         storage.setfloat(0, x)
-    #         return storage.getfloat(0)
+    def test_str(self):
+        data = ["abc"]
+        def f(i):
+            storage = rerased_raw.UntypedStorage("s")
+            storage.setstr(0, data[i])
+            return storage.getstr(0)
 
-    #     res = self.interpret(f, [12.3])
-    #     assert res == 12.3
+        res = self.interpret(f, [0])
+        assert self.ll_to_string(res) == "abc"
 
     def test_exception_catching(self):
         class A(object):
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -751,17 +751,18 @@
             def __init__(self, v):
                 self.v = v
 
-        def fn(v):
-            s = UntypedStorage("io")
+        def fn(v, i):
+            s = UntypedStorage("ios")
             s.setint(0, v)
             s.setinstance(1, A(v))
+            s.setstr(2, "abc" * i)
             rgc.collect()
-            return s.getint(0) + s.getinstance(1, A).v
+            return s.getint(0) + s.getinstance(1, A).v + len(s.getstr(2))
 
-        res = self.interpret(fn, [10])
-        assert res == 20
+        res = self.interpret(fn, [10, 1])
+        assert res == 23
 
-    def test_untyped_storage_multipled_objects(self):
+    def test_untyped_storage_multiple_objects(self):
         class A(object):
             def __init__(self, v):
                 self.v = v
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -935,17 +935,18 @@
                 self.v = v
 
         def fn():
-            s = UntypedStorage("io")
+            s = UntypedStorage("ios")
             s.setint(0, 10)
             s.setinstance(1, A(10))
+            s.setstr(2, str(A(3))[:3])
             rgc.collect()
-            return s.getint(0) + s.getinstance(1, A).v
+            return s.getint(0) + s.getinstance(1, A).v + len(s.getstr(2))
         return fn
 
     def test_untyped_storage(self):
         run = self.runner("untyped_storage")
         res = run([])
-        assert res == 20
+        assert res == 23
 
     def define_untyped_storage_multiple_objects(cls):
         class A(object):


More information about the pypy-commit mailing list