浏览代码

use faster allocator, jit to debug

Nicolas Cannasse 10 年之前
父节点
当前提交
ed03f2cf12
共有 7 个文件被更改,包括 301 次插入120 次删除
  1. 1 0
      .gitignore
  2. 20 68
      src/code.c
  3. 51 1
      src/global.c
  4. 45 2
      src/hl.h
  5. 135 9
      src/jit.c
  6. 45 40
      src/main.c
  7. 4 0
      src/module.c

+ 1 - 0
.gitignore

@@ -10,3 +10,4 @@
 *.filters
 
 *.user
+Release

+ 20 - 68
src/code.c

@@ -109,40 +109,6 @@ static int hl_read_uindex( hl_reader *r ) {
 	return i;
 }
 
-void hl_code_free( hl_code *c ) {
-	int i;
-	if( c == NULL ) return;
-	if( c->ints ) free(c->ints);
-	if( c->strings ) free(c->strings);
-	if( c->floats ) free(c->floats);
-	if( c->strings_data ) free(c->strings_data);
-	if( c->strings_lens ) free(c->strings_lens);
-	if( c->types ) {
-		for(i=0;i<c->ntypes;i++) {
-			hl_type *t = c->types + i;
-			if( t->args ) free(t->args);
-		}
-		free(c->types);
-	}
-	if( c->globals ) free(c->globals);
-	if( c->natives ) free(c->natives);
-	if( c->functions ) {
-		for(i=0;i<c->nfunctions;i++) {
-			hl_function *f = c->functions + i;
-			if( f->regs ) free(f->regs);
-			if( f->allocs ) {
-				int j;
-				for(j=0;j<f->nallocs;j++)
-					free(f->allocs[j]);
-				free(f->allocs);
-			}
-			if( f->ops ) free(f->ops);
-		}
-		free(c->functions);
-	}
-	free(c);
-}
-
 hl_type *hl_get_type( hl_reader *r ) {
 	int i = INDEX();
 	if( i < 0 || i >= r->code->ntypes ) {
@@ -180,7 +146,7 @@ void hl_read_type( hl_reader *r, hl_type *t ) {
 	switch( t->kind ) {
 	case HFUN:
 		t->nargs = READ();
-		t->args = (hl_type**)malloc(sizeof(hl_type*)*t->nargs);
+		t->args = (hl_type**)hl_malloc(&r->code->alloc, sizeof(hl_type*)*t->nargs);
 		if( t->args == NULL ) {
 			ERROR("Out of memory");
 			return;
@@ -194,29 +160,7 @@ void hl_read_type( hl_reader *r, hl_type *t ) {
 	}
 }
 
-void hl_op_alloc( hl_reader *r, hl_function *f, hl_opcode *o, void *data, int *maxAllocs ) {
-	if( f->nallocs == *maxAllocs ) {
-		void **nallocs;
-		int i;
-		int resize = ((*maxAllocs) * 3) >> 1;
-		if( resize == 0 ) resize = 4;
-		nallocs = (void**)malloc(sizeof(void*)*resize);
-		if( nallocs == NULL ) {
-			free(data);
-			r->error = "Out of memory";
-			return;
-		}
-		for(i=0;i<f->nallocs;i++)
-			nallocs[i] = f->allocs[i];
-		if( f->allocs ) free(f->allocs);
-		f->allocs = nallocs;
-		*maxAllocs = resize;
-	}
-	f->allocs[f->nallocs++] = data;
-	o->extra = data;
-}
-
-void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o, int *maxAllocs ) {
+void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 	o->op = (hl_op)READ();
 	if( o->op >= OLast ) {
 		ERROR("Invalid opcode");
@@ -251,10 +195,14 @@ void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o, int *maxAllocs
 				o->p1 = INDEX();
 				o->p2 = INDEX();
 				o->p3 = READ();
-				args = (int*)malloc(sizeof(int) * o->p3);
+				args = (int*)hl_malloc(&r->code->alloc,sizeof(int) * o->p3);
+				if( args == NULL ) {
+					ERROR("Out of memory");
+					return;
+				}
 				for(i=0;i<o->p3;i++)
 					args[i] = INDEX();
-				hl_op_alloc(r,f,o,args,maxAllocs);
+				o->extra = args;
 			}
 			break;
 		default:
@@ -266,11 +214,10 @@ void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o, int *maxAllocs
 
 void hl_read_function( hl_reader *r, hl_function *f ) {
 	int i;
-	int maxAlloc = 0;
 	f->index = UINDEX();
 	f->nregs = UINDEX();
 	f->nops = UINDEX();
-	f->regs = (hl_type**)malloc(f->nregs * sizeof(hl_type*));
+	f->regs = (hl_type**)hl_malloc(&r->code->alloc, f->nregs * sizeof(hl_type*));
 	if( f->regs == NULL ) {
 		ERROR("Out of memory");
 		return;
@@ -278,26 +225,31 @@ void hl_read_function( hl_reader *r, hl_function *f ) {
 	for(i=0;i<f->nregs;i++)
 		f->regs[i] = hl_get_type(r);
 	CHK_ERROR();
-	f->ops = (hl_opcode*)malloc(f->nops * sizeof(hl_opcode));
+	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, &maxAlloc);
+		hl_read_opcode(r, f, f->ops+i);
 }
 
 #undef CHK_ERROR
-#define CHK_ERROR() if( r->error ) { hl_code_free(c); printf("%s\n", r->error); return NULL; }
+#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 *)malloc(count*sizeof(ptr)); if( v == NULL ) EXIT("Out of memory") else memset(v, 0, count*sizeof(ptr)); }
+#define ALLOC(v,ptr,count) { v = (ptr *)hl_zalloc(&c->alloc,count*sizeof(ptr)); if( v == NULL ) EXIT("Out of memory"); }
 
 hl_code *hl_code_read( const unsigned char *data, int size ) {
 	hl_reader _r = { data, size, 0, 0, NULL };	
 	hl_reader *r = &_r;
 	hl_code *c;
+	hl_alloc alloc;
 	int i;
-	ALLOC(c, hl_code, 1);
+	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");
 	r->code = c;
@@ -327,7 +279,7 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 		int size = hl_read_i32(r);
 		char *sdata;
 		CHK_ERROR();
-		sdata = (char*)malloc(sizeof(char) * size);
+		sdata = (char*)hl_malloc(&c->alloc,sizeof(char) * size);
 		if( sdata == NULL )
 			EXIT("Out of memory");
 		hl_read_bytes(r, sdata, size);

+ 51 - 1
src/global.c

@@ -40,4 +40,54 @@ int hl_type_size( hl_type *t ) {
 		PTR,
 	};
 	return SIZES[t->kind];
-}
+}
+
+struct hl_alloc_block {
+	int size;
+	hl_alloc_block *next;
+	unsigned char *p;
+};
+
+void hl_alloc_init( hl_alloc *a ) {
+	a->cur = NULL;
+}
+
+void *hl_malloc( hl_alloc *a, int size ) {
+	hl_alloc_block *b = a->cur;
+	void *p;
+	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;
+		b->p = ((unsigned char*)b) + sizeof(hl_alloc_block);
+		b->size = alloc;
+		b->next = a->cur;
+		a->cur = b;
+	}
+	p = b->p;
+	b->p += size;
+	b->size -= size;
+	return p;
+}
+
+void *hl_zalloc( hl_alloc *a, int size ) {
+	void *p = hl_malloc(a,size);
+	if( p ) memset(p,0,size);
+	return p;
+}
+
+void hl_free( hl_alloc *a ) {
+	hl_alloc_block *b = a->cur;
+	int_val prev = 0;
+	int size = 0;
+	while( b ) {
+		hl_alloc_block *n = b->next;
+		size = b->p + b->size - ((unsigned char*)b);
+		prev = (int_val)b;
+		free(b);
+		b = n;
+	}
+	// check if our allocator was not part of the last free block
+	if( (int_val)a < prev || (int_val)a > prev+size )
+		a->cur = NULL;
+}

+ 45 - 2
src/hl.h

@@ -22,6 +22,40 @@
 #ifndef HL_H
 #define HL_H
 
+#if defined(__APPLE__) || defined(__MACH__) || defined(macintosh)
+#	define HL_MAC
+#endif
+
+#if defined(linux) || defined(__linux__)
+#	define HL_LINUX
+#endif
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#	define HL_BSD
+#endif
+
+#if defined(_64BITS) || defined(__x86_64__)
+#	define HL64
+#endif
+
+#if defined(__GNUC__)
+#	define NEKO_GCC
+#endif
+
+#if defined(_MSC_VER)
+#	define HL_VCC
+// remove deprecated C API usage warnings
+#	pragma warning( disable : 4996 )
+#endif
+
+#include <stddef.h>
+#ifndef HL_VCC
+#	include <stdint.h>
+#endif
+
+
+typedef intptr_t int_val;
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <memory.h>
@@ -29,6 +63,9 @@
 #define HL_VERSION	010
 #include "opcodes.h"
 
+typedef struct hl_alloc_block hl_alloc_block;
+typedef struct { hl_alloc_block *cur; } hl_alloc;
+
 typedef enum {
 	HVOID	= 0,
 	HUI8	= 1,
@@ -70,10 +107,8 @@ typedef struct {
 	int index;
 	int nregs;
 	int nops;
-	int nallocs;
 	hl_type **regs;
 	hl_opcode *ops;
-	void **allocs;
 } hl_function;
 
 typedef struct {
@@ -95,6 +130,7 @@ typedef struct {
 	hl_type**	globals;
 	hl_native*	natives;
 	hl_function*functions;
+	hl_alloc	alloc;
 } hl_code;
 
 typedef struct {
@@ -102,10 +138,16 @@ typedef struct {
 	int *globals_indexes;
 	unsigned char *globals_data;
 	void **functions_ptrs;
+	void *jit_code;
 } hl_module;
 
 typedef struct jit_ctx jit_ctx;
 
+void hl_alloc_init( hl_alloc *a );
+void *hl_malloc( hl_alloc *a, int size );
+void *hl_zalloc( hl_alloc *a, int size );
+void hl_free( hl_alloc *a );
+
 void hl_global_init();
 void hl_global_free();
 
@@ -120,5 +162,6 @@ void hl_module_free( hl_module *m );
 jit_ctx *hl_jit_alloc();
 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 );
 
 #endif

+ 135 - 9
src/jit.c

@@ -34,6 +34,8 @@
 #define JGte		0x83
 #define JEq			0x84
 #define JNeq		0x85
+#define JZero		JEq
+#define JNotZero	JNeq
 #define JLte		0x86
 #define JGt			0x87
 #define JSignLt		0x8C
@@ -67,23 +69,45 @@
 #define XCall_d(delta)			B(0xE8); W(delta)
 #define XPush_r(r)				B(0x50+(r))
 #define XPush_c(cst)			B(0x68); W(cst)
+//XPush_p
 #define XPush_p(reg,idx)		OP_ADDR(0xFF,idx,reg,6)
 #define XAdd_rc(reg,cst)		if IS_SBYTE(cst) { OP_RM(0x83,3,0,reg); B(cst); } else { OP_RM(0x81,3,0,reg); W(cst); }
 #define XAdd_rr(dst,src)		OP_RM(0x03,3,dst,src)
+//XAdd_rp
+//XAdd_pr
+//XAdd_pc
 #define XSub_rc(reg,cst)		if IS_SBYTE(cst) { OP_RM(0x83,3,5,reg); B(cst); } else { OP_RM(0x81,3,5,reg); W(cst); }
 #define XSub_rr(dst,src)		OP_RM(0x2B,3,dst,src)
+//XSub_rp
+//XSub_pr
+//XSub_pc
 #define XCmp_rr(r1,r2)			OP_RM(0x3B,3,r1,r2)
 #define XCmp_rc(reg,cst)		if( reg == Eax ) { B(0x3D); } else { OP_RM(0x81,3,7,reg); }; W(cst)
 #define XCmp_rb(reg,byte)		OP_RM(0x83,3,7,reg); B(byte)
-#define XJump(how,local)		if( (how) == JAlways ) { B(0xE9); } else { B(0x0F); B(how); }; local = buf.i; W(0)
-#define XJump_near(local)		B(0xEB); local = buf.c; B(0)
+#define XJump(how,local)		if( (how) == JAlways ) { B(0xE9); } else { B(0x0F); B(how); }; local = ctx->buf.i; W(0)
+#define XJump_near(local)		B(0xEB); local = ctx->buf.c; B(0)
 #define XJump_r(reg)			OP_RM(0xFF,3,4,reg)
 #define XPop_r(reg)				B(0x58 + (reg))
+//XPop_p
+//XInc_r
+//XInc_p
+//XDec_r
+//XDec_p
+
+//XLea_rp
+//XNot_r
+//XNot_p
+//XNeg_r
+//XNeg_p
 
 #define XTest_rc(r,cst)			if( r == Eax ) { B(0xA9); W(cst); } else { B(0xF7); MOD_RM(3,0,r); W(cst); }
 #define XTest_rr(r,src)			B(0x85); MOD_RM(3,r,src)
 #define XAnd_rc(r,cst)			if( r == Eax ) { B(0x25); W(cst); } else { B(0x81); MOD_RM(3,4,r); W(cst); }
 #define XAnd_rr(r,src)			B(0x23); MOD_RM(3,r,src)
+//XAnd_rp
+//XAnd_rc
+//XAnd_pr
+//XAnd_pc
 #define XOr_rc(r,cst)			if( r == Eax ) { B(0x0D); W(cst); } else { B(0x81); MOD_RM(3,1,r); W(cst); }
 #define XOr_rr(r,src)			B(0x0B); MOD_RM(3,r,src)
 #define XXor_rc(r,cst)			if( r == Eax ) { B(0x35); W(cst); } else { B(0x81); MOD_RM(3,6,r); W(cst); }
@@ -94,13 +118,22 @@
 
 #define XShl_rr(r,src)			if( src != Ecx ) ERROR; shift_r(r,4)
 #define XShl_rc(r,n)			shift_c(r,n,4)
+//XShl_pr
+//XShl_pc
 #define XShr_rr(r,src)			if( src != Ecx ) ERROR; shift_r(r,7)
 #define XShr_rc(r,n)			shift_c(r,n,7)
 #define XUShr_rr(r,src)			if( src != Ecx ) ERROR; shift_r(r,5)
 #define XUShr_rc(r,n)			shift_c(r,n,5)
 
+//XMul (unsigned)
+//
+
 #define XIMul_rr(dst,src)		B(0x0F); B(0xAF); MOD_RM(3,dst,src)
+//XIMul_rp
+//XIMul_rrc
+//XIMul_rpc
 #define XIDiv_r(r)				B(0xF7); MOD_RM(3,7,r)
+//XIDiv_p
 #define XCdq()					B(0x99);
 
 // FPU
@@ -119,19 +152,31 @@
 #define LOAD(cpuReg,vReg)		XMov_rp(cpuReg,Ebp,-ctx->regsPos[vReg])
 #define STORE(vReg, cpuReg)		XMov_pr(Ebp,-ctx->regsPos[vReg],cpuReg)
 
+typedef struct jlist jlist;
+struct jlist {
+	int pos;
+	int target;
+	jlist *next;
+};
+
 struct jit_ctx {
 	union {
 		unsigned char *b;
 		unsigned int *w;
+		int *i;
 	} buf;
 	int *regsPos;
 	int *regsSize;
+	int *opsPos;
 	int maxRegs;
+	int maxOps;
 	unsigned char *startBuf;
 	int bufSize;
 	int totalRegsSize;
 	hl_module *m;
 	hl_function *f;
+	jlist *jumps;
+	hl_alloc alloc;
 };
 
 static void jit_buf( jit_ctx *ctx ) {
@@ -178,6 +223,7 @@ static void op_callr( jit_ctx *ctx, int r, int rf, int size ) {
 }
 
 static void op_enter( jit_ctx *ctx ) {
+	XRet();
 	XPush_r(Ebp);
 	XMov_rr(Ebp, Esp);
 	XAdd_rc(Esp, ctx->totalRegsSize);
@@ -192,28 +238,76 @@ static void op_ret( jit_ctx *ctx, int r ) {
 
 static void op_sub( jit_ctx *ctx, int r, int a, int b ) {
 	LOAD(Eax, a);
-	LOAD(Ebx, b);
-	XSub_rr(Eax, Ebx);
+	LOAD(Ecx, b);
+	XSub_rr(Eax, Ecx);
 	STORE(r, Eax);
 }
 
 static void op_add( jit_ctx *ctx, int r, int a, int b ) {
 	LOAD(Eax, a);
-	LOAD(Ebx, b);
-	XAdd_rr(Eax, Ebx);
+	LOAD(Ecx, b);
+	XAdd_rr(Eax, Ecx);
 	STORE(r, Eax);
 }
 
+static int *do_jump( jit_ctx *ctx, hl_op op ) {
+	int *j;
+	switch( op ) {
+	case OJAlways:
+		XJump(JAlways,j);
+		break;
+	case OGte:
+		XJump(JGte,j);
+		break;
+	default:
+		j = NULL;
+		printf("Unknown JUMP %d\n",op);
+		break;
+	}
+	return j;
+}
+
+static void patch_jump( jit_ctx *ctx, int *p ) {
+	if( p == NULL ) return;
+	*p = (int)((int_val)ctx->buf.b - ((int_val)p + 1)) - 3;
+}
+
+static void op_cmp( jit_ctx *ctx, hl_opcode *op ) {
+	int *p,*e;
+	LOAD(Eax, op->p2);
+	LOAD(Ecx, op->p3);
+	XCmp_rr(Eax, Ecx);
+	p = do_jump(ctx,op->op);
+	XMov_pc(Ebp,-ctx->regsPos[op->p1],0);
+	e = do_jump(ctx,OJAlways);
+	XMov_pc(Ebp,-ctx->regsPos[op->p1],1);
+	patch_jump(ctx,p);
+	patch_jump(ctx,e);
+}
+
+static void register_jump( jit_ctx *ctx, int *p, int target ) {
+	int pos = (int_val)p - (int_val)ctx->startBuf; 
+	jlist *j = (jlist*)hl_malloc(&ctx->alloc, sizeof(jlist));
+	j->pos = pos;
+	j->target = target;
+	j->next = ctx->jumps;
+	ctx->jumps = j;
+}
+
 jit_ctx *hl_jit_alloc() {
 	jit_ctx *ctx = (jit_ctx*)malloc(sizeof(jit_ctx));
 	if( ctx == NULL ) return NULL;
 	memset(ctx,0,sizeof(jit_ctx));
+	hl_alloc_init(&ctx->alloc);
 	return ctx;
 }
 
 void hl_jit_free( jit_ctx *ctx ) {
 	free(ctx->regsPos);
+	free(ctx->regsSize);
+	free(ctx->opsPos);
 	free(ctx->startBuf);
+	hl_free(&ctx->alloc);
 	free(ctx);
 }
 
@@ -233,6 +327,15 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		}
 		ctx->maxRegs = f->nregs;
 	}
+	if( f->nops >= ctx->maxOps ) {
+		free(ctx->opsPos);
+		ctx->opsPos = (int*)malloc(sizeof(int) * (f->nops + 1));
+		if( ctx->opsPos == NULL ) {
+			ctx->maxOps = 0;
+			return -1;
+		}
+		ctx->maxOps = f->nops;
+	}
 	for(i=0;i<f->nregs;i++) {
 		int sz = hl_type_size(f->regs[i]);
 		ctx->regsSize[i] = sz;
@@ -242,7 +345,9 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	ctx->totalRegsSize = size;
 	jit_buf(ctx);
 	op_enter(ctx);
+	ctx->opsPos[0] = 0;
 	for(i=0;i<f->nops;i++) {
+		int *jump;
 		hl_opcode *o = f->ops + i;
 		jit_buf(ctx);
 		switch( o->op ) {
@@ -274,10 +379,13 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			op_add(ctx, o->p1, o->p2, o->p3);
 			break;
 		case OGte:
-			TODO();
+			op_cmp(ctx, o);
 			break;
 		case OJFalse:
-			TODO();
+			LOAD(Eax,o->p1);
+			XTest_rr(Eax,Eax);
+			XJump(JZero,jump);
+			register_jump(ctx,jump,(i + 1) + o->p2);
 			break;
 		case OJToAny:
 			// NOP
@@ -289,8 +397,26 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			printf("Don't know how to jit op #%d\n",o->op);
 			return -1;
 		}
+		ctx->opsPos[i+1] = ctx->buf.b - ctx->startBuf;
+	}
+	// patch jumps
+	{
+		jlist *j = ctx->jumps;
+		while( j ) {
+			*(int*)(ctx->startBuf + j->pos) = ctx->opsPos[j->target] - j->pos;
+			j = j->next;
+		}
+		ctx->jumps = NULL;
 	}
+	// reset tmp allocator
+	hl_free(&ctx->alloc);
 	return codePos;
 }
 
-
+void *hl_jit_code( jit_ctx *ctx ) {
+	int size = ctx->buf.b - ctx->startBuf;
+	void *code = malloc(size);
+	if( code == NULL ) return NULL;
+	memcpy(code,ctx->startBuf,size);
+	return code;
+}

+ 45 - 40
src/main.c

@@ -1,43 +1,44 @@
-/*
- * Copyright (C)2015 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#define _CRT_SECURE_NO_WARNINGS
+/*
+ * Copyright (C)2015 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
 #include "hl.h"
 
-int main( int argc, char *argv[] ) {
-	if( argc == 1 ) {
-		printf("HLVM %d.%d.%d (c)2015 Haxe Foundation\n  Usage : hl <file>\n",HL_VERSION/100,(HL_VERSION/10)%10,HL_VERSION%10);
-		return 1;
-	}
-	hl_global_init();
+typedef void (_cdecl *fptr)();
+
+int main( int argc, char *argv[] ) {
+	if( argc == 1 ) {
+		printf("HLVM %d.%d.%d (c)2015 Haxe Foundation\n  Usage : hl <file>\n",HL_VERSION/100,(HL_VERSION/10)%10,HL_VERSION%10);
+		return 1;
+	}
+	hl_global_init();
 	{
-		hl_code *code;
-		hl_module *m;
-		const char *file = argv[1];
+		hl_code *code;
+		hl_module *m;
+		const char *file = argv[1];
 		FILE *f = fopen(file,"rb");
 		int pos, size;
 		char *fdata;
 		if( f == NULL ) {
 			printf("File not found '%s'\n",file);
-			return -1;
+			return 1;
 		}
 		fseek(f, 0, SEEK_END);
 		size = (int)ftell(f);
@@ -48,19 +49,23 @@ int main( int argc, char *argv[] ) {
 			int r = (int)fread(fdata + pos, 1, size-pos, f);
 			if( r <= 0 ) {
 				printf("Failed to read '%s'\n",file);
-				return -1;
+				return 2;
 			}
 			pos += r;
 		}
 		fclose(f);
 		code = hl_code_read((unsigned char*)fdata, size);
 		if( code == NULL )
-			return -1;
+			return 3;
 		m = hl_module_alloc(code);
 		if( m == NULL )
-			return -1;
-		hl_code_free(code);
-	}
-	hl_global_free();
-	return 0;
-}
+			return 4;
+		
+		((fptr)m->functions_ptrs[m->code->entrypoint])();
+
+		hl_module_free(m);
+		hl_free(&code->alloc);
+	}
+	hl_global_free();
+	return 0;
+}

+ 4 - 0
src/module.c

@@ -65,6 +65,10 @@ hl_module *hl_module_alloc( hl_code *c ) {
 			}
 			m->functions_ptrs[i] = (void*)f;
 		}
+		m->jit_code = hl_jit_code(ctx);
+		for(i=0;i<c->nfunctions;i++)
+			m->functions_ptrs[i] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[i]);
+		hl_jit_free(ctx);
 	}
 	return m;
 }