示例#1
0
    def fetch_int_constant(self, name):
        index = parse_c_type.search_in_globals(self.ctxobj.ctx, name)
        if index >= 0:
            g = self.ctxobj.ctx.c_globals[index]
            op = realize_c_type.getop(g.c_type_op)
            if (op == cffi_opcode.OP_CONSTANT_INT or
                  op == cffi_opcode.OP_ENUM):
                return realize_c_type.realize_global_int(self, g, index)
            raise oefmt(self.w_FFIError,
                        "function, global variable or non-integer constant "
                        "'%s' must be fetched from its original 'lib' "
                        "object", name)

        for ffi1, _ in self.included_ffis_libs:
            w_result = ffi1.fetch_int_constant(name)
            if w_result is not None:
                return w_result
        return None
示例#2
0
文件: ffi_obj.py 项目: pypyjs/pypy
    def fetch_int_constant(self, name):
        index = parse_c_type.search_in_globals(self.ctxobj.ctx, name)
        if index >= 0:
            g = self.ctxobj.ctx.c_globals[index]
            op = realize_c_type.getop(g.c_type_op)
            if (op == cffi_opcode.OP_CONSTANT_INT or
                  op == cffi_opcode.OP_ENUM):
                return realize_c_type.realize_global_int(self, g, index)
            raise oefmt(self.w_FFIError,
                        "function, global variable or non-integer constant "
                        "'%s' must be fetched from its original 'lib' "
                        "object", name)

        for ffi1, _ in self.included_ffis_libs:
            w_result = ffi1.fetch_int_constant(name)
            if w_result is not None:
                return w_result
        return None
示例#3
0
    def _build_attr(self, attr):
        index = parse_c_type.search_in_globals(self.ctx, attr)
        if index < 0:
            for ffi1, lib1 in self.ffi.included_ffis_libs:
                if lib1 is not None:
                    try:
                        w_result = lib1._get_attr_elidable(attr)
                        break  # found, break out of this loop
                    except KeyError:
                        w_result = lib1._build_attr(attr)
                        if w_result is not None:
                            break  # found, break out of this loop
                else:
                    w_result = ffi1.fetch_int_constant(attr)
                    if w_result is not None:
                        break  # found, break out of this loop
            else:
                return None  # not found at all
        else:
            space = self.space
            g = self.ctx.c_globals[index]
            op = getop(g.c_type_op)
            if (op == cffi_opcode.OP_CPYTHON_BLTN_V
                    or op == cffi_opcode.OP_CPYTHON_BLTN_N
                    or op == cffi_opcode.OP_CPYTHON_BLTN_O):
                # A function
                w_result = self._build_cpython_func(g, attr)
                #
            elif op == cffi_opcode.OP_GLOBAL_VAR:
                # A global variable of the exact type specified here
                w_ct = realize_c_type.realize_c_type(self.ffi,
                                                     self.ctx.c_types,
                                                     getarg(g.c_type_op))
                g_size = rffi.cast(lltype.Signed, g.c_size_or_direct_fn)
                if g_size != w_ct.size and g_size != 0 and w_ct.size > 0:
                    raise oefmt(
                        self.ffi.w_FFIError,
                        "global variable '%s' should be %d bytes "
                        "according to the cdef, but is actually %d", attr,
                        w_ct.size, g_size)
                ptr = rffi.cast(rffi.CCHARP, g.c_address)
                if not ptr:  # for dlopen() style
                    ptr = self.cdlopen_fetch(attr)
                w_result = cglob.W_GlobSupport(space, w_ct, ptr)
                #
            elif (op == cffi_opcode.OP_CONSTANT_INT
                  or op == cffi_opcode.OP_ENUM):
                # A constant integer whose value, in an "unsigned long long",
                # is obtained by calling the function at g->address
                w_result = realize_c_type.realize_global_int(
                    self.ffi, g, index)
                #
            elif (op == cffi_opcode.OP_CONSTANT
                  or op == cffi_opcode.OP_DLOPEN_CONST):
                # A constant which is not of integer type
                w_ct = realize_c_type.realize_c_type(self.ffi,
                                                     self.ctx.c_types,
                                                     getarg(g.c_type_op))
                fetch_funcptr = rffi.cast(realize_c_type.FUNCPTR_FETCH_CHARP,
                                          g.c_address)
                if w_ct.size <= 0:
                    raise oefmt(space.w_SystemError,
                                "constant has no known size")
                if not fetch_funcptr:  # for dlopen() style
                    assert op == cffi_opcode.OP_DLOPEN_CONST
                    ptr = self.cdlopen_fetch(attr)
                else:
                    assert op == cffi_opcode.OP_CONSTANT
                    ptr = lltype.malloc(rffi.CCHARP.TO,
                                        w_ct.size,
                                        flavor='raw')
                    self.ffi._finalizer.free_mems.append(ptr)
                    fetch_funcptr(ptr)
                w_result = w_ct.convert_to_object(ptr)
                #
            elif op == cffi_opcode.OP_DLOPEN_FUNC:
                # For dlopen(): the function of the given 'name'.  We use
                # dlsym() to get the address of something in the dynamic
                # library, which we interpret as being exactly a function of
                # the specified type.
                ptr = self.cdlopen_fetch(attr)
                w_ct = realize_c_type.realize_c_type_or_func(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                # must have returned a function type:
                assert isinstance(w_ct, realize_c_type.W_RawFuncType)
                w_ctfnptr = w_ct.unwrap_as_fnptr(self.ffi)
                w_result = W_CData(self.space, ptr, w_ctfnptr)
                #
            else:
                raise oefmt(space.w_NotImplementedError,
                            "in lib_build_attr: op=%d", op)

        assert w_result is not None
        self.dict_w[attr] = w_result
        return w_result
示例#4
0
文件: lib_obj.py 项目: mozillazg/pypy
    def _build_attr(self, attr):
        index = parse_c_type.search_in_globals(self.ctx, attr)
        if index < 0:
            for ffi1, lib1 in self.ffi.included_ffis_libs:
                if lib1 is not None:
                    try:
                        w_result = lib1._get_attr_elidable(attr)
                        break           # found, break out of this loop
                    except KeyError:
                        w_result = lib1._build_attr(attr)
                        if w_result is not None:
                            break       # found, break out of this loop
                else:
                    w_result = ffi1.fetch_int_constant(attr)
                    if w_result is not None:
                        break           # found, break out of this loop
            else:
                return None     # not found at all
        else:
            space = self.space
            g = self.ctx.c_globals[index]
            op = getop(g.c_type_op)
            if (op == cffi_opcode.OP_CPYTHON_BLTN_V or
                op == cffi_opcode.OP_CPYTHON_BLTN_N or
                op == cffi_opcode.OP_CPYTHON_BLTN_O):
                # A function
                w_result = self._build_cpython_func(g, attr)
                #
            elif op == cffi_opcode.OP_GLOBAL_VAR:
                # A global variable of the exact type specified here
                # (nowadays, only used by the ABI mode or backend
                # compatibility; see OP_GLOBAL_F for the API mode
                w_ct = realize_c_type.realize_c_type(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                g_size = rffi.cast(lltype.Signed, g.c_size_or_direct_fn)
                if g_size != w_ct.size and g_size != 0 and w_ct.size > 0:
                    raise oefmt(self.ffi.w_FFIError,
                            "global variable '%s' should be %d bytes "
                            "according to the cdef, but is actually %d",
                            attr, w_ct.size, g_size)
                ptr = rffi.cast(rffi.CCHARP, g.c_address)
                if not ptr:   # for dlopen() style
                    ptr = self.cdlopen_fetch(attr)
                w_result = cglob.W_GlobSupport(space, attr, w_ct, ptr=ptr)
                #
            elif op == cffi_opcode.OP_GLOBAL_VAR_F:
                w_ct = realize_c_type.realize_c_type(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                w_result = cglob.W_GlobSupport(space, attr, w_ct,
                                               fetch_addr=g.c_address)
                #
            elif (op == cffi_opcode.OP_CONSTANT_INT or
                  op == cffi_opcode.OP_ENUM):
                # A constant integer whose value, in an "unsigned long long",
                # is obtained by calling the function at g->address
                w_result = realize_c_type.realize_global_int(self.ffi, g,
                                                             index)
                #
            elif (op == cffi_opcode.OP_CONSTANT or
                  op == cffi_opcode.OP_DLOPEN_CONST):
                # A constant which is not of integer type
                w_ct = realize_c_type.realize_c_type(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                fetch_funcptr = rffi.cast(
                    realize_c_type.FUNCPTR_FETCH_CHARP,
                    g.c_address)
                if w_ct.size <= 0:
                    raise oefmt(self.ffi.w_FFIError,
                                "constant '%s' is of type '%s', "
                                "whose size is not known", attr, w_ct.name)
                    raise oefmt(space.w_SystemError,
                                "constant has no known size")
                if not fetch_funcptr:   # for dlopen() style
                    assert op == cffi_opcode.OP_DLOPEN_CONST
                    ptr = self.cdlopen_fetch(attr)
                else:
                    assert op == cffi_opcode.OP_CONSTANT
                    ptr = lltype.malloc(rffi.CCHARP.TO, w_ct.size, flavor='raw')
                    self.ffi._finalizer.free_mems.append(ptr)
                    fetch_funcptr(ptr)
                w_result = w_ct.convert_to_object(ptr)
                #
            elif op == cffi_opcode.OP_DLOPEN_FUNC:
                # For dlopen(): the function of the given 'name'.  We use
                # dlsym() to get the address of something in the dynamic
                # library, which we interpret as being exactly a function of
                # the specified type.
                ptr = self.cdlopen_fetch(attr)
                w_ct = realize_c_type.realize_c_type_or_func(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                # must have returned a function type:
                assert isinstance(w_ct, realize_c_type.W_RawFuncType)
                w_ctfnptr = w_ct.unwrap_as_fnptr(self.ffi)
                w_result = W_CData(self.space, ptr, w_ctfnptr)
                #
                #
            elif op == cffi_opcode.OP_EXTERN_PYTHON:
                # for reading 'lib.bar' where bar is declared
                # as an extern "Python"
                w_ct = realize_c_type.realize_c_type(
                    self.ffi, self.ctx.c_types, getarg(g.c_type_op))
                ptr = lltype.direct_fieldptr(g, 'c_size_or_direct_fn')
                w_result = w_ct.convert_to_object(rffi.cast(rffi.CCHARP, ptr))
            else:
                raise oefmt(space.w_NotImplementedError,
                            "in lib_build_attr: op=%d", op)

        assert w_result is not None
        self.dict_w[attr] = w_result
        return w_result