コード例 #1
0
 def parse_string_to_type(self, string, consider_fn_as_fnptr):
     # This cannot be made @elidable because it calls general space
     # functions (indirectly, e.g. via the new_xxx_type() functions).
     # The get_string_to_type() function above is elidable, and we
     # hope that in almost all cases, get_string_to_type() has already
     # found an answer.
     try:
         x = self.types_dict[string]
     except KeyError:
         info = self.ctxobj.info
         index = parse_c_type.parse_c_type(info, string)
         if index < 0:
             raise self._ffi_bad_type(string)
         x = realize_c_type.realize_c_type_or_func(
             self, self.ctxobj.info.c_output, index)
         assert x is not None
         if isinstance(x, realize_c_type.W_RawFuncType):
             x.unwrap_as_fnptr(self)      # force it here
         self.types_dict[string] = x
     #
     if isinstance(x, W_CType):
         return x
     else:
         assert isinstance(x, realize_c_type.W_RawFuncType)
         if consider_fn_as_fnptr:
             return x.unwrap_as_fnptr_in_elidable()
         else:
             raise x.unexpected_fn_type(self)
コード例 #2
0
ファイル: ffi_obj.py プロジェクト: pypyjs/pypy
 def parse_string_to_type(self, string, consider_fn_as_fnptr):
     # This cannot be made @elidable because it calls general space
     # functions (indirectly, e.g. via the new_xxx_type() functions).
     # The get_string_to_type() function above is elidable, and we
     # hope that in almost all cases, get_string_to_type() has already
     # found an answer.
     try:
         x = self.types_dict[string]
     except KeyError:
         info = self.ctxobj.info
         index = parse_c_type.parse_c_type(info, string)
         if index < 0:
             num_spaces = rffi.getintfield(info, 'c_error_location')
             raise oefmt(self.w_FFIError, "%s\n%s\n%s^",
                         rffi.charp2str(info.c_error_message),
                         string,
                         " " * num_spaces)
         x = realize_c_type.realize_c_type_or_func(
             self, self.ctxobj.info.c_output, index)
         assert x is not None
         if isinstance(x, realize_c_type.W_RawFuncType):
             x.unwrap_as_fnptr(self)      # force it here
         self.types_dict[string] = x
     #
     if isinstance(x, W_CType):
         return x
     else:
         assert isinstance(x, realize_c_type.W_RawFuncType)
         if consider_fn_as_fnptr:
             return x.unwrap_as_fnptr_in_elidable()
         else:
             raise x.unexpected_fn_type(self)
コード例 #3
0
 def _build_cpython_func(self, g, fnname):
     # Build a function: in the PyPy version, these are all equivalent
     # and 'g->address' is a pointer to a function of exactly the
     # C type specified --- almost: arguments that are structs or
     # unions are replaced with pointers, and a return value that
     # would be struct or union is instead handled by passing
     # inside the function a hidden first pointer argument.
     rawfunctype = realize_c_type.realize_c_type_or_func(
         self.ffi, self.ctx.c_types, getarg(g.c_type_op))
     assert isinstance(rawfunctype, realize_c_type.W_RawFuncType)
     #
     w_ct, locs = rawfunctype.unwrap_as_nostruct_fnptr(self.ffi)
     #
     ptr = rffi.cast(rffi.CCHARP, g.c_address)
     assert ptr
     return W_FunctionWrapper(self.space, ptr, g.c_size_or_direct_fn, w_ct,
                              locs, rawfunctype, fnname)
コード例 #4
0
ファイル: lib_obj.py プロジェクト: abhinavthomas/pypy
 def _build_cpython_func(self, g, fnname):
     # Build a function: in the PyPy version, these are all equivalent
     # and 'g->address' is a pointer to a function of exactly the
     # C type specified --- almost: arguments that are structs or
     # unions are replaced with pointers, and a return value that
     # would be struct or union is instead handled by passing
     # inside the function a hidden first pointer argument.
     rawfunctype = realize_c_type.realize_c_type_or_func(
         self.ffi, self.ctx.c_types, getarg(g.c_type_op))
     assert isinstance(rawfunctype, realize_c_type.W_RawFuncType)
     #
     rawfunctype.prepare_nostruct_fnptr(self.ffi)
     #
     ptr = rffi.cast(rffi.CCHARP, g.c_address)
     assert ptr
     return W_FunctionWrapper(self.space, ptr, g.c_size_or_direct_fn,
                              rawfunctype, fnname, self.libname)
コード例 #5
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
コード例 #6
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