Browse Source

added HSTRUCT support

ncannasse 6 years ago
parent
commit
1aa580e7cc
9 changed files with 58 additions and 10 deletions
  1. 6 2
      src/alloc.c
  2. 1 0
      src/code.c
  3. 2 1
      src/hl.h
  4. 6 0
      src/jit.c
  5. 5 1
      src/module.c
  6. 2 1
      src/std/buffer.c
  7. 3 0
      src/std/cast.c
  8. 21 1
      src/std/obj.c
  9. 12 4
      src/std/types.c

+ 6 - 2
src/alloc.c

@@ -1256,8 +1256,12 @@ vdynamic *hl_alloc_obj( hl_type *t ) {
 	if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(t);
 	size = rt->size;
 	if( size & (HL_WSIZE-1) ) size += HL_WSIZE - (size & (HL_WSIZE-1));
-	o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO);
-	o->t = t;
+	if( t->kind == HSTRUCT ) {
+		o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
+	} else {
+		o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO);
+		o->t = t;
+	}
 	for(i=0;i<rt->nbindings;i++) {
 		hl_runtime_binding *b = rt->bindings + i;
 		*(void**)(((char*)o) + rt->fields_indexes[b->fid]) = b->closure ? hl_alloc_closure_ptr(b->closure,b->ptr,o) : b->ptr;

+ 1 - 0
src/code.c

@@ -167,6 +167,7 @@ static void hl_read_type( hl_reader *r, hl_type *t ) {
 		}
 		break;
 	case HOBJ:
+	case HSTRUCT:
 		{
 			int i;
 			const uchar *name = hl_read_ustring(r);

+ 2 - 1
src/hl.h

@@ -321,8 +321,9 @@ typedef enum {
 	HENUM	= 18,
 	HNULL	= 19,
 	HMETHOD = 20,
+	HSTRUCT	= 21,
 	// ---------
-	HLAST	= 21,
+	HLAST	= 22,
 	_H_FORCE_INT = 0x7FFFFFFF
 } hl_type_kind;
 

+ 6 - 0
src/jit.c

@@ -1722,6 +1722,7 @@ static preg *op_binop( jit_ctx *ctx, vreg *dst, vreg *a, vreg *b, hl_opcode *op
 	case HDYNOBJ:
 	case HVIRTUAL:
 	case HOBJ:
+	case HSTRUCT:
 	case HFUN:
 	case HMETHOD:
 	case HBYTES:
@@ -1759,6 +1760,7 @@ static preg *op_binop( jit_ctx *ctx, vreg *dst, vreg *a, vreg *b, hl_opcode *op
 		return out;
 #	ifdef HL_64
 	case HOBJ:
+	case HSTRUCT:
 	case HDYNOBJ:
 	case HVIRTUAL:
 	case HFUN:
@@ -2114,6 +2116,7 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 		}
 		break;
 	case HOBJ:
+	case HSTRUCT:
 		if( b->t->kind == HVIRTUAL ) {
 			op_jump(ctx,b,a,op,targetPos); // inverse
 			return;
@@ -3131,6 +3134,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				int nargs = 1;
 				switch( dst->t->kind ) {
 				case HOBJ:
+				case HSTRUCT:
 					allocFun = hl_alloc_obj;
 					break;
 				case HDYNOBJ:
@@ -3286,6 +3290,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			{
 				switch( ra->t->kind ) {
 				case HOBJ:
+				case HSTRUCT:
 					{
 						hl_runtime_obj *rt = hl_get_obj_rt(ra->t);
 						preg *rr = alloc_cpu(ctx,ra, true);
@@ -3324,6 +3329,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			{
 				switch( dst->t->kind ) {
 				case HOBJ:
+				case HSTRUCT:
 					{
 						hl_runtime_obj *rt = hl_get_obj_rt(dst->t);
 						preg *rr = alloc_cpu(ctx, dst, true);

+ 5 - 1
src/module.c

@@ -249,6 +249,8 @@ static void append_type( char **p, hl_type *t ) {
 	case HNULL:
 		append_type(p,t->tparam);
 		break;
+	case HSTRUCT:
+		*(*p)++ = 'S';
 	case HOBJ:
 		{
 			int i;
@@ -339,6 +341,7 @@ static void hl_module_init_indexes( hl_module *m ) {
 		hl_type *t = m->code->types + i;
 		switch( t->kind ) {
 		case HOBJ:
+		case HSTRUCT:
 			t->obj->m = &m->ctx;
 			t->obj->global_value = ((int)(int_val)t->obj->global_value) ? (void**)(int_val)(m->globals_data + m->globals_indexes[(int)(int_val)t->obj->global_value-1]) : NULL;
 			{
@@ -504,6 +507,7 @@ int hl_module_init( hl_module *m, h_bool hot_reload ) {
 		vdynamic *v = NULL;
 		switch (t->kind) {
 		case HOBJ:
+		case HSTRUCT:
 			rt = hl_get_obj_rt(t);
 			v = (vdynamic*)hl_malloc(&m->ctx.alloc,rt->size);
 			v->t = t;
@@ -651,7 +655,7 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 	}
 	for(i=0;i<m1->code->ntypes;i++) {
 		hl_type *t = m1->code->types + i;
-		if( t->kind == HOBJ ) hl_flush_proto(t);
+		if( t->kind == HOBJ || t->kind == HSTRUCT ) hl_flush_proto(t);
 	}
 
 	return true;

+ 2 - 1
src/std/buffer.c

@@ -229,10 +229,11 @@ static void hl_buffer_rec( hl_buffer *b, vdynamic *v, vlist *stack ) {
 		hl_buffer_str_sub(b, buf, usprintf(buf, 32, _PTR_FMT,(int_val)v->v.ptr));
 		break;
 	case HOBJ:
+	case HSTRUCT:
 		{
 			hl_type_obj *o = v->t->obj;
 			if( o->rt == NULL || o->rt->toStringFun == NULL ) {
-				hl_buffer_char(b,'#');
+				if( v->t->kind == HSTRUCT ) hl_buffer_char(b,'@');
 				hl_buffer_str(b,o->name);
 			} else
 				hl_buffer_str(b,o->rt->toStringFun(v));

+ 3 - 0
src/std/cast.c

@@ -130,6 +130,7 @@ HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
 		return *(void**)data;
 	switch( TK2(t->kind,to->kind) ) {
 	case TK2(HOBJ,HOBJ):
+	case TK2(HSTRUCT,HSTRUCT):
 		{
 			hl_type_obj *t1 = t->obj;
 			hl_type_obj *t2 = to->obj;
@@ -169,6 +170,7 @@ HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
 	case TK2(HFUN,HDYN):
 	case TK2(HNULL,HDYN):
 	case TK2(HARRAY,HDYN):
+	// NO(HSTRUCT,HDYN)
 		return *(void**)data;
 	}
 	if( to->kind == HDYN )
@@ -352,6 +354,7 @@ HL_PRIM int hl_dyn_compare( vdynamic *a, vdynamic *b ) {
 	case TK2(HI32, HF64):
 		return dcompare((double)a->v.i,b->v.d);
 	case TK2(HOBJ,HOBJ):
+	case TK2(HSTRUCT,HSTRUCT):
 		if( a->t->obj->rt->compareFun )
 			return a->t->obj->rt->compareFun(a,b);
 		return a > b ? 1 : -1;

+ 21 - 1
src/std/obj.c

@@ -227,7 +227,7 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
 		start = p->nfields;
 		memcpy(t->fields_indexes, p->fields_indexes, sizeof(int)*p->nfields);
 	}
-	size = p ? p->size : HL_WSIZE; // hl_type*
+	size = p ? p->size : (ot->kind == HSTRUCT ? 0 : HL_WSIZE); // hl_type*
 	nlookup = 0;
 	for(i=0;i<o->nfields;i++) {
 		hl_type *ft = o->fields[i].t;
@@ -722,6 +722,14 @@ static void *hl_obj_lookup( vdynamic *d, int hfield, hl_type **t ) {
 			return (char*)d + f->field_index;
 		}
 		break;
+	case HSTRUCT:
+		{
+			hl_field_lookup *f = obj_resolve_field(d->t->obj,hfield);
+			if( f == NULL || f->field_index < 0 ) return NULL;
+			*t = f->t;
+			return (char*)d->v.ptr + f->field_index;
+		}
+		break;
 	case HVIRTUAL:
 		{
 			vdynamic *v = ((vvirtual*)d)->value;
@@ -744,6 +752,7 @@ static void *hl_obj_lookup( vdynamic *d, int hfield, hl_type **t ) {
 static vdynamic *hl_obj_lookup_extra( vdynamic *d, int hfield ) {
 	switch( d->t->kind ) {
 	case HOBJ:
+	case HSTRUCT:
 		{
 			hl_field_lookup *f = obj_resolve_field(d->t->obj,hfield);
 			if( f && f->field_index < 0 )
@@ -858,6 +867,14 @@ static void *hl_obj_lookup_set( vdynamic *d, int hfield, hl_type *t, hl_type **f
 			return (char*)d + f->field_index;
 		}
 		break;
+	case HSTRUCT:
+		{
+			hl_field_lookup *f = obj_resolve_field(d->t->obj,hfield);
+			if( f == NULL || f->field_index < 0 ) hl_error("%s does not have field %s",d->t->obj->name,hl_field_name(hfield));
+			*ft = f->t;
+			return (char*)d->v.ptr + f->field_index;
+		}
+		break;
 	case HVIRTUAL:
 		{
 			vvirtual *v = (vvirtual*)d;
@@ -963,6 +980,7 @@ HL_PRIM vdynamic *hl_obj_get_field( vdynamic *obj, int hfield ) {
 	case HOBJ:
 	case HVIRTUAL:
 	case HDYNOBJ:
+	case HSTRUCT:
 		return (vdynamic*)hl_dyn_getp(obj,hfield,&hlt_dyn);
 	default:
 		return NULL;
@@ -1003,6 +1021,7 @@ HL_PRIM bool hl_obj_has_field( vdynamic *obj, int hfield ) {
 	if( obj == NULL ) return false;
 	switch( obj->t->kind ) {
 	case HOBJ:
+	case HSTRUCT:
 		{
 			hl_field_lookup *l = obj_resolve_field(obj->t->obj, hfield);
 			return l && l->field_index >= 0;
@@ -1066,6 +1085,7 @@ HL_PRIM varray *hl_obj_fields( vdynamic *obj ) {
 		}
 		break;
 	case HOBJ:
+	case HSTRUCT:
 		{
 			hl_type_obj *tobj = obj->t->obj;
 			hl_runtime_obj *o = tobj->rt;

+ 12 - 4
src/std/types.c

@@ -37,7 +37,7 @@ static const uchar *TSTR[] = {
 	USTR("void"), USTR("i8"), USTR("i16"), USTR("i32"), USTR("i64"), USTR("f32"), USTR("f64"),
 	USTR("bool"), USTR("bytes"), USTR("dynamic"), NULL, NULL,
 	USTR("array"), USTR("type"), NULL, NULL, USTR("dynobj"),
-	NULL, NULL, NULL, NULL
+	NULL, NULL, NULL, NULL, NULL
 };
 
 static int T_SIZES[] = {
@@ -62,6 +62,7 @@ static int T_SIZES[] = {
 	HL_WSIZE, // ENUM
 	HL_WSIZE, // NULL
 	HL_WSIZE, // METHOD
+	HL_WSIZE, // STRUCT
 };
 
 HL_PRIM int hl_type_size( hl_type *t ) {
@@ -136,6 +137,7 @@ HL_PRIM bool hl_same_type( hl_type *a, hl_type *b ) {
 			return hl_same_type(a->fun->ret, b->fun->ret);
 		}
 	case HOBJ:
+	case HSTRUCT:
 		return a->obj == b->obj;
 	case HVIRTUAL:
 		return a->virt == b->virt;
@@ -172,6 +174,7 @@ HL_PRIM bool hl_is_dynamic( hl_type *t ) {
 		true, // HENUM
 		true, // HNULL
 		false, // HMETHOD
+		false, // HSTRUCT
 	};
 	return T_IS_DYNAMIC[t->kind];
 }
@@ -198,6 +201,7 @@ HL_PRIM bool hl_safe_cast( hl_type *t, hl_type *to ) {
 		}
 		break;
 	case HOBJ:
+	case HSTRUCT:
 		{
 			hl_type_obj *o = t->obj;
 			hl_type_obj *oto = to->obj;
@@ -266,8 +270,9 @@ static void hl_type_str_rec( hl_buffer *b, hl_type *t, tlist *parents ) {
 		hl_buffer_char(b,')');
 		hl_buffer_char(b,')');
 		break;
+	case HSTRUCT:
+		hl_buffer_char(b,'@');
 	case HOBJ:
-		hl_buffer_char(b,'#');
 		hl_buffer_str(b,t->obj->name);
 		break;
 	case HREF:
@@ -321,6 +326,7 @@ HL_PRIM const uchar *hl_type_str( hl_type *t ) {
 HL_PRIM vbyte* hl_type_name( hl_type *t ) {
 	switch( t->kind ) {
 	case HOBJ:
+	case HSTRUCT:
 		return (vbyte*)t->obj->name;
 	case HENUM:
 		return (vbyte*)t->tenum->name;
@@ -408,7 +414,7 @@ HL_PRIM varray *hl_type_instance_fields( hl_type *t ) {
 			names[i] = t->virt->fields[i].name;
 		return a;
 	}
-	if( t->kind != HOBJ )
+	if( t->kind != HOBJ && t->kind != HSTRUCT )
 		return NULL;
 	o = t->obj;
 	while( true ) {
@@ -444,7 +450,7 @@ HL_PRIM varray *hl_type_instance_fields( hl_type *t ) {
 }
 
 HL_PRIM hl_type *hl_type_super( hl_type *t ) {
-	if( t->kind == HOBJ && t->obj->super )
+	if( (t->kind == HOBJ || t->kind == HSTRUCT) && t->obj->super )
 		return t->obj->super;
 	return &hlt_void;
 }
@@ -452,6 +458,7 @@ HL_PRIM hl_type *hl_type_super( hl_type *t ) {
 HL_PRIM vdynamic *hl_type_get_global( hl_type *t ) {
 	switch( t->kind ) {
 	case HOBJ:
+	case HSTRUCT:
 		return t->obj->global_value ? *(vdynamic**)t->obj->global_value : NULL;
 	case HENUM:
 		return *(vdynamic**)t->tenum->global_value;
@@ -464,6 +471,7 @@ HL_PRIM vdynamic *hl_type_get_global( hl_type *t ) {
 HL_PRIM bool hl_type_set_global( hl_type *t, vdynamic *v ) {
 	switch( t->kind ) {
 	case HOBJ:
+	case HSTRUCT:
 		if( t->obj->global_value ) {
 			*(vdynamic**)t->obj->global_value = v;
 			return true;