Author: Armin Rigo <[email protected]>
Branch: nonmovable-list
Changeset: r84881:cdb701579b36
Date: 2016-06-02 15:50 +0200
http://bitbucket.org/pypy/pypy/changeset/cdb701579b36/

Log:    Translation, step 1

diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -1010,13 +1010,15 @@
 _rawptr_missing_item = _rawptr_missing_item()
 
 
-class ListSupportingRawPtr(list):
-    """Calling this class is a no-op after translation.  Before
-    translation, it returns a new instance of ListSupportingRawPtr,
-    on which rgc.nonmoving_raw_ptr_for_resizable_list() might be
+class _ResizableListSupportingRawPtr(list):
+    """Calling this class is a no-op after translation.
+
+    Before translation, it returns a new instance of
+    _ResizableListSupportingRawPtr, on which
+    rgc.nonmoving_raw_ptr_for_resizable_list() might be
     used if needed.  For now, only supports lists of chars.
     """
-    __slots__ = ('_raw_items',)   # either None or a rffi.CArray(Char)
+    __slots__ = ('_raw_items',)   # either None or a rffi.CCHARP
 
     def __init__(self, lst):
         self._raw_items = None
@@ -1141,7 +1143,8 @@
         return list.__imul__(self, other)
 
     def __repr__(self):
-        return 'ListSupportingRawPtr(%s)' % (list.__repr__(self.__as_list()),)
+        return '_ResizableListSupportingRawPtr(%s)' % (
+            list.__repr__(self.__as_list()),)
 
     def append(self, object):
         self.__resize()
@@ -1183,12 +1186,71 @@
         if self._raw_items is None:
             existing_items = list(self)
             from rpython.rtyper.lltypesystem import lltype, rffi
-            self._raw_items = lltype.malloc(rffi.CArray(lltype.Char), 
len(self),
+            self._raw_items = lltype.malloc(rffi.CCHARP.TO, len(self),
                                            flavor='raw', immortal=True)
             self.__from_list(existing_items)
             assert self._raw_items is not None
         return self._raw_items
 
+def resizable_list_supporting_raw_ptr(lst):
+    return _ResizableListSupportingRawPtr(lst)
+
 def nonmoving_raw_ptr_for_resizable_list(lst):
-    assert isinstance(lst, ListSupportingRawPtr)
+    assert isinstance(lst, _ResizableListSupportingRawPtr)
     return lst._nonmoving_raw_ptr_for_resizable_list()
+
+
+def _check_resizable_list_of_chars(s_list):
+    from rpython.annotator import model as annmodel
+    from rpython.rlib import debug
+    if annmodel.s_None.contains(s_list):
+        return    # "None", will likely be generalized later
+    if not isinstance(s_list, annmodel.SomeList):
+        raise Exception("not a list, got %r" % (s_list,))
+    if not isinstance(s_list.listdef.listitem.s_value,
+                      (annmodel.SomeChar, annmodel.SomeImpossibleValue)):
+        raise debug.NotAListOfChars
+    s_list.listdef.resize()    # must be resizable
+
+class Entry(ExtRegistryEntry):
+    _about_ = resizable_list_supporting_raw_ptr
+
+    def compute_result_annotation(self, s_list):
+        _check_resizable_list_of_chars(s_list)
+        return s_list
+
+    def specialize_call(self, hop):
+        hop.exception_cannot_occur()
+        return hop.inputarg(hop.args_r[0], 0)
+
+class Entry(ExtRegistryEntry):
+    _about_ = nonmoving_raw_ptr_for_resizable_list
+
+    def compute_result_annotation(self, s_list):
+        from rpython.rtyper.lltypesystem import lltype, rffi
+        from rpython.rtyper.llannotation import SomePtr
+        _check_resizable_list_of_chars(s_list)
+        return SomePtr(rffi.CCHARP)
+
+    def specialize_call(self, hop):
+        v_list = hop.inputarg(hop.args_r[0], 0)
+        hop.exception_cannot_occur()   # ignoring MemoryError
+        return hop.gendirectcall(ll_nonmovable_raw_ptr_for_resizable_list,
+                                 v_list)
+
+def ll_nonmovable_raw_ptr_for_resizable_list(ll_list):
+    from rpython.rtyper.lltypesystem import lltype, rffi
+    array = ll_list.items
+    if can_move(array):
+        length = ll_list.length
+        new_array = lltype.malloc(lltype.typeOf(ll_list).TO.items.TO, length,
+                                  nonmovable=True)
+        i = 0
+        while i < length:
+            new_array[i] = array[i]
+            i += 1
+        ll_list.items = new_array
+        array = new_array
+    ptr = lltype.direct_arrayitems(array)
+    # ptr is a Ptr(FixedSizeArray(Char, 1)).  Cast it to a rffi.CCHARP
+    return rffi.cast(rffi.CCHARP, ptr)
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -257,14 +257,14 @@
 def test_nonmoving_raw_ptr_for_resizable_list():
     def f(n):
         lst = ['a', 'b', 'c']
-        lst = rgc.ListSupportingRawPtr(lst)
+        lst = rgc.resizable_list_supporting_raw_ptr(lst)
         lst.append(chr(n))
         assert lst[3] == chr(n)
         assert lst[-1] == chr(n)
         #
         ptr = rgc.nonmoving_raw_ptr_for_resizable_list(lst)
         assert lst[:] == ['a', 'b', 'c', chr(n)]
-        assert lltype.typeOf(ptr) == rffi.CArrayPtr(lltype.Char)
+        assert lltype.typeOf(ptr) == rffi.CCHARP
         assert [ptr[i] for i in range(4)] == ['a', 'b', 'c', chr(n)]
         #
         lst[-3] = 'X'
@@ -273,7 +273,7 @@
         assert lst[-2] == 'Y'
         #
         addr = rffi.cast(lltype.Signed, ptr)
-        ptr = rffi.cast(rffi.CArrayPtr(lltype.Char), addr)
+        ptr = rffi.cast(rffi.CCHARP, addr)
         lst[-4] = 'g'
         assert ptr[0] == 'g'
         ptr[3] = 'H'
@@ -282,7 +282,10 @@
     #
     # direct untranslated run
     lst = f(35)
-    assert isinstance(lst, rgc.ListSupportingRawPtr)
+    assert isinstance(lst, rgc._ResizableListSupportingRawPtr)
+    #
+    # llinterp run
+    interpret(f, [35])
 
 
 # ____________________________________________________________
diff --git a/rpython/rtyper/lltypesystem/lltype.py 
b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -2174,7 +2174,8 @@
 
 
 def malloc(T, n=None, flavor='gc', immortal=False, zero=False,
-           track_allocation=True, add_memory_pressure=False):
+           track_allocation=True, add_memory_pressure=False,
+           nonmovable=False):
     assert flavor in ('gc', 'raw')
     if zero or immortal:
         initialization = 'example'
@@ -2200,7 +2201,8 @@
 
 @analyzer_for(malloc)
 def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None,
-               s_track_allocation=None, s_add_memory_pressure=None):
+               s_track_allocation=None, s_add_memory_pressure=None,
+               s_nonmovable=None):
     assert (s_n is None or s_n.knowntype == int
             or issubclass(s_n.knowntype, base_int))
     assert s_T.is_constant()
@@ -2218,6 +2220,7 @@
         assert s_track_allocation is None or s_track_allocation.is_constant()
         assert (s_add_memory_pressure is None or
                 s_add_memory_pressure.is_constant())
+        assert s_nonmovable is None or s_nonmovable.is_constant()
         # not sure how to call malloc() for the example 'p' in the
         # presence of s_extraargs
         r = SomePtr(Ptr(s_T.const))
diff --git a/rpython/rtyper/lltypesystem/test/test_lltype.py 
b/rpython/rtyper/lltypesystem/test/test_lltype.py
--- a/rpython/rtyper/lltypesystem/test/test_lltype.py
+++ b/rpython/rtyper/lltypesystem/test/test_lltype.py
@@ -659,6 +659,7 @@
         a[3] = 30
         a[4] = 40
         b0 = direct_arrayitems(a)
+        assert typeOf(b0) == Ptr(FixedSizeArray(Signed, 1))
         b1 = direct_ptradd(b0, 1)
         b2 = direct_ptradd(b1, 1)
         b3 = direct_ptradd(b0, 3)
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -348,7 +348,7 @@
 
 @typer_for(lltype.malloc)
 def rtype_malloc(hop, i_flavor=None, i_zero=None, i_track_allocation=None,
-                 i_add_memory_pressure=None):
+                 i_add_memory_pressure=None, i_nonmovable=None):
     assert hop.args_s[0].is_constant()
     vlist = [hop.inputarg(lltype.Void, arg=0)]
     opname = 'malloc'
@@ -357,8 +357,10 @@
         (i_flavor, lltype.Void),
         (i_zero, None),
         (i_track_allocation, None),
-        (i_add_memory_pressure, None))
-    (v_flavor, v_zero, v_track_allocation, v_add_memory_pressure) = kwds_v
+        (i_add_memory_pressure, None),
+        (i_nonmovable, None))
+    (v_flavor, v_zero, v_track_allocation,
+     v_add_memory_pressure, v_nonmovable) = kwds_v
     flags = {'flavor': 'gc'}
     if v_flavor is not None:
         flags['flavor'] = v_flavor.value
@@ -368,6 +370,8 @@
         flags['track_allocation'] = v_track_allocation.value
     if i_add_memory_pressure is not None:
         flags['add_memory_pressure'] = v_add_memory_pressure.value
+    if i_nonmovable is not None:
+        flags['nonmovable'] = v_nonmovable
     vlist.append(hop.inputconst(lltype.Void, flags))
 
     assert 1 <= hop.nb_args <= 2
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to