void kp_cdata_record_get(ktap_state_t *ks, ktap_cdata_t *cd, ktap_val_t *key, ktap_val_t *val) { const char *mb_name; csymbol *cs, *mb_cs; csymbol_struct *csst; struct_member *mb; char *addr; csymbol_id mb_cs_id; if (!is_shrstring(key)) { kp_error(ks, "struct member name should be string\n"); return; } mb_name = svalue(key); cs = cd_csym(ks, cd); csst = csym_struct(cs); mb = csymst_mb_by_name(ks, csst, mb_name); if (mb == NULL) { kp_error(ks, "struct member %s doesn't exist\n", mb_name); return; } mb_cs_id = mb->id; mb_cs = id_to_csym(ks, mb_cs_id); addr = cd_record(cd); addr += csym_record_mb_offset_by_name(ks, cs, mb_name); kp_cdata_init(ks, val, addr, mb->len, mb_cs_id); if (mb->len < 0) kp_cdata_pack(ks, val, addr, mb_cs); }
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; } }
void kp_cdata_ptr_get(ktap_state_t *ks, ktap_cdata_t *cd, ktap_val_t *key, ktap_val_t *val) { ktap_number idx; csymbol *cs; size_t size; char *addr; csymbol_id cs_id; if (!is_number(key)) { kp_error(ks, "array index should be number\n"); return; } idx = nvalue(key); if (unlikely(idx < 0 || (cd_ptr_nmemb(cd) >= 0 && idx >= cd_ptr_nmemb(cd)))) { kp_error(ks, "array index out of bound\n"); return; } cs_id = csym_ptr_deref_id(cd_csym(ks, cd)); cs = id_to_csym(ks, cs_id); size = csym_size(ks, cs); addr = cd_ptr(cd); addr += size * idx; kp_cdata_init(ks, val, addr, -1, cs_id); kp_cdata_pack(ks, val, addr, cs); }
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; }
void kp_cdata_record_set(ktap_state *ks, ktap_cdata *cd, ktap_value *key, ktap_value *val) { const char *mb_name; csymbol *cs, *mb_cs; csymbol_struct *csst; struct_member *mb; char *addr; if (!is_shrstring(key)) { kp_error(ks, "struct member name should be string\n"); return; } mb_name = svalue(key); cs = cd_csym(ks, cd); csst = csym_struct(cs); mb = csymst_mb_by_name(ks, csst, mb_name); if (mb == NULL) { kp_error(ks, "struct member %s doesn't exist\n", mb_name); return; } mb_cs = id_to_csym(ks, mb->id); if (kp_cdata_type_match(ks, mb_cs, val)) { kp_error(ks, "struct member should be %s type\n", csym_name(mb_cs)); return; } addr = cd_struct(cd); addr += csym_record_mb_offset_by_name(ks, cs, mb_name); kp_cdata_unpack(ks, addr, mb_cs, val); }
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; }
/* argument nmemb here indicates the length of array that is pointed to, * -1 for unknown */ ktap_cdata_t *kp_cdata_new_ptr(ktap_state_t *ks, void *addr, int nmemb, csymbol_id id, int to_allocate) { ktap_cdata_t *cd; size_t memb_size; csymbol_id deref_id; cd = kp_cdata_new(ks, id); if (to_allocate) { /* allocate new empty space */ deref_id = csym_ptr_deref_id(id_to_csym(ks, id)); memb_size = csym_size(ks, id_to_csym(ks, deref_id)); cd_ptr(cd) = kp_rawobj_alloc(ks, memb_size * nmemb); } else { cd_ptr(cd) = addr; } cd_ptr_nmemb(cd) = nmemb; return cd; }
ktap_cdata_t *kp_cdata_new_record(ktap_state_t *ks, void *val, csymbol_id id) { ktap_cdata_t *cd; size_t size; cd = kp_cdata_new(ks, id); /* if val == NULL, allocate new empty space */ if (val == NULL) { size = csym_size(ks, id_to_csym(ks, id)); cd_record(cd) = kp_rawobj_alloc(ks, size); } else cd_record(cd) = val; return cd; }
static csymbol *ffi_get_arg_csym(ktap_state_t *ks, csymbol_func *csf, int idx) { StkId arg; csymbol *cs; if (idx < csymf_arg_nr(csf)) return csymf_arg(ks, csf, idx); arg = kp_arg(ks, idx + 1); cs = id_to_csym(ks, ffi_get_csym_id(ks, "void *")); switch (ttypenv(arg)) { case KTAP_TYPE_LIGHTUSERDATA: case KTAP_TYPE_BOOLEAN: case KTAP_TYPE_NUMBER: case KTAP_TYPE_STRING: return cs; case KTAP_TYPE_CDATA: return cd_csym(ks, cdvalue(arg)); default: kp_error(ks, "Error: Cannot get type for arg %d\n", idx); return cs; } }
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; }