[pypy-commit] pypy default: Support list(some_string) and list(some_unicode) in RPython.

arigo noreply at buildbot.pypy.org
Thu Sep 4 17:36:21 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r73303:4b4f0a70d03c
Date: 2014-09-04 17:18 +0200
http://bitbucket.org/pypy/pypy/changeset/4b4f0a70d03c/

Log:	Support list(some_string) and list(some_unicode) in RPython.

diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -1152,6 +1152,24 @@
         return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
     do_stringformat = classmethod(do_stringformat)
 
+    def ll_string2list(RESLIST, src):
+        length = len(src.chars)
+        lst = RESLIST.ll_newlist(length)
+        dst = lst.ll_items()
+        SRC = typeOf(src).TO     # STR or UNICODE
+        DST = typeOf(dst).TO     # GcArray
+        assert DST.OF is SRC.chars.OF
+        # from here, no GC operations can happen
+        asrc = llmemory.cast_ptr_to_adr(src) + (
+            llmemory.offsetof(SRC, 'chars') +
+            llmemory.itemoffsetof(SRC.chars, 0))
+        adst = llmemory.cast_ptr_to_adr(dst) + llmemory.itemoffsetof(DST, 0)
+        llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(DST.OF) * length)
+        # end of "no GC" section
+        keepalive_until_here(src)
+        keepalive_until_here(dst)
+        return lst
+
 TEMP = GcArray(Ptr(STR))
 TEMP_UNICODE = GcArray(Ptr(UNICODE))
 
diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py
--- a/rpython/rtyper/rstr.py
+++ b/rpython/rtyper/rstr.py
@@ -372,6 +372,17 @@
         ll_fn = getattr(r_str.ll, 'll_stringslice_%s' % (kind,))
         return hop.gendirectcall(ll_fn, v_str, *vlist)
 
+    def rtype_bltn_list(self, hop):
+        string_repr = hop.args_r[0].repr
+        if hop.r_result.LIST.ITEM != string_repr.lowleveltype.TO.chars.OF:
+            raise TyperError("list(str-or-unicode) returns a list of chars; "
+                             "it cannot return a list of %r" % (
+                                 hop.r_result.LIST.ITEM,))
+        v_str, = hop.inputargs(string_repr)
+        cRESLIST = hop.inputconst(Void, hop.r_result.LIST)
+        hop.exception_is_here()
+        return hop.gendirectcall(self.ll.ll_string2list, cRESLIST, v_str)
+
 
 class AbstractUnicodeRepr(AbstractStringRepr):
 
diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py
--- a/rpython/rtyper/test/test_rlist.py
+++ b/rpython/rtyper/test/test_rlist.py
@@ -430,6 +430,36 @@
                 res = self.interpret(dummyfn, ())
                 assert res == 42
 
+    def test_bltn_list_from_string(self):
+        def dummyfn(n):
+            l1 = list(str(n))
+            return ord(l1[0])
+        res = self.interpret(dummyfn, [71234])
+        assert res == ord('7')
+
+    def test_bltn_list_from_unicode(self):
+        def dummyfn(n):
+            l1 = list(unicode(str(n)))
+            return ord(l1[0])
+        res = self.interpret(dummyfn, [71234])
+        assert res == ord('7')
+
+    def test_bltn_list_from_string_resize(self):
+        def dummyfn(n):
+            l1 = list(str(n))
+            l1.append('X')
+            return ord(l1[0])
+        res = self.interpret(dummyfn, [71234])
+        assert res == ord('7')
+
+    def test_bltn_list_from_unicode_resize(self):
+        def dummyfn(n):
+            l1 = list(unicode(str(n)))
+            l1.append(u'X')
+            return ord(l1[0])
+        res = self.interpret(dummyfn, [71234])
+        assert res == ord('7')
+
     def test_is_true(self):
         def is_true(lst):
             if lst:


More information about the pypy-commit mailing list