浏览代码

added int64 dynamic and reflect support

Nicolas Cannasse 3 年之前
父节点
当前提交
9cadbe5aac
共有 5 个文件被更改,包括 161 次插入2 次删除
  1. 3 0
      src/hl.h
  2. 14 0
      src/jit.c
  3. 61 0
      src/std/cast.c
  4. 13 2
      src/std/fun.c
  5. 70 0
      src/std/obj.c

+ 3 - 0
src/hl.h

@@ -616,11 +616,13 @@ HL_API hl_field_lookup *hl_lookup_find( hl_field_lookup *l, int size, int hash )
 HL_API hl_field_lookup *hl_lookup_insert( hl_field_lookup *l, int size, int hash, hl_type *t, int index );
 
 HL_API int hl_dyn_geti( vdynamic *d, int hfield, hl_type *t );
+HL_API int64 hl_dyn_geti64( vdynamic *d, int hfield );
 HL_API void *hl_dyn_getp( vdynamic *d, int hfield, hl_type *t );
 HL_API float hl_dyn_getf( vdynamic *d, int hfield );
 HL_API double hl_dyn_getd( vdynamic *d, int hfield );
 
 HL_API int hl_dyn_casti( void *data, hl_type *t, hl_type *to );
+HL_API int64 hl_dyn_casti64( void *data, hl_type *t );
 HL_API void *hl_dyn_castp( void *data, hl_type *t, hl_type *to );
 HL_API float hl_dyn_castf( void *data, hl_type *t );
 HL_API double hl_dyn_castd( void *data, hl_type *t );
@@ -631,6 +633,7 @@ HL_API vdynamic *hl_make_dyn( void *data, hl_type *t );
 HL_API void hl_write_dyn( void *data, hl_type *t, vdynamic *v, bool is_tmp );
 
 HL_API void hl_dyn_seti( vdynamic *d, int hfield, hl_type *t, int value );
+HL_API void hl_dyn_seti64( vdynamic *d, int hfield, int64 value );
 HL_API void hl_dyn_setp( vdynamic *d, int hfield, hl_type *t, void *ptr );
 HL_API void hl_dyn_setf( vdynamic *d, int hfield, float f );
 HL_API void hl_dyn_setd( vdynamic *d, int hfield, double v );

+ 14 - 0
src/jit.c

@@ -858,6 +858,7 @@ static int stack_size( hl_type *t ) {
 	case HF32:
 #	endif
 		return sizeof(int_val);
+	case HI64:
 	default:
 		return hl_type_size(t);
 	}
@@ -1990,6 +1991,7 @@ static void dyn_value_compare( jit_ctx *ctx, preg *a, preg *b, hl_type *t ) {
 			op64(ctx,COMISD,fa,fb);
 		}
 		break;
+	case HI64:
 	default:
 		// ptr comparison
 		op64(ctx,MOV,a,pmem(&p,a->id,HDYN_VALUE));
@@ -2374,6 +2376,9 @@ static void *callback_c2hl( void **f, hl_type *t, void **args, vdynamic *ret ) {
 	case HBOOL:
 		ret->v.i = ((int (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 		return &ret->v.i;
+	case HI64:
+		ret->v.i64 = ((int64 (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
+		return &ret->v.i64;
 	case HF32:
 		ret->v.f = ((float (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 		return &ret->v.f;
@@ -2488,6 +2493,8 @@ static void *jit_wrapper_ptr( vclosure_wrapper *c, char *stack_args, void **regs
 	case HI32:
 	case HBOOL:
 		return (void*)(int_val)hl_dyn_casti(&ret,&hlt_dyn,tret);
+	case HI64:
+		return (void*)hl_dyn_casti64(&ret,&hlt_dyn);
 	default:
 		return hl_dyn_castp(&ret,&hlt_dyn,tret);
 	}
@@ -2694,6 +2701,8 @@ static void *get_dyncast( hl_type *t ) {
 		return hl_dyn_castf;
 	case HF64:
 		return hl_dyn_castd;
+	case HI64:
+		return hl_dyn_casti64;
 	case HI32:
 	case HUI16:
 	case HUI8:
@@ -2710,6 +2719,8 @@ static void *get_dynset( hl_type *t ) {
 		return hl_dyn_setf;
 	case HF64:
 		return hl_dyn_setd;
+	case HI64:
+		return hl_dyn_seti64;
 	case HI32:
 	case HUI16:
 	case HUI8:
@@ -2726,6 +2737,8 @@ static void *get_dynget( hl_type *t ) {
 		return hl_dyn_getf;
 	case HF64:
 		return hl_dyn_getd;
+	case HI64:
+		return hl_dyn_geti64;
 	case HI32:
 	case HUI16:
 	case HUI8:
@@ -2802,6 +2815,7 @@ static void make_dyn_cast( jit_ctx *ctx, vreg *dst, vreg *v ) {
 	switch( dst->t->kind ) {
 	case HF32:
 	case HF64:
+	case HI64:
 		size = begin_native_call(ctx, 2);
 		set_native_arg(ctx, pconst64(&p,(int_val)v->t));
 		break;

+ 61 - 0
src/std/cast.c

@@ -46,6 +46,11 @@ HL_PRIM vdynamic *hl_make_dyn( void *data, hl_type *t ) {
 		v->t = t;
 		v->v.i = *(int*)data;
 		return v;
+	case HI64:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.i64 = *(int64*)data;
+		return v;
 	case HF32:
 		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
 		v->t = t;
@@ -90,6 +95,8 @@ HL_PRIM int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
 		return *(unsigned short*)data;
 	case HI32:
 		return *(int*)data;
+	case HI64:
+		return (int)*(int64*)data;
 	case HF32:
 		return (int)*(float*)data;
 	case HF64:
@@ -109,6 +116,42 @@ HL_PRIM int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
 	return 0;
 }
 
+HL_PRIM int64 hl_dyn_casti64( void *data, hl_type *t ) {
+	hl_track_call(HL_TRACK_CAST, on_cast(t,&hlt_i64));
+	if( t->kind == HDYN ) {
+		vdynamic *v = *((vdynamic**)data);
+		if( v == NULL ) return 0;
+		t = v->t;
+		if( !hl_is_dynamic(t) ) data = &v->v;
+	}
+	switch( t->kind ) {
+	case HUI8:
+		return *(unsigned char*)data;
+	case HUI16:
+		return *(unsigned short*)data;
+	case HI32:
+		return *(int*)data;
+	case HI64:
+		return *(int64*)data;
+	case HF32:
+		return (int64)*(float*)data;
+	case HF64:
+		return (int64)*(double*)data;
+	case HBOOL:
+		return *(bool*)data;
+	case HNULL:
+		{
+			vdynamic *v = *(vdynamic**)data;
+			if( v == NULL ) return 0;
+			return hl_dyn_casti64(&v->v,t->tparam);
+		}
+	default:
+		break;
+	}
+	invalid_cast(t,&hlt_i64);
+	return 0;
+}
+
 HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
 	hl_track_call(HL_TRACK_CAST, on_cast(t,to));
 	if( to->kind == HDYN && hl_is_dynamic(t) )
@@ -187,6 +230,11 @@ HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
 				int v = hl_dyn_casti(data,t,to->tparam);
 				return hl_make_dyn(&v,to->tparam);
 			}
+		case HI64:
+			{
+				int64 v = hl_dyn_casti64(data,t);
+				return hl_make_dyn(&v,to->tparam);
+			}
 		case HF32:
 			{
 				float f = hl_dyn_castf(data,t);
@@ -212,6 +260,12 @@ HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
 				*v = hl_dyn_casti(data,t,to->tparam);
 				return v;
 			}
+		case HI64:
+			{
+				int64 *d = (int64*)hl_gc_alloc_noptr(sizeof(int64));
+				*d = hl_dyn_casti64(data,t);
+				return d;
+			}
 		case HF32:
 			{
 				float *f = (float*)hl_gc_alloc_noptr(sizeof(float));
@@ -256,6 +310,8 @@ HL_PRIM double hl_dyn_castd( void *data, hl_type *t ) {
 		return *(unsigned short*)data;
 	case HI32:
 		return *(int*)data;
+	case HI64:
+		return (double)*(int64*)data;
 	case HBOOL:
 		return *(bool*)data;
 	case HNULL:
@@ -290,6 +346,8 @@ HL_PRIM float hl_dyn_castf( void *data, hl_type *t ) {
 		return *(unsigned short*)data;
 	case HI32:
 		return (float)*(int*)data;
+	case HI64:
+		return (float)*(int64*)data;
 	case HBOOL:
 		return *(bool*)data;
 	case HNULL:
@@ -409,6 +467,9 @@ HL_PRIM void hl_write_dyn( void *data, hl_type *t, vdynamic *v, bool is_tmp ) {
 	case HI32:
 		*(int*)data = hl_dyn_casti(&v,&hlt_dyn,t);
 		break;
+	case HI64:
+		*(int64*)data = hl_dyn_casti64(&v,&hlt_dyn);
+		break;
 	case HF32:
 		*(float*)data = hl_dyn_castf(&v,&hlt_dyn);
 		break;

+ 13 - 2
src/std/fun.c

@@ -141,7 +141,7 @@ HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 	vdynamic **vargs = hl_aptr(args,vdynamic*);
 	void *pargs[HL_MAX_ARGS];
 	void *ret;
-	union { double d; int i; float f; } tmp[HL_MAX_ARGS];
+	union { double d; int i; float f; int64 i64; } tmp[HL_MAX_ARGS];
 	hl_type *tret;
 	vdynamic *dret;
 	vdynamic out;
@@ -176,6 +176,10 @@ HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 			tmp[i].i = hl_dyn_casti(vargs + i, &hlt_dyn,t);
 			p = &tmp[i].i;
 			break;
+		case HI64:
+			tmp[i].i64 = hl_dyn_casti64(vargs + i, &hlt_dyn);
+			p = &tmp[i].i64;
+			break;
 		case HF32:
 			tmp[i].f = hl_dyn_castf(vargs + i, &hlt_dyn);
 			p = &tmp[i].f;
@@ -243,7 +247,7 @@ HL_PRIM vdynamic *hl_dyn_call( vclosure *c, vdynamic **args, int nargs ) {
 HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) {
 	vclosure_wrapper *c = (vclosure_wrapper*)_c;
 	hl_type_fun *tfun = c->cl.t->fun;
-	union { double d; int i; float f; } tmp[HL_MAX_ARGS];
+	union { double d; int i; float f; int64 i64; } tmp[HL_MAX_ARGS];
 	void *vargs[HL_MAX_ARGS+1];
 	vdynamic out;
 	vclosure *w = c->wrappedFun;
@@ -279,6 +283,10 @@ HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) {
 				tmp[i].i = hl_dyn_casti(v,t,to);
 				v = &tmp[i].i;
 				break;
+			case HI64:
+				tmp[i].i64 = hl_dyn_casti64(v,t);
+				v = &tmp[i].i64;
+				break;
 			case HF32:
 				tmp[i].f = hl_dyn_castf(v,t);
 				v = &tmp[i].f;
@@ -306,6 +314,9 @@ HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) {
 	case HBOOL:
 		ret->v.i = hl_dyn_casti(aret,w->t->fun->ret,tfun->ret);
 		break;
+	case HI64:
+		ret->v.i64 = hl_dyn_casti64(aret,w->t->fun->ret);
+		break;
 	case HF32:
 		ret->v.f = hl_dyn_castf(aret,w->t->fun->ret);
 		break;

+ 70 - 0
src/std/obj.c

@@ -862,6 +862,8 @@ HL_PRIM int hl_dyn_geti( vdynamic *d, int hfield, hl_type *t ) {
 		return *(unsigned short*)addr;
 	case HI32:
 		return *(int*)addr;
+	case HI64:
+		return (int)*(int64*)addr;
 	case HF32:
 		return (int)*(float*)addr;
 	case HF64:
@@ -873,6 +875,34 @@ HL_PRIM int hl_dyn_geti( vdynamic *d, int hfield, hl_type *t ) {
 	}
 }
 
+HL_PRIM int64 hl_dyn_geti64( vdynamic *d, int hfield ) {
+	hl_type *ft;
+	hl_track_call(HL_TRACK_DYNFIELD, on_dynfield(d,hfield));
+	void *addr = hl_obj_lookup(d,hfield,&ft);
+	if( !addr ) {
+		d = hl_obj_lookup_extra(d,hfield);
+		return d == NULL ? 0 : hl_dyn_casti64(&d,&hlt_dyn);
+	}
+	switch( ft->kind ) {
+	case HUI8:
+		return *(unsigned char*)addr;
+	case HUI16:
+		return *(unsigned short*)addr;
+	case HI32:
+		return *(int*)addr;
+	case HI64:
+		return *(int64*)addr;
+	case HF32:
+		return (int64)*(float*)addr;
+	case HF64:
+		return (int64)*(double*)addr;
+	case HBOOL:
+		return *(bool*)addr;
+	default:
+		return hl_dyn_casti64(addr,ft);
+	}
+}
+
 HL_PRIM float hl_dyn_getf( vdynamic *d, int hfield ) {
 	hl_type *ft;
 	hl_track_call(HL_TRACK_DYNFIELD, on_dynfield(d,hfield));
@@ -977,6 +1007,9 @@ HL_PRIM void hl_dyn_seti( vdynamic *d, int hfield, hl_type *t, int value ) {
 	case HI32:
 		*(int*)addr = value;
 		break;
+	case HI64:
+		*(int64*)addr = value;
+		break;
 	case HBOOL:
 		*(bool*)addr = value != 0;
 		break;
@@ -997,6 +1030,43 @@ HL_PRIM void hl_dyn_seti( vdynamic *d, int hfield, hl_type *t, int value ) {
 	}
 }
 
+HL_PRIM void hl_dyn_seti64( vdynamic *d, int hfield, int64 value ) {
+	hl_type *ft = NULL;
+	hl_track_call(HL_TRACK_DYNFIELD, on_dynfield(d,hfield));
+	void *addr = hl_obj_lookup_set(d,hfield,&hlt_i64,&ft);
+	switch( ft->kind ) {
+	case HUI8:
+		*(unsigned char*)addr = (unsigned char)value;
+		break;
+	case HUI16:
+		*(unsigned short*)addr = (unsigned short)value;
+		break;
+	case HI32:
+		*(int*)addr = (int)value;
+		break;
+	case HI64:
+		*(int64*)addr = value;
+		break;
+	case HBOOL:
+		*(bool*)addr = value != 0;
+		break;
+	case HF32:
+		*(float*)addr = (float)value;
+		break;
+	case HF64:
+		*(double*)addr = (double)value;
+		break;
+	default:
+		{
+			vdynamic tmp;
+			tmp.t = &hlt_i64;
+			tmp.v.i64 = value;
+			hl_write_dyn(addr,ft,&tmp,true);
+		}
+		break;
+	}
+}
+
 HL_PRIM void hl_dyn_setf( vdynamic *d, int hfield, float value ) {
 	hl_type *t = NULL;
 	hl_track_call(HL_TRACK_DYNFIELD, on_dynfield(d,hfield));