Jelajahi Sumber

started string/array support

Nicolas Cannasse 10 tahun lalu
induk
melakukan
c0ac577d32
6 mengubah file dengan 108 tambahan dan 12 penghapusan
  1. 2 0
      src/alloc.c
  2. 4 1
      src/code.c
  3. 9 4
      src/hl.h
  4. 70 5
      src/jit.c
  5. 20 2
      src/module.c
  6. 3 0
      src/opcodes.h

+ 2 - 0
src/alloc.c

@@ -41,6 +41,8 @@ int hl_type_size( hl_type *t ) {
 		HL_WSIZE, // ANY
 		HL_WSIZE, // FUN
 		HL_WSIZE, // OBJ
+		HL_WSIZE, // BYTES
+		HL_WSIZE, // ARRAY
 	};
 	return SIZES[t->kind];
 }

+ 4 - 1
src/code.c

@@ -185,7 +185,10 @@ static void hl_read_type( hl_reader *r, hl_type *t ) {
 		break;
 	case HDYN | 0x80:
 		t->kind = HDYN;
-		t->dyn = hl_get_type(r);
+		t->t = hl_get_type(r);
+		break;
+	case HARRAY:
+		t->t = hl_get_type(r);
 		break;
 	default:
 		if( t->kind >= HLAST ) ERROR("Invalid type");

+ 9 - 4
src/hl.h

@@ -58,9 +58,11 @@
 #endif
 
 #ifdef HL_64
-#	define	HL_WSIZE 8
+#	define HL_WSIZE 8
+#	define IS_64	1
 #else
-#	define	HL_WSIZE 4
+#	define HL_WSIZE 4
+#	define IS_64	0
 #endif
 
 typedef	enum { false = 0, true = 1 } bool;
@@ -87,8 +89,10 @@ typedef enum {
 	HDYN	= 6,
 	HFUN	= 7,
 	HOBJ	= 8,
+	HBYTES	= 9,
+	HARRAY	= 10,
 	// ---------
-	HLAST	= 9,
+	HLAST	= 11,
 	_H_FORCE_INT = 0x7FFFFFFF
 } hl_type_kind;
 
@@ -127,7 +131,7 @@ struct hl_type {
 	union {
 		hl_type_fun *fun;
 		hl_type_obj *obj;
-		hl_type	*dyn;
+		hl_type	*t;
 	};
 };
 
@@ -263,6 +267,7 @@ struct hl_runtime_obj {
 	int size;
 	int *fields_indexes;
 	vobj_proto *proto;
+	const char *(*toString)( vobj * );
 };
 
 void *hl_alloc_executable_memory( int size );

+ 70 - 5
src/jit.c

@@ -54,6 +54,7 @@ typedef enum {
 	RET,
 	CALL,
 	AND,
+	XOR,
 	CMP,
 	NOP,
 	// SSE
@@ -61,6 +62,9 @@ typedef enum {
 	COMISD,
 	ADDSD,
 	SUBSD,
+	// 8 bits
+	MOV8,
+	// --
 	_CPU_LAST
 } CpuOp;
 
@@ -86,10 +90,8 @@ typedef enum {
 
 #ifdef HL_64
 #	define W64(wv)	*ctx->buf.w64++ = wv
-#	define IS_64	1
 #else
 #	define W64(wv)	W(wv)
-#	define IS_64	0
 #endif
 
 #define MOD_RM(mod,reg,rm)		B(((mod) << 6) | (((reg)&7) << 3) | ((rm)&7))
@@ -292,6 +294,7 @@ static opform OP_FORMS[_CPU_LAST] = {
 	{ "RET", 0xC3 },
 	{ "CALL", RM(0xFF,2), 0, 0xE8 },
 	{ "AND" },
+	{ "XOR", 0x33, 0x31, RM(0x81,6), RM(0x83,6) },
 	{ "CMP", 0x3B, 0x39, RM(0x81,7), RM(0x83,7) },
 	{ "NOP", 0x90 },
 	// SSE
@@ -299,6 +302,8 @@ static opform OP_FORMS[_CPU_LAST] = {
 	{ "COMISD", 0x660F2F },
 	{ "ADDSD", 0xF20F58 },
 	{ "SUBSD", 0xF20F5C },
+	// 8 bits,
+	{ "MOV8", 0x8A, 0x88, 0, 0xB0, RM(0xC6,0) },
 };
 
 static const char *REG_NAMES[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; 
@@ -761,10 +766,16 @@ static void store( jit_ctx *ctx, vreg *r, preg *v, bool bind ) {
 	switch( r->size ) {
 	case 0:
 		break;
+	case 1:
+		if( v->kind == RSTACK )
+			store(ctx,r,alloc_cpu(ctx, R(v->id), true), bind);
+		else
+			op32(ctx,MOV8,&r->stack,v);
+		break;
 	case 4:
 		if( v->kind == RSTACK )
 			store(ctx,r,alloc_cpu(ctx, R(v->id), true), bind);
-		else if( r->size == 4 )
+		else
 			op32(ctx,MOV,&r->stack,v);
 		break;
 	case 8:
@@ -799,9 +810,13 @@ static void op_mov( jit_ctx *ctx, vreg *to, vreg *from ) {
 
 static void store_const( jit_ctx *ctx, vreg *r, int c, bool useTmpReg ) {
 	preg p;
-	if( r->size != 4 ) ASSERT(r->size);
+	if( r->size > 4 )
+		ASSERT(r->size);
 	if( useTmpReg ) {
-		op32(ctx,MOV,alloc_cpu(ctx,r,false),pconst(&p,c));
+		if( c == 0 )
+			op32(ctx,XOR,alloc_cpu(ctx,r,false),alloc_cpu(ctx,r,false));
+		else
+			op32(ctx,MOV,alloc_cpu(ctx,r,false),pconst(&p,c));
 		store(ctx,r,r->current,false);
 	} else {
 		scratch(r->current);
@@ -1342,6 +1357,9 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		case OInt:
 			store_const(ctx, R(o->p1), m->code->ints[o->p2], true);
 			break;
+		case OBool:
+			store_const(ctx, R(o->p1), o->p2, true);
+			break;
 		case OGetGlobal:
 			{
 				vreg *to = R(o->p1);
@@ -1454,6 +1472,20 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				store(ctx,r,r->current,false); 
 			}
 			break;
+		case OString:
+			{
+				vreg *r = R(o->p1);
+				op64(ctx,MOV,alloc_cpu(ctx, r, false),pconst64(&p,(int_val)m->code->strings[o->p2]));
+				store(ctx,r,r->current,false);
+			}
+			break;
+		case ONull:
+			{
+				vreg *r = R(o->p1);
+				op64(ctx,XOR,alloc_cpu(ctx, r, false),alloc_cpu(ctx, r, false));
+				store(ctx,r,r->current,false);
+			}
+			break;
 		case ONew:
 			{
 				vreg *r = R(o->p1);
@@ -1503,6 +1535,33 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		case OCallClosure:
 			op_call_closure(ctx,R(o->p1),R(o->p2),o->p3,o->extra);
 			break;
+		case OField:
+			{
+				vreg *r = R(o->p2);
+				hl_runtime_obj *rt = hl_get_obj_rt(m, r->t);
+				preg *rr = alloc_cpu(ctx,r, true);
+				preg *rv;
+				LOCK(rr);
+				rv = alloc_reg(ctx,RCPU);
+				if( rr == rv ) ASSERT(0);
+				// TODO : copy data
+				op32(ctx, MOV, rv, pmem(&p, (CpuReg)rr->id, rt->fields_indexes[o->p3], 0));
+				store(ctx, R(o->p1), rv, true);
+			}
+			break;
+		case OSetField:
+			{
+				vreg *r = R(o->p1);
+				hl_runtime_obj *rt = hl_get_obj_rt(m, r->t);
+				preg *rr = alloc_cpu(ctx, r, true);
+				preg *rv;
+				LOCK(rr);
+				rv = alloc_cpu(ctx, R(o->p3), true);
+				if( rr == rv ) ASSERT(0);
+				// TODO : copy data
+				op32(ctx, MOV, pmem(&p, (CpuReg)rr->id, rt->fields_indexes[o->p2], 0), rv);
+			}
+			break;
 		case OGetThis:
 			{
 				vreg *r = R(0);
@@ -1570,6 +1629,12 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				store(ctx, dst, IS_FLOAT(dst) ? PXMM(0) : PEAX, true);
 			}
 			break;
+		case OThrow:
+			{
+				// TODO
+				BREAK();
+			}
+			break;
 		default:
 			printf("Don't know how to jit %s\n",hl_op_name(o->op));
 			break;

+ 20 - 2
src/module.c

@@ -31,6 +31,7 @@ hl_runtime_obj *hl_get_obj_rt( hl_module *m, hl_type *ot ) {
 	t = (hl_runtime_obj*)hl_malloc(alloc,sizeof(hl_runtime_obj));
 	t->nfields = o->nfields + (p ? p->nfields : 0);
 	t->fields_indexes = (int*)hl_malloc(alloc,sizeof(int)*t->nfields);
+	t->toString = NULL;
 	
 	// fields indexes
 	start = 0;
@@ -65,6 +66,8 @@ hl_runtime_obj *hl_get_obj_proto( hl_module *m, hl_type *ot ) {
 	for(i=0;i<o->nproto;i++) {
 		hl_obj_proto *p = o->proto + i;
 		if( p->pindex >= t->nproto ) t->nproto = p->pindex + 1;
+		if( memcmp(p->name,"__string",9) == 0 )
+			t->toString = m->functions_ptrs[p->findex];
 	}
 	t->proto = (vobj_proto*)hl_malloc(alloc, sizeof(vobj_proto) + t->nproto * sizeof(void*));
 	t->proto->t = ot;
@@ -121,7 +124,7 @@ static void null_function() {
 }
 
 static void do_log( vdynamic *v ) {
-	switch( (*v->t)->dyn->kind ) {
+	switch( (*v->t)->t->kind ) {
 	case HI32:
 		printf("%di\n",v->v.i);
 		break;
@@ -131,8 +134,23 @@ static void do_log( vdynamic *v ) {
 	case HVOID:
 		printf("void\n");
 		break;
+	case HBYTES:
+		printf("[%s]\n",v->v);
+		break;
+	case HOBJ:
+		{
+			hl_type_obj *o = v->v.o->proto->t->obj;
+			if( o->rt == NULL || o->rt->toString == NULL )
+				printf("#%s\n",o->name);
+			else
+				printf("[%s]\n",o->rt->toString(v->v.o));
+		}
+		break;
 	default:
-		printf("%llXH\n",v->v.ptr);
+		if( IS_64 )
+			printf("%llXH\n",v->v.ptr);
+		else
+			printf("%XH\n",v->v.ptr);
 		break;
 	}
 }

+ 3 - 0
src/opcodes.h

@@ -34,6 +34,8 @@ OP_BEGIN
 	OP(OInt,2)
 	OP(OFloat,2)
 	OP(OBool,2)
+	OP(OString,2)
+	OP(ONull,1)
 	OP(OAdd,3)
 	OP(OSub,3)
 	OP(OMul,3)
@@ -75,6 +77,7 @@ OP_BEGIN
 	OP(OSetField,3)
 	OP(OGetThis,2)
 	OP(OSetThis,2)
+	OP(OThrow,1)
 	// --
 	OP(OLast,0)
 OP_END