Exemple #1
0
def ctypes2lltype(T, cobj):
    """Convert the ctypes object 'cobj' to its lltype equivalent.
    'T' is the expected lltype type.
    """
    if isinstance(T, lltype.Ptr):
        if not cobj:  # NULL pointer
            return lltype.nullptr(T.TO)
        if isinstance(T.TO, lltype.Struct):
            if T.TO._arrayfld is not None:
                lgt = getattr(cobj.contents, T.TO._arrayfld).length
                container = lltype._struct(T.TO, lgt)
            else:
                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:
                raise NotImplementedError("array with an explicit length")
        elif isinstance(T.TO, lltype.FuncType):
            _callable = get_ctypes_trampoline(T.TO, cobj)
            return lltype.functionptr(T.TO,
                                      getattr(cobj, '__name__', '?'),
                                      _callable=_callable)
        elif isinstance(T.TO, lltype.OpaqueType):
            container = lltype._opaque(T.TO)
        else:
            raise NotImplementedError(T)
        llobj = lltype._ptr(T, container, solid=True)
    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)
    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
Exemple #2
0
def ctypes2lltype(T, cobj):
    """Convert the ctypes object 'cobj' to its lltype equivalent.
    'T' is the expected lltype type.
    """
    if isinstance(T, lltype.Ptr):
        if not cobj:   # NULL pointer
            return lltype.nullptr(T.TO)
        if isinstance(T.TO, lltype.Struct):
            if T.TO._arrayfld is not None:
                raise NotImplementedError("XXX var-sized structs")
            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:
                raise NotImplementedError("array with an explicit length")
        elif isinstance(T.TO, lltype.FuncType):
            _callable = get_ctypes_trampoline(T.TO, cobj)
            return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'),
                                      _callable=_callable)
        elif isinstance(T.TO, lltype.OpaqueType):
            container = lltype._opaque(T.TO)
        else:
            raise NotImplementedError(T)
        llobj = lltype._ptr(T, container, solid=True)
    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)
    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
Exemple #3
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.Typedef):
        T = T.OF
    if isinstance(T, lltype.Ptr):
        ptrval = ctypes.cast(cobj, ctypes.c_void_p).value
        if not cobj or not ptrval:   # NULL pointer
            # CFunctionType.__nonzero__ is broken before Python 2.6
            return lltype.nullptr(T.TO)
        if isinstance(T.TO, lltype.Struct):
            if T.TO._gckind == 'gc' and ptrval & 1: # a tagged pointer
                gcref = _opaque_objs[ptrval // 2].hide()
                return lltype.cast_opaque_ptr(T, gcref)
            REAL_TYPE = T.TO
            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(REAL_TYPE, OBJECT) >= 0:
                    # figure out the real type of the object
                    containerheader = lltype._struct(OBJECT)
                    cobjheader = ctypes.cast(cobj,
                                       get_ctypes_type(lltype.Ptr(OBJECT)))
                    struct_use_ctypes_storage(containerheader,
                                              cobjheader)
                    REAL_TYPE = get_rtyper().get_type_for_typeptr(
                        containerheader.typeptr)
                    REAL_T = lltype.Ptr(REAL_TYPE)
                    cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T))
                container = lltype._struct(REAL_TYPE)
            struct_use_ctypes_storage(container, cobj)
            if REAL_TYPE != T.TO:
                p = container._as_ptr()
                container = lltype.cast_pointer(T, p)._as_obj()
            # special treatment of 'OBJECT_VTABLE' subclasses
            if get_rtyper() and lltype._castdepth(REAL_TYPE,
                                                  OBJECT_VTABLE) >= 0:
                # figure out the real object that this vtable points to,
                # and just return that
                p = get_rtyper().get_real_typeptr_for_typeptr(
                    container._as_ptr())
                container = lltype.cast_pointer(T, p)._as_obj()
        elif isinstance(T.TO, lltype.Array):
            if T.TO._hints.get('nolength', False):
                container = _array_of_unknown_length(T.TO)
                container._storage = type(cobj)(cobj.contents)
            else:
                container = _array_of_known_length(T.TO)
                container._storage = type(cobj)(cobj.contents)
        elif isinstance(T.TO, lltype.FuncType):
            cobjkey = intmask(ctypes.cast(cobj, ctypes.c_void_p).value)
            if cobjkey in _int2obj:
                container = _int2obj[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)
                cbuf = ctypes.cast(cobj, ctypes.c_void_p)
                add_storage(container, _parentable_mixin, cbuf)
        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:
        try:
            llobj = unichr(cobj)
        except (ValueError, OverflowError):
            for tc in 'HIL':
                if array(tc).itemsize == array('u').itemsize:
                    import struct
                    cobj &= 256 ** struct.calcsize(tc) - 1
                    llobj = array('u', array(tc, (cobj,)).tostring())[0]
                    break
            else:
                raise
    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.LongFloat:
        if isinstance(cobj, ctypes.c_longdouble):
            cobj = cobj.value
        llobj = r_longfloat(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
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
Exemple #5
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 isinstance(T.TO, lltype.Struct):
            REAL_TYPE = T.TO
            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(REAL_TYPE, OBJECT) >= 0:
                    # figure out the real type of the object
                    containerheader = lltype._struct(OBJECT)
                    cobjheader = ctypes.cast(
                        cobj, get_ctypes_type(lltype.Ptr(OBJECT)))
                    struct_use_ctypes_storage(containerheader,
                                              cobjheader.contents)
                    REAL_TYPE = get_rtyper().get_type_for_typeptr(
                        containerheader.typeptr)
                    REAL_T = lltype.Ptr(REAL_TYPE)
                    cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T))
                container = lltype._struct(REAL_TYPE)
            struct_use_ctypes_storage(container, cobj.contents)
            if REAL_TYPE != T.TO:
                p = container._as_ptr()
                container = lltype.cast_pointer(T, p)._as_obj()
            # special treatment of 'OBJECT_VTABLE' subclasses
            if get_rtyper() and lltype._castdepth(REAL_TYPE,
                                                  OBJECT_VTABLE) >= 0:
                # figure out the real object that this vtable points to,
                # and just return that
                p = get_rtyper().get_real_typeptr_for_typeptr(
                    container._as_ptr())
                container = lltype.cast_pointer(T, p)._as_obj()
        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
Exemple #6
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 isinstance(T.TO, lltype.Struct):
            REAL_TYPE = T.TO
            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(REAL_TYPE, OBJECT) >= 0:
                    # figure out the real type of the object
                    containerheader = lltype._struct(OBJECT)
                    cobjheader = ctypes.cast(cobj,
                                       get_ctypes_type(lltype.Ptr(OBJECT)))
                    struct_use_ctypes_storage(containerheader,
                                              cobjheader.contents)
                    REAL_TYPE = get_rtyper().get_type_for_typeptr(
                        containerheader.typeptr)
                    REAL_T = lltype.Ptr(REAL_TYPE)
                    cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T))
                container = lltype._struct(REAL_TYPE)
            struct_use_ctypes_storage(container, cobj.contents)
            if REAL_TYPE != T.TO:
                p = container._as_ptr()
                container = lltype.cast_pointer(T, p)._as_obj()
            # special treatment of 'OBJECT_VTABLE' subclasses
            if get_rtyper() and lltype._castdepth(REAL_TYPE,
                                                  OBJECT_VTABLE) >= 0:
                # figure out the real object that this vtable points to,
                # and just return that
                p = get_rtyper().get_real_typeptr_for_typeptr(
                    container._as_ptr())
                container = lltype.cast_pointer(T, p)._as_obj()
        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
Exemple #7
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