static void init_builtin_type(struct cp_ctype *ct, ffi_type ftype) { csymbol cs; int cs_id; csym_type(&cs) = ftype; strncpy(csym_name(&cs), ffi_type_name(ftype), CSYM_NAME_MAX_LEN); cs_id = cp_ctype_reg_csymbol(&cs); memset(ct, 0, sizeof(*ct)); ct->ffi_cs_id = cs_id; switch (ftype) { case FFI_VOID: ct_set_type(ct, VOID_TYPE, 0); break; case FFI_UINT8: ct_set_type(ct, INT8_TYPE, 1); break; case FFI_INT8: ct_set_type(ct, INT8_TYPE, 0); break; case FFI_UINT16: ct_set_type(ct, INT16_TYPE, 1); break; case FFI_INT16: ct_set_type(ct, INT16_TYPE, 0); break; case FFI_UINT32: ct_set_type(ct, INT32_TYPE, 1); break; case FFI_INT32: ct_set_type(ct, INT32_TYPE, 0); break; case FFI_UINT64: ct_set_type(ct, INT64_TYPE, 1); break; case FFI_INT64: ct_set_type(ct, INT64_TYPE, 0); break; default: break; } ct->base_size = ffi_type_size(ftype); ct->align_mask = ffi_type_align(ftype) - 1; ct->is_defined = 1; }
/* * Returns a void pointer to the data the cell holds, * whose data type must be compatible with `type`. */ static void* make_arg(ffi_type *type, cons_t* val) { if ( type == &ffi_type_uint || type == &ffi_type_sint ) { if ( !integerp(val) ) raise(runtime_exception("Argument must be an integer")); return static_cast<void*>(&val->number.integer); } if ( type == &ffi_type_pointer ) { if ( stringp(val) ) return static_cast<void*>(&val->string); if ( pointerp(val) ) return &val->pointer->value; if ( integerp(val) ) return &val->number.integer; if ( realp(val) ) return &val->number.real; raise(runtime_exception(format( "Unsupported pointer type %s", to_s(type_of(val)).c_str()))); } const std::string expect = ffi_type_name(type), given = to_s(type_of(val)); raise(runtime_exception(format( "Foreign function wants %s but input data was %s, " "which we don't know how to convert.", indef_art("'"+expect+"'").c_str(), indef_art("'"+given+"'").c_str()))); return NULL; }
void ktapc_dump_csymbol_id(char *prefix, int id) { csymbol *cs, *cs_arr; cs_arr = ctype_get_csym_state()->cs_arr; cs = &cs_arr[id]; if (prefix != NULL) printf("%s: ", prefix); printf("%s (id: %d; ffi_type: %s)\n", cs->name, id, ffi_type_name(cs->type)); }
static int ffi_set_return(ktap_state_t *ks, void *rvalue, csymbol_id ret_id) { ktap_cdata_t *cd; ffi_type type = csym_type(id_to_csym(ks, ret_id)); /* push return value to ktap stack */ switch (type) { case FFI_VOID: return 0; case FFI_UINT8: case FFI_INT8: case FFI_UINT16: case FFI_INT16: case FFI_UINT32: case FFI_INT32: case FFI_UINT64: case FFI_INT64: set_number(ks->top, (ktap_number)rvalue); break; case FFI_PTR: cd = kp_cdata_new_ptr(ks, rvalue, -1, ret_id, 0); set_cdata(ks->top, cd); break; case FFI_STRUCT: case FFI_UNION: cd = kp_cdata_new_record(ks, rvalue, ret_id); set_cdata(ks->top, cd); break; case FFI_FUNC: case FFI_UNKNOWN: kp_error(ks, "Error: Have not support ffi_type %s\n", ffi_type_name(type)); return 0; } incr_top(ks); return 1; }