Author: Armin Rigo <[email protected]> Branch: cpyext-gc-support Changeset: r80191:5bac5cb80e81 Date: 2015-10-14 09:03 +0200 http://bitbucket.org/pypy/pypy/changeset/5bac5cb80e81/
Log: Starting diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/rawrefcount.py @@ -0,0 +1,61 @@ +# +# See documentation in pypy/doc/discussion/rawrefcount.rst +# +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rlib.objectmodel import we_are_translated, specialize +from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.rtyper import annlowlevel +from rpython.rlib import rgc + + +REFCNT_FROM_PYPY_OBJECT = 80 # == 0x50 + + +_p_list = [] # not rpython +_o_list = [] # not rpython + + +def create_link_from_pypy(p, ob): + "NOT_RPYTHON" + assert not hasattr(p, '__rawrefcount') + assert not ob.ob_pypy_link + ob.ob_pypy_link = rgc.cast_instance_to_gcref(p) + ob.ob_refcnt += REFCNT_FROM_PYPY_OBJECT + p.__rawrefcount = ob + _p_list.append(ob) + +def create_link_to_pypy(p, ob): + "NOT_RPYTHON" + assert not ob.ob_pypy_link + ob.ob_pypy_link = rgc.cast_instance_to_gcref(p) + ob.ob_refcnt += REFCNT_FROM_PYPY_OBJECT + _o_list.append(ob) + +def from_obj(OBTYPE, p): + "NOT_RPYTHON" + null = lltype.nullptr(OBTYPE) + ob = getattr(p, '__rawrefcount', null) + assert lltype.typeOf(ob) == lltype.Ptr(OBTYPE) + return ob + [email protected](0) +def to_obj(Class, ob): + pypy_gcref = ob.ob_pypy_link + if we_are_translated(): + return annlowlevel.cast_gcref_to_instance(Class, pypy_gcref) + else: + if not pypy_gcref: + return None + p = rgc.try_cast_gcref_to_instance(Class, pypy_gcref) + assert p is not None + return p + +def collect(): + "NOT_RPYTHON: for tests only" + for ob in _p_list: + xxx + +# ____________________________________________________________ + +## class Entry(ExtRegistryEntry): +## _about_ = create_link_from_pypy diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -481,6 +481,7 @@ class _GcRef(object): # implementation-specific: there should not be any after translation __slots__ = ['_x', '_handle'] + _TYPE = llmemory.GCREF def __init__(self, x): self._x = x def __hash__(self): diff --git a/rpython/rlib/test/test_rawrefcount.py b/rpython/rlib/test/test_rawrefcount.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rawrefcount.py @@ -0,0 +1,32 @@ +from rpython.rlib import rawrefcount +from rpython.rtyper.lltypesystem import lltype, llmemory + +class W_Root(object): + def __init__(self, intval=0): + self.intval = intval + +PyObjectS = lltype.Struct('PyObjectS', + ('ob_refcnt', lltype.Signed), + ('ob_pypy_link', llmemory.GCREF)) +PyObject = lltype.Ptr(PyObjectS) + + +def test_create_link_from_pypy(): + p = W_Root(42) + ob = lltype.malloc(PyObjectS, flavor='raw', zero=True, + track_allocation=False) + assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS) + assert rawrefcount.to_obj(W_Root, ob) == None + rawrefcount.create_link_from_pypy(p, ob) + assert rawrefcount.from_obj(PyObjectS, p) == ob + assert rawrefcount.to_obj(W_Root, ob) == p + +def test_create_link_to_pypy(): + p = W_Root(42) + ob = lltype.malloc(PyObjectS, flavor='raw', zero=True, + track_allocation=False) + assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS) + assert rawrefcount.to_obj(W_Root, ob) == None + rawrefcount.create_link_to_pypy(p, ob) + assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS) + assert rawrefcount.to_obj(W_Root, ob) == p _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
