Example #1
0
def get_primitive_type(ffi, num):
    space = ffi.space
    if not (0 <= num < cffi_opcode._NUM_PRIM):
        if num == cffi_opcode._UNKNOWN_PRIM:
            raise oefmt(ffi.w_FFIError, "primitive integer type with an "
                        "unexpected size (or not an integer type at all)")
        elif num == cffi_opcode._UNKNOWN_FLOAT_PRIM:
            raise oefmt(ffi.w_FFIError, "primitive floating-point type with an "
                        "unexpected size (or not a float type at all)")
        elif num == cffi_opcode._UNKNOWN_LONG_DOUBLE:
            raise oefmt(ffi.w_FFIError, "primitive floating-point type is "
                        "'long double', not supported for now with "
                        "the syntax 'typedef double... xxx;'")
        else:
            raise oefmt(space.w_NotImplementedError, "prim=%d", num)
    realize_cache = space.fromcache(RealizeCache)
    w_ctype = realize_cache.all_primitives[num]
    if w_ctype is None:
        if num == cffi_opcode.PRIM_VOID:
            w_ctype = newtype.new_void_type(space)
        else:
            assert RealizeCache.NAMES[num]
            w_ctype = newtype.new_primitive_type(space, RealizeCache.NAMES[num])
        realize_cache.all_primitives[num] = w_ctype
    return w_ctype
Example #2
0
 def prepare_nostruct_fnptr(self, ffi):
     # tweaked version: instead of returning the ctfuncptr
     # corresponding exactly to the OP_FUNCTION ... OP_FUNCTION_END
     # opcodes, this builds in self.nostruct_ctype another one in
     # which the struct args are replaced with ptr-to- struct, and
     # a struct return value is replaced with a hidden first arg of
     # type ptr-to-struct.  This is how recompiler.py produces
     # trampoline functions for PyPy.
     if self.nostruct_ctype is None:
         fargs, fret, ellipsis, abi = self._unpack(ffi)
         # 'locs' will be a string of the same length as the final fargs,
         # containing 'A' where a struct argument was detected, and 'R'
         # in first position if a struct return value was detected
         locs = ['\x00'] * len(fargs)
         for i in range(len(fargs)):
             farg = fargs[i]
             if isinstance(farg, ctypestruct.W_CTypeStructOrUnion):
                 farg = newtype.new_pointer_type(ffi.space, farg)
                 fargs[i] = farg
                 locs[i] = 'A'
         if isinstance(fret, ctypestruct.W_CTypeStructOrUnion):
             fret = newtype.new_pointer_type(ffi.space, fret)
             fargs = [fret] + fargs
             locs = ['R'] + locs
             fret = newtype.new_void_type(ffi.space)
         ctfuncptr = newtype._new_function_type(
             ffi.space, fargs, fret, ellipsis, abi)
         if locs == ['\x00'] * len(locs):
             locs = None
         else:
             locs = ''.join(locs)
         self.nostruct_ctype = ctfuncptr
         self.nostruct_locs = locs
         self.nostruct_nargs = len(ctfuncptr.fargs) - (locs is not None and
                                                       locs[0] == 'R')
Example #3
0
def get_primitive_type(ffi, num):
    space = ffi.space
    if not (0 <= num < cffi_opcode._NUM_PRIM):
        if num == cffi_opcode._UNKNOWN_PRIM:
            raise oefmt(ffi.w_FFIError, "primitive integer type with an "
                        "unexpected size (or not an integer type at all)")
        else:
            raise oefmt(space.w_NotImplementedError, "prim=%d", num)
    realize_cache = space.fromcache(RealizeCache)
    w_ctype = realize_cache.all_primitives[num]
    if w_ctype is None:
        if num == cffi_opcode.PRIM_VOID:
            w_ctype = newtype.new_void_type(space)
        else:
            assert RealizeCache.NAMES[num]
            w_ctype = newtype.new_primitive_type(space, RealizeCache.NAMES[num])
        realize_cache.all_primitives[num] = w_ctype
    return w_ctype
Example #4
0
    def __init__(self, space):
        self.library = None
        self.capi_calls = {}

        import pypy.module._cffi_backend.newtype as nt

        # TODO: the following need to match up with the globally defined C_XYZ low-level
        # types (see capi/__init__.py), but by using strings here, that isn't guaranteed
        c_opaque_ptr = nt.new_primitive_type(space, 'unsigned long')
 
        c_scope  = c_opaque_ptr
        c_type   = c_scope
        c_object = c_opaque_ptr
        c_method = c_opaque_ptr
        c_index  = nt.new_primitive_type(space, 'long')

        c_void   = nt.new_void_type(space)
        c_char   = nt.new_primitive_type(space, 'char')
        c_uchar  = nt.new_primitive_type(space, 'unsigned char')
        c_short  = nt.new_primitive_type(space, 'short')
        c_int    = nt.new_primitive_type(space, 'int')
        c_long   = nt.new_primitive_type(space, 'long')
        c_llong  = nt.new_primitive_type(space, 'long long')
        c_ullong = nt.new_primitive_type(space, 'unsigned long long')
        c_float  = nt.new_primitive_type(space, 'float')
        c_double = nt.new_primitive_type(space, 'double')

        c_ccharp = nt.new_pointer_type(space, c_char)
        c_index_array = nt.new_pointer_type(space, c_void)

        c_voidp  = nt.new_pointer_type(space, c_void)
        c_size_t = nt.new_primitive_type(space, 'size_t')

        c_ptrdiff_t = nt.new_primitive_type(space, 'ptrdiff_t')

        self.capi_call_ifaces = {
            # name to opaque C++ scope representation
            'num_scopes'               : ([c_scope],                  c_int),
            'scope_name'               : ([c_scope, c_int],           c_ccharp),

            'resolve_name'             : ([c_ccharp],                 c_ccharp),
            'get_scope'                : ([c_ccharp],                 c_scope),
            'get_template'             : ([c_ccharp],                 c_type),
            'actual_class'             : ([c_type, c_object],         c_type),

            # memory management
            'allocate'                 : ([c_type],                   c_object),
            'deallocate'               : ([c_type, c_object],         c_void),
            'destruct'                 : ([c_type, c_object],         c_void),

            # method/function dispatching
            'call_v'       : ([c_method, c_object, c_int, c_voidp],   c_void),
            'call_b'       : ([c_method, c_object, c_int, c_voidp],   c_uchar),
            'call_c'       : ([c_method, c_object, c_int, c_voidp],   c_char),

            'call_h'       : ([c_method, c_object, c_int, c_voidp],   c_short),
            'call_i'       : ([c_method, c_object, c_int, c_voidp],   c_int),
            'call_l'       : ([c_method, c_object, c_int, c_voidp],   c_long),
            'call_ll'      : ([c_method, c_object, c_int, c_voidp],   c_llong),
            'call_f'       : ([c_method, c_object, c_int, c_voidp],   c_float),
            'call_d'       : ([c_method, c_object, c_int, c_voidp],   c_double),

            'call_r'       : ([c_method, c_object, c_int, c_voidp],   c_voidp),
            'call_s'       : ([c_method, c_object, c_int, c_voidp],   c_ccharp),

            'constructor'  : ([c_method, c_object, c_int, c_voidp],   c_object),
            'call_o'       : ([c_method, c_object, c_int, c_voidp, c_type],     c_object),

            'get_methptr_getter'       : ([c_scope, c_index],         c_voidp), # TODO: verify

            # handling of function argument buffer
            'allocate_function_args'   : ([c_int],                    c_voidp),
            'deallocate_function_args' : ([c_voidp],                  c_void),
            'function_arg_sizeof'      : ([],                         c_size_t),
            'function_arg_typeoffset'  : ([],                         c_size_t),

            # scope reflection information
            'is_namespace'             : ([c_scope],                  c_int),
            'is_enum'                  : ([c_ccharp],                 c_int),

            # type/class reflection information
            'final_name'               : ([c_type],                   c_ccharp),
            'scoped_final_name'        : ([c_type],                   c_ccharp),
            'has_complex_hierarchy'    : ([c_type],                   c_int),
            'num_bases'                : ([c_type],                   c_int),
            'base_name'                : ([c_type, c_int],            c_ccharp),
            'is_subtype'               : ([c_type, c_type],           c_int),

            'base_offset'              : ([c_type, c_type, c_object, c_int],    c_ptrdiff_t),

            # method/function reflection information
            'num_methods'              : ([c_scope],                  c_int),
            'method_index_at'          : ([c_scope, c_int],           c_index),
            'method_indices_from_name' : ([c_scope, c_ccharp],        c_index_array),

            'method_name'              : ([c_scope, c_index],         c_ccharp),
            'method_result_type'       : ([c_scope, c_index],         c_ccharp),
            'method_num_args'          : ([c_scope, c_index],         c_int),
            'method_req_args'          : ([c_scope, c_index],         c_int),
            'method_arg_type'          : ([c_scope, c_index, c_int],  c_ccharp),
            'method_arg_default'       : ([c_scope, c_index, c_int],  c_ccharp),
            'method_signature'         : ([c_scope, c_index],         c_ccharp),

            'method_is_template'       : ([c_scope, c_index],         c_int),
            'method_num_template_args' : ([c_scope, c_index],         c_int),
            'method_template_arg_name' : ([c_scope, c_index, c_index],          c_ccharp),

            'get_method'               : ([c_scope, c_index],         c_method),
            'get_global_operator'      : ([c_scope, c_scope, c_scope, c_ccharp],   c_index),

            # method properties
            'is_constructor'           : ([c_type, c_index],          c_int),
            'is_staticmethod'          : ([c_type, c_index],          c_int),

            # data member reflection information
            'num_datamembers'          : ([c_scope],                  c_int),
            'datamember_name'          : ([c_scope, c_int],           c_ccharp),
            'datamember_type'          : ([c_scope, c_int],           c_ccharp),
            'datamember_offset'        : ([c_scope, c_int],           c_ptrdiff_t),

            'datamember_index'         : ([c_scope, c_ccharp],        c_int),

            # data member properties
            'is_publicdata'            : ([c_scope, c_int],           c_int),
            'is_staticdata'            : ([c_scope, c_int],           c_int),

            # misc helpers
            'strtoll'                  : ([c_ccharp],                 c_llong),
            'strtoull'                 : ([c_ccharp],                 c_ullong),
            'free'                     : ([c_voidp],                  c_void),

            'charp2stdstring'          : ([c_ccharp],                 c_object),
            'stdstring2stdstring'      : ([c_object],                 c_object),
        }

        # size/offset are backend-specific but fixed after load
        self.c_sizeof_farg = 0
        self.c_offset_farg = 0
Example #5
0
    def __init__(self, space):
        self.library = None
        self.capi_calls = {}

        import pypy.module._cffi_backend.newtype as nt

        # TODO: the following need to match up with the globally defined C_XYZ low-level
        # types (see capi/__init__.py), but by using strings here, that isn't guaranteed
        c_opaque_ptr = nt.new_primitive_type(space, 'unsigned long')

        c_scope = c_opaque_ptr
        c_type = c_scope
        c_object = c_opaque_ptr
        c_method = c_opaque_ptr
        c_index = nt.new_primitive_type(space, 'long')

        c_void = nt.new_void_type(space)
        c_char = nt.new_primitive_type(space, 'char')
        c_uchar = nt.new_primitive_type(space, 'unsigned char')
        c_short = nt.new_primitive_type(space, 'short')
        c_int = nt.new_primitive_type(space, 'int')
        c_long = nt.new_primitive_type(space, 'long')
        c_llong = nt.new_primitive_type(space, 'long long')
        c_ullong = nt.new_primitive_type(space, 'unsigned long long')
        c_float = nt.new_primitive_type(space, 'float')
        c_double = nt.new_primitive_type(space, 'double')

        c_ccharp = nt.new_pointer_type(space, c_char)
        c_index_array = nt.new_pointer_type(space, c_void)

        c_voidp = nt.new_pointer_type(space, c_void)
        c_size_t = nt.new_primitive_type(space, 'size_t')

        c_ptrdiff_t = nt.new_primitive_type(space, 'ptrdiff_t')

        self.capi_call_ifaces = {
            # name to opaque C++ scope representation
            'num_scopes': ([c_scope], c_int),
            'scope_name': ([c_scope, c_int], c_ccharp),
            'resolve_name': ([c_ccharp], c_ccharp),
            'get_scope': ([c_ccharp], c_scope),
            'get_template': ([c_ccharp], c_type),
            'actual_class': ([c_type, c_object], c_type),

            # memory management
            'allocate': ([c_type], c_object),
            'deallocate': ([c_type, c_object], c_void),
            'destruct': ([c_type, c_object], c_void),

            # method/function dispatching
            'call_v': ([c_method, c_object, c_int, c_voidp], c_void),
            'call_b': ([c_method, c_object, c_int, c_voidp], c_uchar),
            'call_c': ([c_method, c_object, c_int, c_voidp], c_char),
            'call_h': ([c_method, c_object, c_int, c_voidp], c_short),
            'call_i': ([c_method, c_object, c_int, c_voidp], c_int),
            'call_l': ([c_method, c_object, c_int, c_voidp], c_long),
            'call_ll': ([c_method, c_object, c_int, c_voidp], c_llong),
            'call_f': ([c_method, c_object, c_int, c_voidp], c_float),
            'call_d': ([c_method, c_object, c_int, c_voidp], c_double),
            'call_r': ([c_method, c_object, c_int, c_voidp], c_voidp),
            'call_s': ([c_method, c_object, c_int, c_voidp], c_ccharp),
            'constructor': ([c_method, c_object, c_int, c_voidp], c_object),
            'call_o': ([c_method, c_object, c_int, c_voidp, c_type], c_object),
            'get_methptr_getter': ([c_scope,
                                    c_index], c_voidp),  # TODO: verify

            # handling of function argument buffer
            'allocate_function_args': ([c_int], c_voidp),
            'deallocate_function_args': ([c_voidp], c_void),
            'function_arg_sizeof': ([], c_size_t),
            'function_arg_typeoffset': ([], c_size_t),

            # scope reflection information
            'is_namespace': ([c_scope], c_int),
            'is_enum': ([c_ccharp], c_int),

            # type/class reflection information
            'final_name': ([c_type], c_ccharp),
            'scoped_final_name': ([c_type], c_ccharp),
            'has_complex_hierarchy': ([c_type], c_int),
            'num_bases': ([c_type], c_int),
            'base_name': ([c_type, c_int], c_ccharp),
            'is_subtype': ([c_type, c_type], c_int),
            'base_offset': ([c_type, c_type, c_object, c_int], c_ptrdiff_t),

            # method/function reflection information
            'num_methods': ([c_scope], c_int),
            'method_index_at': ([c_scope, c_int], c_index),
            'method_indices_from_name': ([c_scope, c_ccharp], c_index_array),
            'method_name': ([c_scope, c_index], c_ccharp),
            'method_result_type': ([c_scope, c_index], c_ccharp),
            'method_num_args': ([c_scope, c_index], c_int),
            'method_req_args': ([c_scope, c_index], c_int),
            'method_arg_type': ([c_scope, c_index, c_int], c_ccharp),
            'method_arg_default': ([c_scope, c_index, c_int], c_ccharp),
            'method_signature': ([c_scope, c_index], c_ccharp),
            'method_is_template': ([c_scope, c_index], c_int),
            'method_num_template_args': ([c_scope, c_index], c_int),
            'method_template_arg_name': ([c_scope, c_index,
                                          c_index], c_ccharp),
            'get_method': ([c_scope, c_index], c_method),
            'get_global_operator': ([c_scope, c_scope, c_scope,
                                     c_ccharp], c_index),

            # method properties
            'is_constructor': ([c_type, c_index], c_int),
            'is_staticmethod': ([c_type, c_index], c_int),

            # data member reflection information
            'num_datamembers': ([c_scope], c_int),
            'datamember_name': ([c_scope, c_int], c_ccharp),
            'datamember_type': ([c_scope, c_int], c_ccharp),
            'datamember_offset': ([c_scope, c_int], c_ptrdiff_t),
            'datamember_index': ([c_scope, c_ccharp], c_int),

            # data member properties
            'is_publicdata': ([c_scope, c_int], c_int),
            'is_staticdata': ([c_scope, c_int], c_int),

            # misc helpers
            'strtoll': ([c_ccharp], c_llong),
            'strtoull': ([c_ccharp], c_ullong),
            'free': ([c_voidp], c_void),
            'charp2stdstring': ([c_ccharp], c_object),
            'stdstring2stdstring': ([c_object], c_object),
        }

        # size/offset are backend-specific but fixed after load
        self.c_sizeof_farg = 0
        self.c_offset_farg = 0