浏览代码

make sure jit null access and assert always push stack pointer whatever the compiler optimizations

ncannasse 7 年之前
父节点
当前提交
04ba68145d
共有 1 个文件被更改,包括 49 次插入16 次删除
  1. 49 16
      src/jit.c

+ 49 - 16
src/jit.c

@@ -293,6 +293,7 @@ struct jit_ctx {
 	int c2hl;
 	int hl2c;
 	int longjump;
+	int static_functions[8];
 };
 
 #define jit_exit() { hl_debug_break(); exit(-1); }
@@ -1446,18 +1447,6 @@ static int prepare_call_args( jit_ctx *ctx, int count, int *args, vreg *vregs, i
 	return paddedSize;
 }
 
-#ifdef HL_VCC
-#	pragma optimize( "", off )
-#endif
-HL_NO_OPT static void hl_null_access() {
-	vdynamic *d = hl_alloc_dynamic(&hlt_bytes);
-	d->v.ptr = USTR("Null access");
-	hl_throw(d);
-}
-#ifdef HL_VCC
-#	pragma optimize( "", on )
-#endif
-
 static void op_call( jit_ctx *ctx, preg *r, int size ) {
 	preg p;
 #	ifdef JIT_DEBUG
@@ -1479,7 +1468,7 @@ static void op_call( jit_ctx *ctx, preg *r, int size ) {
 }
 
 static void call_native( jit_ctx *ctx, void *nativeFun, int size ) {
-	bool isExc = nativeFun == hl_null_access || nativeFun == hl_assert || nativeFun == hl_throw || nativeFun == on_jit_error;
+	bool isExc = nativeFun == hl_assert || nativeFun == hl_throw || nativeFun == on_jit_error;
 	preg p;
 	// native function, already resolved
 	op64(ctx,MOV,PEAX,pconst64(&p,(int_val)nativeFun));
@@ -2572,6 +2561,30 @@ static void jit_longjump( jit_ctx *ctx ) {
 }
 #endif
 
+static void jit_fail( uchar *msg ) {
+	if( msg == NULL ) {
+		hl_debug_break();
+		msg = USTR("assert");
+	}
+	vdynamic *d = hl_alloc_dynamic(&hlt_bytes);
+	d->v.ptr = msg;
+	hl_throw(d);
+}
+
+static void jit_null_access( jit_ctx *ctx ) {
+	op64(ctx,PUSH,PEBP,UNUSED);
+	op64(ctx,MOV,PEBP,PESP);
+	int_val arg = (int_val)USTR("Null access");
+	call_native_consts(ctx, jit_fail, &arg, 1);
+}
+
+static void jit_assert( jit_ctx *ctx ) {
+	op64(ctx,PUSH,PEBP,UNUSED);
+	op64(ctx,MOV,PEBP,PESP);
+	int_val arg = 0;
+	call_native_consts(ctx, jit_fail, &arg, 1);
+}
+
 static int jit_build( jit_ctx *ctx, void (*fbuild)( jit_ctx *) ) {
 	int pos;
 	jit_buf(ctx);
@@ -2596,6 +2609,8 @@ void hl_jit_init( jit_ctx *ctx, hl_module *m ) {
 #	ifdef JIT_CUSTOM_LONGJUMP
 	ctx->longjump = jit_build(ctx, jit_longjump);
 #	endif
+	ctx->static_functions[0] = jit_build(ctx,jit_null_access);
+	ctx->static_functions[1] = jit_build(ctx,jit_assert);
 }
 
 static void *get_dyncast( hl_type *t ) {
@@ -3724,7 +3739,16 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				preg *r = alloc_cpu(ctx,dst,true);
 				op64(ctx,TEST,r,r);
 				XJump_small(JNotZero,jz);
-				call_native_consts(ctx,hl_null_access,NULL,0);
+				pad_before_call(ctx, 0);
+
+				jlist *j = (jlist*)hl_malloc(&ctx->galloc,sizeof(jlist));
+				j->pos = BUF_POS();
+				j->target = -1;
+				j->next = ctx->calls;
+				ctx->calls = j;
+
+				op64(ctx,MOV,PEAX,pconst64(&p,RESERVE_ADDRESS));
+				op_call(ctx,PEAX,-1);
 				patch_jump(ctx,jz);
 			}
 			break;
@@ -3982,7 +4006,16 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			store(ctx,dst,dst->current,false);
 			break;
 		case OAssert:
-			call_native(ctx, hl_assert, 0);
+			{
+				jlist *j = (jlist*)hl_malloc(&ctx->galloc,sizeof(jlist));
+				j->pos = BUF_POS();
+				j->target = -1;
+				j->next = ctx->calls;
+				ctx->calls = j;
+
+				op64(ctx,MOV,PEAX,pconst64(&p,RESERVE_ADDRESS));
+				op_call(ctx,PEAX,-2);
+			}
 			break;
 		case ONop:
 			break;
@@ -4056,7 +4089,7 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, hl_debug_infos **d
 	// patch calls
 	c = ctx->calls;
 	while( c ) {
-		int fpos = (int)(int_val)m->functions_ptrs[c->target];
+		int fpos = c->target < 0 ? ctx->static_functions[-c->target-1] : (int)(int_val)m->functions_ptrs[c->target];
 		if( (code[c->pos]&~3) == (IS_64?0x48:0xB8) || code[c->pos] == 0x68 ) // MOV : absolute | PUSH
 			*(int_val*)(code + c->pos + (IS_64?2:1)) = (int_val)(code + fpos);
 		else