[pypy-svn] r47205 - in pypy/branch/kill-keepalives-again/pypy/rpython: lltypesystem rctypes rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 5 22:13:12 CEST 2007
Author: arigo
Date: Fri Oct 5 22:13:09 2007
New Revision: 47205
Modified:
pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py
pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rarray.py
pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rchar_p.py
pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rmodel.py
pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/test/test_rfunc.py
Log:
Some progress on rctypes. Based on a function unsafe_getfield(ptr, name),
which does that a plain getattr(ptr, name) used to do before the introduction
of interior pointer objects. In other words, it's grossly unsafe unless we
put enough keepalives by hand around it, and has no chance to be safe on a
moving GC. Good enough for rctypes.
Modified: pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py Fri Oct 5 22:13:09 2007
@@ -297,6 +297,7 @@
def offsetof(TYPE, fldname):
assert fldname in TYPE._flds
return FieldOffset(TYPE, fldname)
+offsetof._annspecialcase_ = 'specialize:memo'
def itemoffsetof(TYPE, n=0):
return ArrayItemsOffset(TYPE) + ItemOffset(TYPE.OF) * n
Modified: pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rarray.py (original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rarray.py Fri Oct 5 22:13:09 2007
@@ -7,11 +7,13 @@
from pypy.annotation.pairtype import pairtype
from pypy.rpython.rctypes.rmodel import CTypesRefRepr, CTypesValueRepr
from pypy.rpython.rctypes.rmodel import genreccopy_arrayitem, reccopy, C_ZERO
+from pypy.rpython.rctypes.rmodel import unsafe_getfield
from pypy.rpython.rctypes.rprimitive import PrimitiveRepr
from pypy.rpython.rctypes.rpointer import PointerRepr
from pypy.rpython.rctypes.aarray import VarSizedArrayType
from pypy.annotation.model import SomeCTypesObject
from pypy.objspace.flow.model import Constant
+from pypy.rlib.objectmodel import keepalive_until_here
ArrayType = type(ARRAY(c_int, 10))
@@ -171,12 +173,13 @@
def ll_chararrayvalue(box):
from pypy.rpython.rctypes import rchar_p
- p = box.c_data
+ p = unsafe_getfield(box, 'c_data')
length = rchar_p.ll_strnlen(lltype.direct_arrayitems(p), len(p))
newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
newstr.hash = 0
for i in range(length):
newstr.chars[i] = p[i]
+ keepalive_until_here(box)
return newstr
def ll_chararrayslice(box, slice):
Modified: pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rchar_p.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rchar_p.py (original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rchar_p.py Fri Oct 5 22:13:09 2007
@@ -3,6 +3,7 @@
from pypy.rpython.rstr import AbstractStringRepr
from pypy.rpython.lltypesystem.rstr import string_repr
from pypy.rpython.rctypes.rmodel import CTypesValueRepr, C_ZERO
+from pypy.rpython.rctypes.rmodel import unsafe_getfield
from pypy.rpython.rctypes.rarray import ArrayRepr
from pypy.rpython.rctypes.rstringbuf import StringBufRepr
from pypy.annotation.pairtype import pairtype
@@ -116,7 +117,7 @@
return i
def ll_str2charp(s):
- return lltype.direct_arrayitems(s.chars)
+ return lltype.direct_arrayitems(unsafe_getfield(s, 'chars'))
def ll_charp2str(p):
if not p:
Modified: pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rmodel.py (original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/rmodel.py Fri Oct 5 22:13:09 2007
@@ -93,21 +93,15 @@
else:
# we must return a non-memory-owning box that keeps the
# memory-owning box alive
+ pdata = unsafe_getfield(p, 'c_data')
result = lltype.malloc(self.lowleveltype.TO, zero=True)
- result.c_data = p.c_data # initialize c_data pointer
+ result.c_data = pdata # initialize c_data pointer
result.c_data_owner_keepalive = p
self.const_cache[key] = result, keepalive
return result
def get_c_data(self, llops, v_box):
- if self.ownsmemory:
- inputargs = [v_box, inputconst(lltype.Void, "c_data")]
- return llops.genop('getsubstruct', inputargs,
- lltype.Ptr(self.c_data_type) )
- else:
- inputargs = [v_box, inputconst(lltype.Void, "c_data")]
- return llops.genop('getfield', inputargs,
- lltype.Ptr(self.c_data_type) )
+ return gen_unsafe_getfield(llops, v_box, 'c_data')
def get_c_data_owner(self, llops, v_box):
if self.ownsmemory:
@@ -162,19 +156,10 @@
return self.allocate_instance_ref(llops, v_c_data)
def getkeepalive(self, llops, v_box):
- try:
- TYPE = self.lowleveltype.TO.keepalive
- except AttributeError:
- return None
+ if hasattr(self.lowleveltype.TO, 'keepalive'):
+ return gen_unsafe_getfield(llops, v_box, 'keepalive')
else:
- if isinstance(TYPE, lltype.ContainerType):
- TYPE = lltype.Ptr(TYPE)
- opname = 'getsubstruct'
- else:
- opname = 'getfield'
- c_name = inputconst(lltype.Void, 'keepalive')
- return llops.genop(opname, [v_box, c_name],
- resulttype = TYPE)
+ return None
class __extend__(pairtype(CTypesRepr, CTypesRepr)):
@@ -263,6 +248,39 @@
C_ZERO = inputconst(lltype.Signed, 0)
+def unsafe_getfield(ptr, name):
+ """Equivalent of getattr(ptr, name), but if the 'name' belongs to an
+ inlined substructure of a GC pointer, it returns a raw pointer to it.
+ This is dangerous! You *have* to keep the 'ptr' alive as long as you
+ use the result - put a call to keepalive_until_here()."""
+ STRUCT = lltype.typeOf(ptr).TO
+ FIELD = getattr(STRUCT, name)
+ if isinstance(FIELD, lltype.ContainerType):
+ addr = llmemory.cast_ptr_to_adr(ptr)
+ addr += llmemory.offsetof(STRUCT, name)
+ return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(FIELD))
+ else:
+ return getattr(ptr, name)
+unsafe_getfield._annspecialcase_ = 'specialize:ll_and_arg(1)'
+
+def gen_unsafe_getfield(llops, v_ptr, name):
+ """Generate lloperations equivalent to 'unsafe_getfield(ptr, name)'."""
+ STRUCT = v_ptr.concretetype.TO
+ assert isinstance(STRUCT, lltype.Struct)
+ FIELD = getattr(STRUCT, name)
+ if isinstance(FIELD, lltype.ContainerType):
+ v_addr = llops.genop('cast_ptr_to_adr', [v_ptr],
+ resulttype = llmemory.Address)
+ c_ofs = inputconst(lltype.Signed, llmemory.offsetof(STRUCT, name))
+ v_addr = llops.genop('adr_add', [v_addr, c_ofs],
+ resulttype = llmemory.Address)
+ return llops.genop('cast_adr_to_ptr', [v_addr],
+ resulttype = lltype.Ptr(FIELD))
+ else:
+ c_name = inputconst(lltype.Void, name)
+ return llops.genop('getfield', [v_ptr, c_name],
+ resulttype = FIELD)
+
def reccopy(source, dest):
# copy recursively a structure or array onto another.
T = lltype.typeOf(source).TO
Modified: pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/test/test_rfunc.py (original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/rctypes/test/test_rfunc.py Fri Oct 5 22:13:09 2007
@@ -5,6 +5,7 @@
import py
import sys
import pypy.rpython.rctypes.implementation
+from pypy.rpython.rctypes.rmodel import unsafe_getfield
from pypy.annotation import model as annmodel
from pypy.annotation.annrpython import RPythonAnnotator
from pypy.translator.translator import TranslationContext, graphof
@@ -109,7 +110,7 @@
def str2subarray(string):
llstring = string_repr.convert_const(string)
keepalive.append(llstring)
- return lltype.direct_arrayitems(llstring.chars)
+ return lltype.direct_arrayitems(unsafe_getfield(llstring, 'chars'))
assert ll_atoi(str2subarray("")) == 0
assert ll_atoi(str2subarray("42z7")) == 42
assert ll_atoi(str2subarray("blah")) == 0
More information about the Pypy-commit
mailing list