コード例 #1
0
    def test_pass_around_t_object(self):
        from pypy.rpython.annlowlevel import base_ptr_lltype
        T = base_ptr_lltype()
        
        class X(object):
            _TYPE = T
            x = 10

        def callback(x):
            return x.x

        c_source = py.code.Source("""
        int eating_callback(void *arg, int(*call)(int))
        {
            return call(arg);
        }
        """)

        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [T, rffi.CCallback([T], rffi.INT)]
        eating_callback = rffi.llexternal('eating_callback', args, rffi.INT,
                                          compilation_info=eci)

        res = eating_callback(X(), callback)
        assert res == 10
コード例 #2
0
    def test_pass_around_t_object(self):
        from pypy.rpython.annlowlevel import base_ptr_lltype
        T = base_ptr_lltype()

        class X(object):
            _TYPE = T
            x = 10

        def callback(x):
            return x.x

        c_source = py.code.Source("""
        long eating_callback(void *arg, long(*call)(void*))
        {
            return call(arg);
        }
        """)

        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [T, rffi.CCallback([T], rffi.LONG)]
        eating_callback = rffi.llexternal('eating_callback',
                                          args,
                                          rffi.LONG,
                                          compilation_info=eci)

        res = eating_callback(X(), callback)
        assert res == 10
コード例 #3
0
ファイル: test_annlowlevel.py プロジェクト: Debug-Orz/Sypy
 def test_cast_instance_to_base_ptr(self):
     class X(object):
         pass
     x = X()
     ptr = annlowlevel.cast_instance_to_base_ptr(x)
     assert lltype.typeOf(ptr) == annlowlevel.base_ptr_lltype()
     y = annlowlevel.cast_base_ptr_to_instance(X, ptr)
     assert y is x
コード例 #4
0
    def test_cast_instance_to_base_ptr(self):
        class X(object):
            pass

        x = X()
        ptr = annlowlevel.cast_instance_to_base_ptr(x)
        assert lltype.typeOf(ptr) == annlowlevel.base_ptr_lltype()
        y = annlowlevel.cast_base_ptr_to_instance(X, ptr)
        assert y is x
コード例 #5
0
def new_opaque_object(llobj):
    try:
        return _opaque_cache[llobj]
    except KeyError:
        assert len(_opaque_cache) == len(_opaque_list)
        ctypes_type = get_ctypes_type(base_ptr_lltype())
        val = ctypes.cast(len(_opaque_cache), ctypes_type)
        _opaque_list.append(llobj)
        _opaque_cache[llobj] = val
        return val
コード例 #6
0
def new_opaque_object(llobj):
    try:
        return _opaque_cache[llobj]
    except KeyError:
        assert len(_opaque_cache) == len(_opaque_list)
        ctypes_type = get_ctypes_type(base_ptr_lltype())
        val = ctypes.cast(len(_opaque_cache), ctypes_type)
        _opaque_list.append(llobj)
        _opaque_cache[llobj] = val
        return val
コード例 #7
0
ファイル: test_llann.py プロジェクト: Debug-Orz/Sypy
def test_cast_instance_to_base_ptr():
    class A:
        def __init__(self, x, y):
            self.x = x
            self.y = y

    def f(x, y):
        if x > 20:
            a = None
        else:
            a = A(x, y)
        a1 = cast_instance_to_base_ptr(a)
        return a1

    res = interpret(f, [5, 10])
    assert typeOf(res) == base_ptr_lltype()
    assert fishllattr(res, 'x') == 5
    assert fishllattr(res, 'y') == 10

    res = interpret(f, [25, 10])
    assert res == nullptr(base_ptr_lltype().TO)
コード例 #8
0
ファイル: test_llann.py プロジェクト: nipengadmaster/pypy
def test_cast_instance_to_base_ptr():
    class A:
        def __init__(self, x, y):
            self.x = x
            self.y = y

    def f(x, y):
        if x > 20:
            a = None
        else:
            a = A(x, y)
        a1 = cast_instance_to_base_ptr(a)
        return a1

    res = interpret(f, [5, 10])
    assert typeOf(res) == base_ptr_lltype()
    assert fishllattr(res, 'x') == 5
    assert fishllattr(res, 'y') == 10

    res = interpret(f, [25, 10])
    assert res == nullptr(base_ptr_lltype().TO)
コード例 #9
0
ファイル: rgc.py プロジェクト: ieure/pypy
def try_cast_gcref_to_instance(Class, gcref):
    # Before translation, unwraps the RPython instance contained in a _GcRef.
    # After translation, it is a type-check performed by the GC.
    if we_are_translated():
        from pypy.rpython.annlowlevel import base_ptr_lltype
        from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
        from pypy.rpython.lltypesystem import rclass
        if _is_rpy_instance(gcref):
            objptr = lltype.cast_opaque_ptr(base_ptr_lltype(), gcref)
            if objptr.typeptr:   # may be NULL, e.g. in rdict's dummykeyobj
                clsptr = _get_llcls_from_cls(Class)
                if rclass.ll_isinstance(objptr, clsptr):
                    return cast_base_ptr_to_instance(Class, objptr)
        return None
    else:
        if isinstance(gcref._x, Class):
            return gcref._x
        return None
コード例 #10
0
ファイル: rgc.py プロジェクト: purepython/pypy
def try_cast_gcref_to_instance(Class, gcref):
    # Before translation, unwraps the RPython instance contained in a _GcRef.
    # After translation, it is a type-check performed by the GC.
    if we_are_translated():
        from pypy.rpython.annlowlevel import base_ptr_lltype
        from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
        from pypy.rpython.lltypesystem import rclass
        if _is_rpy_instance(gcref):
            objptr = lltype.cast_opaque_ptr(base_ptr_lltype(), gcref)
            if objptr.typeptr:  # may be NULL, e.g. in rdict's dummykeyobj
                clsptr = _get_llcls_from_cls(Class)
                if rclass.ll_isinstance(objptr, clsptr):
                    return cast_base_ptr_to_instance(Class, objptr)
        return None
    else:
        if isinstance(gcref._x, Class):
            return gcref._x
        return None
コード例 #11
0
#
#     class Numbering: __slots__ = ['prev', 'nums']
#
# except that it is more compact in translated programs, because the
# array 'nums' is inlined in the single NUMBERING object.  This is
# important because this is often the biggest single consumer of memory
# in a pypy-c-jit.
#
NUMBERINGP = lltype.Ptr(lltype.GcForwardReference())
NUMBERING = lltype.GcStruct('Numbering',
                            ('prev', NUMBERINGP),
                            ('nums', lltype.Array(rffi.SHORT)))
NUMBERINGP.TO.become(NUMBERING)

PENDINGFIELDSTRUCT = lltype.Struct('PendingField',
                                   ('lldescr', annlowlevel.base_ptr_lltype()),
                                   ('num', rffi.SHORT),
                                   ('fieldnum', rffi.SHORT),
                                   ('itemindex', rffi.INT))
PENDINGFIELDSP = lltype.Ptr(lltype.GcArray(PENDINGFIELDSTRUCT))

TAGMASK = 3

def tag(value, tagbits):
    if tagbits >> 2:
        raise ValueError
    sx = value >> 13
    if sx != 0 and sx != -1:
        raise ValueError
    return rffi.r_short(value<<2|tagbits)
コード例 #12
0
def ctypes2lltype(T, cobj):
    """Convert the ctypes object 'cobj' to its lltype equivalent.
    'T' is the expected lltype type.
    """
    if T is lltype.Void:
        return None
    if isinstance(T, lltype.Ptr):
        if not cobj:   # NULL pointer
            return lltype.nullptr(T.TO)
        if T is base_ptr_lltype():
            return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value]
        if isinstance(T.TO, lltype.Struct):
            if T.TO._arrayfld is not None:
                carray = getattr(cobj.contents, T.TO._arrayfld)
                container = lltype._struct(T.TO, carray.length)
            else:
                # special treatment of 'OBJECT' subclasses
                if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0:
                    ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT))
                    as_obj = ctypes2lltype(lltype.Ptr(OBJECT),
                                           ctypes.cast(cobj, ctypes_object))
                    TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr)
                    if TObj != T.TO:
                        ctypes_instance = get_ctypes_type(lltype.Ptr(TObj))
                        return lltype.cast_pointer(T,
                            ctypes2lltype(lltype.Ptr(TObj),
                                          ctypes.cast(cobj, ctypes_instance)))
                container = lltype._struct(T.TO)
            struct_use_ctypes_storage(container, cobj.contents)
        elif isinstance(T.TO, lltype.Array):
            if T.TO._hints.get('nolength', False):
                container = _array_of_unknown_length(T.TO)
                container._storage = cobj.contents
            else:
                container = _array_of_known_length(T.TO)
                container._storage = cobj.contents
        elif isinstance(T.TO, lltype.FuncType):
            cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value
            if cobjkey in _callback2obj:
                container = _callback2obj[cobjkey]
            else:
                _callable = get_ctypes_trampoline(T.TO, cobj)
                return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'),
                                          _callable=_callable)
        elif isinstance(T.TO, lltype.OpaqueType):
            if T == llmemory.GCREF:
                # XXX obscure hack
                return _llgcref(cobj)
            else:
                container = lltype._opaque(T.TO)
        else:
            raise NotImplementedError(T)
        llobj = lltype._ptr(T, container, solid=True)
    elif T is llmemory.Address:
        if cobj is None:
            llobj = llmemory.NULL
        else:
            llobj = _lladdress(cobj)
    elif T is lltype.Char:
        llobj = chr(cobj)
    elif T is lltype.UniChar:
        llobj = unichr(cobj)
    elif T is lltype.Signed:
        llobj = cobj
    elif T is lltype.SingleFloat:
        if isinstance(cobj, ctypes.c_float):
            cobj = cobj.value
        llobj = r_singlefloat(cobj)
    elif T is lltype.Void:
        llobj = cobj
    else:
        from pypy.rpython.lltypesystem import rffi
        try:
            inttype = rffi.platform.numbertype_to_rclass[T]
        except KeyError:
            llobj = cobj
        else:
            llobj = inttype(cobj)

    assert lltype.typeOf(llobj) == T
    return llobj
コード例 #13
0
def lltype2ctypes(llobj, normalize=True):
    """Convert the lltype object 'llobj' to its ctypes equivalent.
    'normalize' should only be False in tests, where we want to
    inspect the resulting ctypes object manually.
    """
    if isinstance(llobj, lltype._uninitialized):
        return uninitialized2ctypes(llobj.TYPE)

    T = lltype.typeOf(llobj)

    if isinstance(T, lltype.Ptr):
        if not llobj:   # NULL pointer
            return get_ctypes_type(T)()

        if T is base_ptr_lltype():
            return new_opaque_object(llobj)
        if T == llmemory.GCREF:
            if isinstance(llobj, _llgcref):
                return ctypes.c_void_p(llobj.intval)
            container = llobj._obj.container
            T = lltype.Ptr(lltype.typeOf(container))
            # otherwise it came from integer and we want a c_void_p with
            # the same valu
        else:
            container = llobj._obj
        if isinstance(T.TO, lltype.FuncType):
            # XXX a temporary workaround for comparison of lltype.FuncType
            key = llobj._obj.__dict__.copy()
            key['_TYPE'] = repr(key['_TYPE'])
            items = key.items()
            items.sort()
            key = tuple(items)
            if key in _all_callbacks:
                return _all_callbacks[key]
            v1voidlist = [(i, getattr(container, '_void' + str(i), None))
                             for i in range(len(T.TO.ARGS))
                                 if T.TO.ARGS[i] is lltype.Void]
            def callback(*cargs):
                cargs = list(cargs)
                for v1 in v1voidlist:
                    cargs.insert(v1[0], v1[1])
                assert len(cargs) == len(T.TO.ARGS)
                llargs = []
                for ARG, carg in zip(T.TO.ARGS, cargs):
                    if ARG is lltype.Void:
                        llargs.append(carg)
                    else:
                        llargs.append(ctypes2lltype(ARG, carg))
                if hasattr(container, 'graph'):
                    if LLInterpreter.current_interpreter is None:
                        raise AssertionError
                    llinterp = LLInterpreter.current_interpreter
                    try:
                        llres = llinterp.eval_graph(container.graph, llargs)
                    except LLException, lle:
                        llinterp._store_exception(lle)
                        return 0
                else:
                    llres = container._callable(*llargs)
                assert lltype.typeOf(llres) == T.TO.RESULT
                if T.TO.RESULT is lltype.Void:
                    return None
                res = lltype2ctypes(llres)
                if isinstance(T.TO.RESULT, lltype.Ptr):
                    _all_callbacks_results.append(res)
                    res = ctypes.cast(res, ctypes.c_void_p).value
                    if res is None:
                        return 0
                return res

            if getattr(conftest.option, 'usepdb', False):
                callback_original = callback
                def callback(*cargs):
                    try:
                        return callback_original(*cargs)
                    except:
                        import pdb, sys; pdb.post_mortem(sys.exc_traceback)
                        raise

            if isinstance(T.TO.RESULT, lltype.Ptr):
                TMod = lltype.Ptr(lltype.FuncType(T.TO.ARGS,
                                                  lltype.Signed))
                ctypes_func_type = get_ctypes_type(TMod)
                res = ctypes_func_type(callback)
                ctypes_func_type = get_ctypes_type(T)
                res = ctypes.cast(res, ctypes_func_type)
            else:
                ctypes_func_type = get_ctypes_type(T)
                res = ctypes_func_type(callback)
            _callback2obj[ctypes.cast(res, ctypes.c_void_p).value] = container
            _all_callbacks[key] = res
            return res
コード例 #14
0
def ctypes2lltype(T, cobj):
    """Convert the ctypes object 'cobj' to its lltype equivalent.
    'T' is the expected lltype type.
    """
    if T is lltype.Void:
        return None
    if isinstance(T, lltype.Ptr):
        if not cobj:  # NULL pointer
            return lltype.nullptr(T.TO)
        if T is base_ptr_lltype():
            return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value]
        if isinstance(T.TO, lltype.Struct):
            if T.TO._arrayfld is not None:
                carray = getattr(cobj.contents, T.TO._arrayfld)
                container = lltype._struct(T.TO, carray.length)
            else:
                # special treatment of 'OBJECT' subclasses
                if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0:
                    ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT))
                    as_obj = ctypes2lltype(lltype.Ptr(OBJECT),
                                           ctypes.cast(cobj, ctypes_object))
                    TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr)
                    if TObj != T.TO:
                        ctypes_instance = get_ctypes_type(lltype.Ptr(TObj))
                        return lltype.cast_pointer(
                            T,
                            ctypes2lltype(lltype.Ptr(TObj),
                                          ctypes.cast(cobj, ctypes_instance)))
                container = lltype._struct(T.TO)
            struct_use_ctypes_storage(container, cobj.contents)
            addr = ctypes.addressof(cobj.contents)
            if addr in _parent_cache:
                setparentstructure(container, _parent_cache[addr])
        elif isinstance(T.TO, lltype.Array):
            if T.TO._hints.get('nolength', False):
                container = _array_of_unknown_length(T.TO)
                container._storage = cobj.contents
            else:
                container = _array_of_known_length(T.TO)
                container._storage = cobj.contents
        elif isinstance(T.TO, lltype.FuncType):
            cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value
            if cobjkey in _callback2obj:
                container = _callback2obj[cobjkey]
            else:
                _callable = get_ctypes_trampoline(T.TO, cobj)
                return lltype.functionptr(T.TO,
                                          getattr(cobj, '__name__', '?'),
                                          _callable=_callable)
        elif isinstance(T.TO, lltype.OpaqueType):
            if T == llmemory.GCREF:
                container = _llgcopaque(cobj)
            else:
                container = lltype._opaque(T.TO)
        else:
            raise NotImplementedError(T)
        llobj = lltype._ptr(T, container, solid=True)
    elif T is llmemory.Address:
        if cobj is None:
            llobj = llmemory.NULL
        else:
            llobj = _lladdress(cobj)
    elif T is lltype.Char:
        llobj = chr(cobj)
    elif T is lltype.UniChar:
        llobj = unichr(cobj)
    elif T is lltype.Signed:
        llobj = cobj
    elif T is lltype.Bool:
        assert cobj == True or cobj == False  # 0 and 1 work too
        llobj = bool(cobj)
    elif T is lltype.SingleFloat:
        if isinstance(cobj, ctypes.c_float):
            cobj = cobj.value
        llobj = r_singlefloat(cobj)
    elif T is lltype.Void:
        llobj = cobj
    else:
        from pypy.rpython.lltypesystem import rffi
        try:
            inttype = rffi.platform.numbertype_to_rclass[T]
        except KeyError:
            llobj = cobj
        else:
            llobj = inttype(cobj)

    assert lltype.typeOf(llobj) == T
    return llobj
コード例 #15
0
def lltype2ctypes(llobj, normalize=True):
    """Convert the lltype object 'llobj' to its ctypes equivalent.
    'normalize' should only be False in tests, where we want to
    inspect the resulting ctypes object manually.
    """
    if isinstance(llobj, lltype._uninitialized):
        return uninitialized2ctypes(llobj.TYPE)

    T = lltype.typeOf(llobj)

    if isinstance(T, lltype.Ptr):
        if not llobj:  # NULL pointer
            if T == llmemory.GCREF:
                return ctypes.c_void_p(0)
            return get_ctypes_type(T)()

        if T is base_ptr_lltype():
            return new_opaque_object(llobj)
        if T == llmemory.GCREF:
            if isinstance(llobj._obj, _llgcopaque):
                return ctypes.c_void_p(llobj._obj.intval)
            container = llobj._obj.container
            T = lltype.Ptr(lltype.typeOf(container))
            # otherwise it came from integer and we want a c_void_p with
            # the same valu
        else:
            container = llobj._obj
        if isinstance(T.TO, lltype.FuncType):
            # XXX a temporary workaround for comparison of lltype.FuncType
            key = llobj._obj.__dict__.copy()
            key['_TYPE'] = repr(key['_TYPE'])
            items = key.items()
            items.sort()
            key = tuple(items)
            if key in _all_callbacks:
                return _all_callbacks[key]
            v1voidlist = [(i, getattr(container, '_void' + str(i), None))
                          for i in range(len(T.TO.ARGS))
                          if T.TO.ARGS[i] is lltype.Void]

            def callback_internal(*cargs):
                cargs = list(cargs)
                for v1 in v1voidlist:
                    cargs.insert(v1[0], v1[1])
                assert len(cargs) == len(T.TO.ARGS)
                llargs = []
                for ARG, carg in zip(T.TO.ARGS, cargs):
                    if ARG is lltype.Void:
                        llargs.append(carg)
                    else:
                        llargs.append(ctypes2lltype(ARG, carg))
                if hasattr(container, 'graph'):
                    if LLInterpreter.current_interpreter is None:
                        raise AssertionError
                    llinterp = LLInterpreter.current_interpreter
                    try:
                        llres = llinterp.eval_graph(container.graph, llargs)
                    except LLException, lle:
                        llinterp._store_exception(lle)
                        return 0
                    #except:
                    #    import pdb
                    #    pdb.set_trace()
                else:
                    try:
                        llres = container._callable(*llargs)
                    except LLException, lle:
                        llinterp = LLInterpreter.current_interpreter
                        llinterp._store_exception(lle)
                        return 0
                assert lltype.typeOf(llres) == T.TO.RESULT
                if T.TO.RESULT is lltype.Void:
                    return None
                res = lltype2ctypes(llres)
                if isinstance(T.TO.RESULT, lltype.Ptr):
                    _all_callbacks_results.append(res)
                    res = ctypes.cast(res, ctypes.c_void_p).value
                    if res is None:
                        return 0
                return res