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