예제 #1
0
파일: cdata.c 프로젝트: ktap/ktap
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);
}
예제 #2
0
파일: cdata.c 프로젝트: ktap/ktap
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;
	}
}
예제 #3
0
파일: cdata.c 프로젝트: ktap/ktap
/* 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;
	}
}
예제 #4
0
파일: cdata.c 프로젝트: ktap/ktap
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);
}
예제 #5
0
파일: lib_ffi.c 프로젝트: lianghu/ktap
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;
}
예제 #6
0
파일: cdata.c 프로젝트: WinLinKer/ktap
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);
}
예제 #7
0
파일: lib_ffi.c 프로젝트: ktap/ktap
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;
}
예제 #8
0
파일: cdata.c 프로젝트: ktap/ktap
/* 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;
}
예제 #9
0
파일: cdata.c 프로젝트: ktap/ktap
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;
}
예제 #10
0
파일: ffi_call.c 프로젝트: awreece/ktap
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;
	}
}
예제 #11
0
파일: ffi_call.c 프로젝트: awreece/ktap
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;
}