ktap_cdata_t *kp_cdata_new_by_id(ktap_state_t *ks, void *val, csymbol_id id) { csymbol *cs = id_to_csym(ks, id); switch (csym_type(cs)) { case FFI_VOID: kp_error(ks, "Error: Cannot new a void type\n"); return NULL; case FFI_UINT8: case FFI_INT8: case FFI_UINT16: case FFI_INT16: case FFI_UINT32: case FFI_INT32: case FFI_UINT64: case FFI_INT64: return kp_cdata_new_number(ks, val, id); case FFI_PTR: return kp_cdata_new_ptr(ks, val, 0, id, 0); case FFI_STRUCT: case FFI_UNION: return kp_cdata_new_record(ks, val, id); case FFI_FUNC: kp_error(ks, "Error: Cannot new a function type\n"); return NULL; case FFI_UNKNOWN: default: kp_error(ks, "Error: unknown csymbol type %s\n", csym_name(cs)); return NULL; } }
/* Init its cdata type, but not its actual value */ static void kp_cdata_init(ktap_state_t *ks, ktap_val_t *val, void *addr, int len, csymbol_id id) { ffi_type type = csym_type(id_to_csym(ks, id)); switch (type) { case FFI_PTR: set_cdata(val, kp_cdata_new_ptr(ks, addr, len, id, 0)); break; case FFI_STRUCT: case FFI_UNION: set_cdata(val, kp_cdata_new_record(ks, addr, id)); break; 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 all these value into ktap_number(long) */ set_number(val, 0); break; default: set_cdata(val, kp_cdata_new(ks, id)); break; } }
static int kplib_ffi_new(ktap_state *ks) { int n = kp_arg_nr(ks), array_size; csymbol_id cs_id; ktap_cdata *cd; if (unlikely(n != 2)) { /* this is not likely to happen since ffi.new arguments are * generated by compiler */ set_nil(ks->top++); kp_error(ks, "wrong number of arguments\n"); return 1; } kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); kp_arg_check(ks, 2, KTAP_TYPE_NUMBER); cs_id = nvalue(kp_arg(ks, 1)); array_size = nvalue(kp_arg(ks, 2)); if (unlikely(cs_id > max_csym_id(ks))) kp_error(ks, "invalid csymbol id\n"); kp_verbose_printf(ks, "ffi.new symbol %s with length %d\n", id_to_csym(ks, cs_id)->name, array_size); cd = kp_cdata_new_ptr(ks, NULL, array_size, cs_id, 1); set_cdata(ks->top, cd); incr_top(ks); return 1; }
static int kplib_ffi_new(ktap_state_t *ks) { int n = kp_arg_nr(ks); csymbol_id cs_id = kp_arg_checknumber(ks, 1); int array_size = kp_arg_checknumber(ks, 2); int is_array = kp_arg_checknumber(ks, 3); ktap_cdata_t *cd; if (unlikely(n != 3)) { /* this is not likely to happen since ffi.new arguments are * generated by compiler */ set_nil(ks->top++); kp_error(ks, "wrong number of arguments\n"); return 1; } if (unlikely(cs_id > max_csym_id(ks))) kp_error(ks, "invalid csymbol id\n"); kp_verbose_printf(ks, "ffi.new symbol %s with length %d\n", id_to_csym(ks, cs_id)->name, array_size); if (is_array) cd = kp_cdata_new_ptr(ks, NULL, array_size, cs_id, 1); else cd = kp_cdata_new_by_id(ks, NULL, cs_id); set_cdata(ks->top, cd); incr_top(ks); return 1; }
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; }