Explorar o código

OO continued (not yet finished)

Nicolas Cannasse %!s(int64=10) %!d(string=hai) anos
pai
achega
56ad1f617a
Modificáronse 5 ficheiros con 85 adicións e 52 borrados
  1. 13 8
      src/code.c
  2. 5 4
      src/hl.h
  3. 55 31
      src/jit.c
  4. 7 9
      src/module.c
  5. 5 0
      src/opcodes.h

+ 13 - 8
src/code.c

@@ -163,9 +163,9 @@ static void hl_read_type( hl_reader *r, hl_type *t ) {
 		{
 		{
 			int i;
 			int i;
 			const char *name = hl_get_string(r);
 			const char *name = hl_get_string(r);
-			int super = INDEX() - 1;
-			int nfields = INDEX();
-			int nproto = INDEX();
+			int super = INDEX();
+			int nfields = UINDEX();
+			int nproto = UINDEX();
 			t->obj = (hl_type_obj*)hl_malloc(&r->code->alloc,sizeof(hl_type_obj));
 			t->obj = (hl_type_obj*)hl_malloc(&r->code->alloc,sizeof(hl_type_obj));
 			t->obj->name = name;
 			t->obj->name = name;
 			t->obj->super = super < 0 ? NULL : r->code->types + super;
 			t->obj->super = super < 0 ? NULL : r->code->types + super;
@@ -181,8 +181,7 @@ static void hl_read_type( hl_reader *r, hl_type *t ) {
 			for(i=0;i<nproto;i++) {
 			for(i=0;i<nproto;i++) {
 				hl_obj_proto *p = t->obj->proto + i;
 				hl_obj_proto *p = t->obj->proto + i;
 				p->name = hl_get_string(r);
 				p->name = hl_get_string(r);
-				p->t = hl_get_type(r);
-				p->global = UINDEX();
+				p->findex = UINDEX();
 			}
 			}
 		}
 		}
 	default:
 	default:
@@ -220,6 +219,8 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 	case -1:
 	case -1:
 		switch( o->op ) {
 		switch( o->op ) {
 		case OCallN:
 		case OCallN:
+		case OCallClosure:
+		case OCallMethod:
 			{
 			{
 				int i;
 				int i;
 				o->p1 = INDEX();
 				o->p1 = INDEX();
@@ -234,6 +235,7 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 			ERROR("Don't know how to process opcode");
 			ERROR("Don't know how to process opcode");
 			break;
 			break;
 		}
 		}
+		break;
 	default:
 	default:
 		{
 		{
 			int i, size = hl_op_nargs[o->op] - 3;
 			int i, size = hl_op_nargs[o->op] - 3;
@@ -250,7 +252,8 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 
 
 static void hl_read_function( hl_reader *r, hl_function *f ) {
 static void hl_read_function( hl_reader *r, hl_function *f ) {
 	int i;
 	int i;
-	f->global = UINDEX();
+	f->type = hl_get_type(r);
+	f->findex = UINDEX();
 	f->nregs = UINDEX();
 	f->nregs = UINDEX();
 	f->nops = UINDEX();
 	f->nops = UINDEX();
 	f->regs = (hl_type**)hl_malloc(&r->code->alloc, f->nregs * sizeof(hl_type*));
 	f->regs = (hl_type**)hl_malloc(&r->code->alloc, f->nregs * sizeof(hl_type*));
@@ -338,8 +341,10 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	CHK_ERROR();
 	CHK_ERROR();
 	ALLOC(c->natives, hl_native, c->nnatives);
 	ALLOC(c->natives, hl_native, c->nnatives);
 	for(i=0;i<c->nnatives;i++) {
 	for(i=0;i<c->nnatives;i++) {
-		c->natives[i].name = hl_get_string(r);
-		c->natives[i].global = hl_get_global(r);
+		hl_native *n = c->natives + i;
+		n->name = hl_get_string(r);
+		n->t = hl_get_type(r);
+		n->findex = UINDEX();
 	}
 	}
 	CHK_ERROR();
 	CHK_ERROR();
 	ALLOC(c->functions, hl_function, c->nfunctions);
 	ALLOC(c->functions, hl_function, c->nfunctions);

+ 5 - 4
src/hl.h

@@ -107,8 +107,7 @@ typedef struct {
 
 
 typedef struct {
 typedef struct {
 	const char *name;
 	const char *name;
-	hl_type *t;
-	int global;
+	int findex;
 } hl_obj_proto;
 } hl_obj_proto;
 
 
 typedef struct {
 typedef struct {
@@ -130,7 +129,8 @@ struct hl_type {
 
 
 typedef struct {
 typedef struct {
 	const char *name;
 	const char *name;
-	int global;
+	hl_type *t;
+	int findex;
 } hl_native;
 } hl_native;
 
 
 typedef struct {
 typedef struct {
@@ -144,9 +144,10 @@ typedef struct {
 typedef struct hl_ptr_list hl_ptr_list;
 typedef struct hl_ptr_list hl_ptr_list;
 
 
 typedef struct {
 typedef struct {
-	int global;
+	int findex;
 	int nregs;
 	int nregs;
 	int nops;
 	int nops;
+	hl_type *type;
 	hl_type **regs;
 	hl_type **regs;
 	hl_opcode *ops;
 	hl_opcode *ops;
 } hl_function;
 } hl_function;

+ 55 - 31
src/jit.c

@@ -194,7 +194,7 @@ struct jit_ctx {
 	int functionPos;
 	int functionPos;
 	int allocOffset;
 	int allocOffset;
 	int currentPos;
 	int currentPos;
-	int *globalToFunction;
+	int *functionReindex;
 	unsigned char *startBuf;
 	unsigned char *startBuf;
 	hl_module *m;
 	hl_module *m;
 	hl_function *f;
 	hl_function *f;
@@ -528,6 +528,19 @@ static void op( jit_ctx *ctx, CpuOp o, preg *a, preg *b, bool mode64 ) {
 		else
 		else
 			W((int)b->holds);
 			W((int)b->holds);
 		break;
 		break;
+#	ifndef HL_64
+	case ID2(RADDR,RFPU):
+#	endif
+	case ID2(RADDR,RCPU):
+		ERRIF( f->mem_r == 0 );
+		if( b->id > 7 ) r64 |= 4;
+		OP(f->mem_r);
+		MOD_RM(0,b->id,5);
+		if( IS_64 )
+			W64((int_val)a->holds);
+		else
+			W((int)a->holds);
+		break;
 	case ID2(RMEM, RCPU):
 	case ID2(RMEM, RCPU):
 	case ID2(RMEM, RFPU):
 	case ID2(RMEM, RFPU):
 		ERRIF( f->mem_r == 0 );
 		ERRIF( f->mem_r == 0 );
@@ -760,13 +773,6 @@ static void store_const( jit_ctx *ctx, vreg *r, int c, bool useTmpReg ) {
 	}
 	}
 }
 }
 
 
-static void op_mova( jit_ctx *ctx, vreg *to, void *value ) {
-	preg *r = alloc_cpu(ctx, to, false);
-	preg p;
-	op32(ctx,MOV,r,paddr(&p,value));
-	store(ctx, to, r, false);
-}
-
 static void discard_regs( jit_ctx *ctx, int native_call ) {
 static void discard_regs( jit_ctx *ctx, int native_call ) {
 	int i;
 	int i;
 	for(i=0;i<RCPU_SCRATCH_COUNT;i++) {
 	for(i=0;i<RCPU_SCRATCH_COUNT;i++) {
@@ -904,24 +910,24 @@ static void call_native( jit_ctx *ctx, void *nativeFun, int size ) {
 	op64(ctx,ADD,PESP,pconst(&p,size));
 	op64(ctx,ADD,PESP,pconst(&p,size));
 }
 }
 
 
-static void op_callg( jit_ctx *ctx, vreg *dst, int g, int count, int *args ) {
-	int fid = ctx->globalToFunction[g];
+static void op_call_fun( jit_ctx *ctx, vreg *dst, int findex, int count, int *args ) {
+	int fid = ctx->functionReindex[findex];
 	int isNative = fid >= ctx->m->code->nfunctions;
 	int isNative = fid >= ctx->m->code->nfunctions;
 	int i = 0, size = prepare_call_args(ctx,count,args,isNative);
 	int i = 0, size = prepare_call_args(ctx,count,args,isNative);
 	preg p;
 	preg p;
 	if( fid < 0 ) {
 	if( fid < 0 ) {
 		// not a static function or native, load it at runtime
 		// not a static function or native, load it at runtime
-		op64(ctx,MOV,PEAX,paddr(&p,ctx->m->globals_data + ctx->m->globals_indexes[g]));
+		op64(ctx,MOV,PEAX,paddr(&p,ctx->m->functions_ptrs + findex));
 		op64(ctx,CALL,PEAX,NULL);
 		op64(ctx,CALL,PEAX,NULL);
 		discard_regs(ctx, 1);
 		discard_regs(ctx, 1);
 	} else if( isNative ) {
 	} else if( isNative ) {
-		call_native(ctx,*(void**)(ctx->m->globals_data + ctx->m->globals_indexes[g]), size);
+		call_native(ctx,ctx->m->functions_ptrs[findex],size);
 		size = 0;
 		size = 0;
 	} else {
 	} else {
 		int cpos = BUF_POS();
 		int cpos = BUF_POS();
-		if( ctx->m->functions_ptrs[fid] ) {
+		if( ctx->m->functions_ptrs[findex] ) {
 			// already compiled
 			// already compiled
-			op32(ctx,CALL,pconst(&p,(int)ctx->m->functions_ptrs[fid] - (cpos + 5)), UNUSED);
+			op32(ctx,CALL,pconst(&p,(int)ctx->m->functions_ptrs[findex] - (cpos + 5)), UNUSED);
 		} else if( ctx->m->code->functions + fid == ctx->f ) {
 		} else if( ctx->m->code->functions + fid == ctx->f ) {
 			// our current function
 			// our current function
 			op32(ctx,CALL,pconst(&p, ctx->functionPos - (cpos + 5)), UNUSED);
 			op32(ctx,CALL,pconst(&p, ctx->functionPos - (cpos + 5)), UNUSED);
@@ -929,7 +935,7 @@ static void op_callg( jit_ctx *ctx, vreg *dst, int g, int count, int *args ) {
 			// stage for later
 			// stage for later
 			jlist *j = (jlist*)hl_malloc(&ctx->galloc,sizeof(jlist));
 			jlist *j = (jlist*)hl_malloc(&ctx->galloc,sizeof(jlist));
 			j->pos = cpos;
 			j->pos = cpos;
-			j->target = g;
+			j->target = findex;
 			j->next = ctx->calls;
 			j->next = ctx->calls;
 			ctx->calls = j;
 			ctx->calls = j;
 			op32(ctx,CALL,pconst(&p,0),UNUSED);
 			op32(ctx,CALL,pconst(&p,0),UNUSED);
@@ -1126,7 +1132,7 @@ void hl_jit_free( jit_ctx *ctx ) {
 	free(ctx->vregs);
 	free(ctx->vregs);
 	free(ctx->opsPos);
 	free(ctx->opsPos);
 	free(ctx->startBuf);
 	free(ctx->startBuf);
-	free(ctx->globalToFunction);
+	free(ctx->functionReindex);
 	hl_free(&ctx->falloc);
 	hl_free(&ctx->falloc);
 	hl_free(&ctx->galloc);
 	hl_free(&ctx->galloc);
 	free(ctx);
 	free(ctx);
@@ -1135,17 +1141,17 @@ void hl_jit_free( jit_ctx *ctx ) {
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	int i, size = 0;
 	int i, size = 0;
 	int codePos;
 	int codePos;
-	int nargs = m->code->globals[f->global]->fun->nargs;
+	int nargs = f->type->fun->nargs;
 	preg p;
 	preg p;
 	ctx->m = m;
 	ctx->m = m;
 	ctx->f = f;
 	ctx->f = f;
-	if( !ctx->globalToFunction ) {
-		ctx->globalToFunction = (int*)malloc(sizeof(int)*m->code->nglobals);
-		memset(ctx->globalToFunction,0xFF,sizeof(int)*m->code->nglobals);
+	if( !ctx->functionReindex ) {
+		ctx->functionReindex = (int*)malloc(sizeof(int)*(m->code->nfunctions+m->code->nnatives));
+		memset(ctx->functionReindex,0xFF,sizeof(int)*(m->code->nfunctions+m->code->nnatives));
 		for(i=0;i<m->code->nfunctions;i++)
 		for(i=0;i<m->code->nfunctions;i++)
-			ctx->globalToFunction[(m->code->functions + i)->global] = i;
+			ctx->functionReindex[(m->code->functions + i)->findex] = i;
 		for(i=0;i<m->code->nnatives;i++)
 		for(i=0;i<m->code->nnatives;i++)
-			ctx->globalToFunction[(m->code->natives + i)->global] = i + m->code->nfunctions;
+			ctx->functionReindex[(m->code->natives + i)->findex] = i + m->code->nfunctions;
 		for(i=0;i<m->code->nfloats;i++) {
 		for(i=0;i<m->code->nfloats;i++) {
 			jit_buf(ctx);
 			jit_buf(ctx);
 			*ctx->buf.d++ = m->code->floats[i];
 			*ctx->buf.d++ = m->code->floats[i];
@@ -1214,25 +1220,45 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			store_const(ctx, R(o->p1), m->code->ints[o->p2], true);
 			store_const(ctx, R(o->p1), m->code->ints[o->p2], true);
 			break;
 			break;
 		case OGetGlobal:
 		case OGetGlobal:
-			op_mova(ctx, R(o->p1), m->globals_data + m->globals_indexes[o->p2]);
+			{
+				vreg *to = R(o->p1);
+				preg *r = IS_FLOAT(to) ? alloc_fpu(ctx,to,false) : alloc_cpu(ctx, to, false);
+				void *addr = m->globals_data + m->globals_indexes[o->p2];
+				if( IS_FLOAT(to) )
+					op64(ctx,MOVSD,r,paddr(&p,addr));
+				else
+					op32(ctx,MOV,r,paddr(&p,addr));
+				store(ctx, to, r, false);
+			}
+			break;
+		case OSetGlobal:
+			{
+				vreg *r = R(o->p2);
+				preg *v = IS_FLOAT(r) ? alloc_fpu(ctx,r,true) : alloc_cpu(ctx,r,true);
+				void *addr = m->globals_data + m->globals_indexes[o->p1];
+				if( IS_FLOAT(r) )
+					op64(ctx,MOVSD,paddr(&p,addr),v);
+				else
+					op32(ctx,MOV,paddr(&p,addr),v);
+			}
 			break;
 			break;
 		case OCall3:
 		case OCall3:
 		case OCall4:
 		case OCall4:
 		case OCallN:
 		case OCallN:
-			op_callg(ctx, R(o->p1), o->p2, o->p3, o->extra);
+			op_call_fun(ctx, R(o->p1), o->p2, o->p3, o->extra);
 			break;
 			break;
 		case OCall0:
 		case OCall0:
-			op_callg(ctx, R(o->p1), o->p2, 0, NULL);
+			op_call_fun(ctx, R(o->p1), o->p2, 0, NULL);
 			break;
 			break;
 		case OCall1:
 		case OCall1:
-			op_callg(ctx, R(o->p1), o->p2, 1, &o->p3);
+			op_call_fun(ctx, R(o->p1), o->p2, 1, &o->p3);
 			break;
 			break;
 		case OCall2:
 		case OCall2:
 			{
 			{
 				int args[2];
 				int args[2];
 				args[0] = o->p3;
 				args[0] = o->p3;
 				args[1] = (int)o->extra;
 				args[1] = (int)o->extra;
-				op_callg(ctx, R(o->p1), o->p2, 2, args);
+				op_call_fun(ctx, R(o->p1), o->p2, 2, args);
 			}
 			}
 			break;
 			break;
 		case OSub:
 		case OSub:
@@ -1308,8 +1334,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			break;
 			break;
 		default:
 		default:
 			printf("Don't know how to jit %s\n",hl_op_name(o->op));
 			printf("Don't know how to jit %s\n",hl_op_name(o->op));
-			ASSERT(o->op);
-			return -1;
+			break;
 		}
 		}
 		// we are landing at this position, assume we have lost our registers
 		// we are landing at this position, assume we have lost our registers
 		if( ctx->opsPos[i+1] == -1 )
 		if( ctx->opsPos[i+1] == -1 )
@@ -1350,8 +1375,7 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m ) {
 	// patch calls
 	// patch calls
 	c = ctx->calls;
 	c = ctx->calls;
 	while( c ) {
 	while( c ) {
-		int fid = ctx->globalToFunction[c->target];
-		int fpos = (int)m->functions_ptrs[fid];
+		int fpos = (int)m->functions_ptrs[c->target];
 		*(int*)(code + c->pos + 1) = fpos - (c->pos + 5);
 		*(int*)(code + c->pos + 1) = fpos - (c->pos + 5);
 		c = c->next;
 		c = c->next;
 	}
 	}

+ 7 - 9
src/module.c

@@ -87,29 +87,27 @@ int hl_module_init( hl_module *m ) {
 	// INIT natives
 	// INIT natives
 	for(i=0;i<m->code->nnatives;i++) {
 	for(i=0;i<m->code->nnatives;i++) {
 		hl_native *n = m->code->natives + i;
 		hl_native *n = m->code->natives + i;
-		*(void**)(m->globals_data + m->globals_indexes[n->global]) = do_log;
+		m->functions_ptrs[n->findex] = do_log;
 	}
 	}
 	// JIT
 	// JIT
 	ctx = hl_jit_alloc();
 	ctx = hl_jit_alloc();
 	if( ctx == NULL )
 	if( ctx == NULL )
 		return 0;
 		return 0;
 	for(i=0;i<m->code->nfunctions;i++) {
 	for(i=0;i<m->code->nfunctions;i++) {
-		int f = hl_jit_function(ctx, m, m->code->functions+i);
-		if( f < 0 ) {
+		hl_function *f = m->code->functions + i;
+		int fpos = hl_jit_function(ctx, m, f);
+		if( fpos < 0 ) {
 			hl_jit_free(ctx);
 			hl_jit_free(ctx);
 			return 0;
 			return 0;
 		}
 		}
-		m->functions_ptrs[i] = (void*)f;
+		m->functions_ptrs[f->findex] = (void*)fpos;
 	}
 	}
 	m->jit_code = hl_jit_code(ctx, m);
 	m->jit_code = hl_jit_code(ctx, m);
-	for(i=0;i<m->code->nfunctions;i++)
-		m->functions_ptrs[i] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[i]);
-	hl_jit_free(ctx);
-	// INIT functions
 	for(i=0;i<m->code->nfunctions;i++) {
 	for(i=0;i<m->code->nfunctions;i++) {
 		hl_function *f = m->code->functions + i;
 		hl_function *f = m->code->functions + i;
-		*(void**)(m->globals_data + m->globals_indexes[f->global]) = m->functions_ptrs[i];
+		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);
 	}
 	}
+	hl_jit_free(ctx);
 	return 1;
 	return 1;
 }
 }
 
 

+ 5 - 0
src/opcodes.h

@@ -46,6 +46,10 @@ OP_BEGIN
 	OP(OCall3,5)
 	OP(OCall3,5)
 	OP(OCall4,6)
 	OP(OCall4,6)
 	OP(OCallN,-1)
 	OP(OCallN,-1)
+	OP(OCallMethod,-1)
+	OP(OCallClosure,-1)
+	OP(OGetFunction,2)
+	OP(OClosure,3)
 	OP(OGetGlobal, 2)
 	OP(OGetGlobal, 2)
 	OP(OSetGlobal,2)
 	OP(OSetGlobal,2)
 	OP(OEq,3)
 	OP(OEq,3)
@@ -66,6 +70,7 @@ OP_BEGIN
 	OP(OLabel,1)
 	OP(OLabel,1)
 	OP(ONew,1)
 	OP(ONew,1)
 	OP(OField,3)
 	OP(OField,3)
+	OP(OMethod,3)
 	OP(OSetField,3)
 	OP(OSetField,3)
 	OP(OGetThis,2)
 	OP(OGetThis,2)
 	OP(OSetThis,2)
 	OP(OSetThis,2)