Nicolas Cannasse пре 10 година
родитељ
комит
bb9a0781fd
6 измењених фајлова са 127 додато и 46 уклоњено
  1. 1 1
      hl.vcxproj
  2. 10 1
      src/alloc.c
  3. 35 30
      src/code.c
  4. 45 4
      src/hl.h
  5. 30 9
      src/jit.c
  6. 6 1
      src/opcodes.h

+ 1 - 1
hl.vcxproj

@@ -139,8 +139,8 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="src\alloc.c" />
     <ClCompile Include="src\code.c" />
-    <ClCompile Include="src\global.c" />
     <ClCompile Include="src\jit.c" />
     <ClCompile Include="src\main.c" />
     <ClCompile Include="src\module.c" />

+ 10 - 1
src/global.c → src/alloc.c

@@ -40,6 +40,7 @@ int hl_type_size( hl_type *t ) {
 		1, // BOOL
 		HL_WSIZE, // ANY
 		HL_WSIZE, // FUN
+		HL_WSIZE, // OBJ
 	};
 	return SIZES[t->kind];
 }
@@ -70,7 +71,10 @@ void *hl_malloc( hl_alloc *a, int size ) {
 	if( b == NULL || b->size <= size ) {
 		int alloc = size < 4096-sizeof(hl_alloc_block) ? 4096-sizeof(hl_alloc_block) : size;
 		b = (hl_alloc_block *)malloc(sizeof(hl_alloc_block) + alloc);
-		if( b == NULL ) return NULL;
+		if( b == NULL ) {
+			printf("Out of memory");
+			exit(99);
+		}
 		b->p = ((unsigned char*)b) + sizeof(hl_alloc_block);
 		b->size = alloc;
 		b->next = a->cur;
@@ -120,6 +124,11 @@ vdynamic *hl_alloc_dynamic( hl_type *t ) {
 	return d;
 }
 
+vobj *hl_alloc_obj( hl_module *m, hl_type_obj *t ) {
+	printf("TODO");
+	return NULL;
+}
+
 void hl_call( void *f ) {
 #	if !defined(HL_64) && defined(HL_VCC)
 	int old_esp;

+ 35 - 30
src/code.c

@@ -142,7 +142,6 @@ static int hl_get_global( hl_reader *r ) {
 }
 
 static void hl_read_type( hl_reader *r, hl_type *t ) {
-	int i;
 	t->kind = READ();
 	if( t->kind >= HLAST ) {
 		ERROR("Invalid type");
@@ -150,16 +149,42 @@ static void hl_read_type( hl_reader *r, hl_type *t ) {
 	}
 	switch( t->kind ) {
 	case HFUN:
-		t->nargs = READ();
-		t->args = (hl_type**)hl_malloc(&r->code->alloc, sizeof(hl_type*)*t->nargs);
-		if( t->args == NULL ) {
-			ERROR("Out of memory");
-			return;
+		{
+			int i;
+			int nargs = READ(); 
+			t->fun = (hl_type_fun*)hl_malloc(&r->code->alloc,sizeof(hl_type_fun) + sizeof(hl_type*)*(nargs-1));
+			t->fun->nargs = nargs;
+			for(i=0;i<nargs;i++)
+				(&t->fun->args)[i] = hl_get_type(r);
+			t->fun->ret = hl_get_type(r);
 		}
-		for(i=0;i<t->nargs;i++)
-			t->args[i] = hl_get_type(r);
-		t->ret = hl_get_type(r);
 		break;
+	case HOBJ:
+		{
+			int i;
+			const char *name = hl_get_string(r);
+			int super = INDEX() - 1;
+			int nfields = INDEX();
+			int nproto = INDEX();
+			t->obj = (hl_type_obj*)hl_malloc(&r->code->alloc,sizeof(hl_type_obj));
+			t->obj->name = name;
+			t->obj->super = super < 0 ? NULL : r->code->types + super;
+			t->obj->nfields = nfields;
+			t->obj->nproto = nproto;
+			t->obj->fields = (hl_obj_field*)hl_malloc(&r->code->alloc,sizeof(hl_obj_field)*nfields);
+			t->obj->proto = (hl_obj_proto*)hl_malloc(&r->code->alloc,sizeof(hl_obj_proto)*nproto);
+			for(i=0;i<nfields;i++) {
+				hl_obj_field *f = t->obj->fields + i;
+				f->name = hl_get_string(r);
+				f->t = hl_get_type(r);
+			}
+			for(i=0;i<nproto;i++) {
+				hl_obj_proto *p = t->obj->proto + i;
+				p->name = hl_get_string(r);
+				p->t = hl_get_type(r);
+				p->global = UINDEX();
+			}
+		}
 	default:
 		break;
 	}
@@ -201,10 +226,6 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 				o->p2 = INDEX();
 				o->p3 = READ();
 				o->extra = (int*)hl_malloc(&r->code->alloc,sizeof(int) * o->p3);
-				if( o->extra == NULL ) {
-					ERROR("Out of memory");
-					return;
-				}
 				for(i=0;i<o->p3;i++)
 					o->extra[i] = INDEX();
 			}
@@ -220,10 +241,6 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 			o->p2 = INDEX();
 			o->p3 = INDEX();
 			o->extra = (int*)hl_malloc(&r->code->alloc,sizeof(int) * size);
-			if( o->extra == NULL ) {
-				ERROR("Out of memory");
-				return;
-			}
 			for(i=0;i<size;i++)
 				o->extra[i] = INDEX();
 		}
@@ -237,18 +254,10 @@ static void hl_read_function( hl_reader *r, hl_function *f ) {
 	f->nregs = UINDEX();
 	f->nops = UINDEX();
 	f->regs = (hl_type**)hl_malloc(&r->code->alloc, f->nregs * sizeof(hl_type*));
-	if( f->regs == NULL ) {
-		ERROR("Out of memory");
-		return;
-	}
 	for(i=0;i<f->nregs;i++)
 		f->regs[i] = hl_get_type(r);
 	CHK_ERROR();
 	f->ops = (hl_opcode*)hl_malloc(&r->code->alloc, f->nops * sizeof(hl_opcode));
-	if( f->ops == NULL ) {
-		ERROR("Out of memory");
-		return;
-	}
 	for(i=0;i<f->nops;i++)
 		hl_read_opcode(r, f, f->ops+i);
 }
@@ -256,7 +265,7 @@ static void hl_read_function( hl_reader *r, hl_function *f ) {
 #undef CHK_ERROR
 #define CHK_ERROR() if( r->error ) { if( c ) hl_free(&c->alloc); printf("%s\n", r->error); return NULL; }
 #define EXIT(msg) { ERROR(msg); CHK_ERROR(); }
-#define ALLOC(v,ptr,count) { v = (ptr *)hl_zalloc(&c->alloc,count*sizeof(ptr)); if( v == NULL ) EXIT("Out of memory"); }
+#define ALLOC(v,ptr,count) v = (ptr *)hl_zalloc(&c->alloc,count*sizeof(ptr))
 
 const char *hl_op_name( int op ) {
 	if( op < 0 || op >= OLast )
@@ -272,8 +281,6 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	int i;
 	hl_alloc_init(&alloc);
 	c = hl_zalloc(&alloc,sizeof(hl_code));
-	if( c == NULL )
-		EXIT("Out of memory");
 	c->alloc = alloc;
 	if( READ() != 'H' || READ() != 'L' || READ() != 'B' )
 		EXIT("Invalid header");
@@ -305,8 +312,6 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 		char *sdata;
 		CHK_ERROR();
 		sdata = (char*)hl_malloc(&c->alloc,sizeof(char) * size);
-		if( sdata == NULL )
-			EXIT("Out of memory");
 		hl_read_bytes(r, sdata, size);
 		c->strings_data = sdata;
 		ALLOC(c->strings, char*, c->nstrings);

+ 45 - 4
src/hl.h

@@ -86,18 +86,46 @@ typedef enum {
 	HBOOL	= 5,
 	HANY	= 6,
 	HFUN	= 7,
+	HOBJ	= 8,
 	// ---------
-	HLAST	= 8,
+	HLAST	= 9,
 	_H_FORCE_INT = 0x7FFFFFFF
 } hl_type_kind;
 
 typedef struct hl_type hl_type;
 
-struct hl_type {
-	hl_type_kind kind;
+typedef struct {
 	int nargs;
-	hl_type **args;
 	hl_type *ret;
+	hl_type *args;
+} hl_type_fun;
+
+typedef struct {
+	const char *name;
+	hl_type *t;
+} hl_obj_field;
+
+typedef struct {
+	const char *name;
+	hl_type *t;
+	int global;
+} hl_obj_proto;
+
+typedef struct {
+	int nfields;
+	int nproto;
+	const char *name;
+	hl_type *super;
+	hl_obj_field *fields;
+	hl_obj_proto *proto;
+} hl_type_obj;
+
+struct hl_type {
+	hl_type_kind kind;
+	union {
+		hl_type_fun *fun;
+		hl_type_obj *obj;
+	};
 };
 
 typedef struct {
@@ -179,6 +207,8 @@ void hl_jit_free( jit_ctx *ctx );
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f );
 void *hl_jit_code( jit_ctx *ctx, hl_module *m );
 
+/* -------------------- RUNTIME ------------------------------ */
+
 typedef struct {
 	hl_type *t;
 #	ifndef HL_64
@@ -192,7 +222,18 @@ typedef struct {
 	} v;
 } vdynamic;
 
+typedef struct vobj_proto vobj_proto;
+
+struct vobj_proto {
+	hl_type *t;
+};
+
+typedef struct {
+	vobj_proto *proto;
+} vobj;
+
 void hl_call( void *f );
 vdynamic *hl_alloc_dynamic( hl_type *t );
+vobj *hl_alloc_obj( hl_module *m, hl_type_obj *o );
 
 #endif

+ 30 - 9
src/jit.c

@@ -1088,6 +1088,20 @@ static void register_jump( jit_ctx *ctx, int *p, int target ) {
 	ctx->opsPos[target] = -1;
 }
 
+static void call_native_consts( jit_ctx *ctx, void *nativeFun, int_val *args, int nargs ) {
+	int size = pad_stack(ctx, IS_64 ? 0 : HL_WSIZE*nargs);
+	preg p;
+	int i;
+#	ifdef HL_64
+	for(i=0;i<nargs;i++)
+		op64(ctx, MOV, REG_AT(CALL_REGS[i]), pconst64(&p, args[i]));
+#	else
+	for(i=nargs-1;i>=0;i--)
+		op32(ctx, PUSH, pconst64(&p, args[i]), UNUSED);
+#	endif
+	call_native(ctx, nativeFun, size);
+}
+
 jit_ctx *hl_jit_alloc() {
 	int i;
 	jit_ctx *ctx = (jit_ctx*)malloc(sizeof(jit_ctx));
@@ -1121,7 +1135,7 @@ void hl_jit_free( jit_ctx *ctx ) {
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	int i, size = 0;
 	int codePos;
-	int nargs = m->code->globals[f->global]->nargs;
+	int nargs = m->code->globals[f->global]->fun->nargs;
 	preg p;
 	ctx->m = m;
 	ctx->f = f;
@@ -1228,17 +1242,20 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			op_binop(ctx, R(o->p1), R(o->p2), R(o->p3), o);
 			break;
 		case OGte:
+		case OLt:
 			op_cmp(ctx, o);
 			break;
 		case OJFalse:
+		case OJTrue:
 			{
 				preg *r = alloc_cpu(ctx, R(o->p1), true);
 				op32(ctx, AND, r, r);
-				XJump(JZero,jump);
+				XJump( o->op == OJFalse ? JZero : JNotZero,jump);
 				register_jump(ctx,jump,(i + 1) + o->p2);
 			}
 			break;
 		case OJLt:
+		case OJGte:
 			op_binop(ctx, NULL, R(o->p1), R(o->p2), o);
 			jump = do_jump(ctx,o->op);
 			register_jump(ctx,jump,(i + 1) + o->p3);
@@ -1246,13 +1263,8 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		case OToAny:
 			{
 				vreg *r = R(o->p2);
-				int size = pad_stack(ctx, IS_64 ? 0 : HL_WSIZE);
-#				ifdef HL_64
-					op64(ctx, MOV, REG_AT(CALL_REGS[0]), pconst64(&p, (int_val)r->t));
-#				else
-					op32(ctx, PUSH, pconst64(&p, (int_val)r->t), UNUSED);
-#				endif
-				call_native(ctx, hl_alloc_dynamic, size);
+				int_val rt = (int_val)r->t;
+				call_native_consts(ctx, hl_alloc_dynamic, &rt, 1);
 				// copy value to dynamic
 				if( IS_FLOAT(r) && !IS_64 ) {
 					preg *tmp = REG_AT(RCPU_SCRATCH_REGS[1]);
@@ -1285,6 +1297,15 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				store(ctx,r,r->current,false); 
 			}
 			break;
+		case ONew:
+			{
+				vreg *r = R(o->p1);
+				int_val args[2] = { (int_val)m, (int_val)r->t->obj }; 
+				if( r->t->kind != HOBJ ) ASSERT(r->t->kind);
+				call_native_consts(ctx, hl_alloc_obj, args, 2);
+				store(ctx, r, PEAX, true);
+			}
+			break;
 		default:
 			printf("Don't know how to jit %s\n",hl_op_name(o->op));
 			ASSERT(o->op);

+ 6 - 1
src/opcodes.h

@@ -63,7 +63,12 @@ OP_BEGIN
 	OP(OJNeq,3)
 	OP(OJAlways,1)
 	OP(OToAny,2)
-	OP(OLabel,0)
+	OP(OLabel,1)
+	OP(ONew,1)
+	OP(OField,3)
+	OP(OSetField,3)
+	OP(OGetThis,2)
+	OP(OSetThis,2)
 	// --
 	OP(OLast,0)
 OP_END