Selaa lähdekoodia

partial handle for wrapper callbacks, OEnumAlloc, OSetEnumField, OInstanceClosure, fixed JTrue/JFalse

Nicolas Cannasse 9 vuotta sitten
vanhempi
commit
22db3047f5
8 muutettua tiedostoa jossa 164 lisäystä ja 53 poistoa
  1. 1 0
      src/alloc.c
  2. 93 27
      src/callback.c
  3. 1 0
      src/hl.h
  4. 0 1
      src/hlmodule.h
  5. 65 14
      src/jit.c
  6. 2 2
      src/main.c
  7. 1 9
      src/module.c
  8. 1 0
      src/std/error.c

+ 1 - 0
src/alloc.c

@@ -461,6 +461,7 @@ void *hl_gc_alloc_gen( int size, int flags ) {
 	memset(ptr,0xCD,size);
 #	endif
 #endif
+	if( flags & MEM_ZERO ) memset(ptr,0,size);
 	return ptr;
 }
 

+ 93 - 27
src/callback.c

@@ -25,61 +25,127 @@
 
 static void *hl_callback_entry = NULL;
 
-void hl_callback_init( void *e ) {
-	hl_callback_entry = e;
-}
-
-void *hl_callback( void *f, int nargs, vdynamic **args ) {
+void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret ) {
 	union {
-		unsigned char b[MAX_ARGS * HL_WSIZE];
+		unsigned char b[MAX_ARGS * 8];
+		unsigned short s[MAX_ARGS * 4];
+		int i[MAX_ARGS * 2];
 		double d[MAX_ARGS];
-		int i[MAX_ARGS];
-		int_val i64[MAX_ARGS];
-	} stack;
+		void *p[MAX_ARGS * 8 / HL_WSIZE];
+	} stack;	
 	/*
 		Same as jit(prepare_call_args) but writes values to the stack var
 	*/
 	int i, size = 0, pad = 0, pos = 0;
-	for(i=0;i<nargs;i++) {
-		vdynamic *d = args[i];
-		hl_type *dt = d->t;
-		size += hl_pad_size(size,dt);
-		size += hl_type_size(dt);
+	for(i=0;i<t->fun->nargs;i++) {
+		hl_type *at = t->fun->args[i];
+		size += hl_pad_size(size,at);
+		size += hl_type_size(at);
 	}
 	if( size & 15 )
 		pad = 16 - (size&15);
 	size = pos = pad;
-	for(i=0;i<nargs;i++) {
+	for(i=0;i<t->fun->nargs;i++) {
 		// RTL
-		vdynamic *d = args[i];
-		hl_type *dt = d->t;
+		hl_type *at = t->fun->args[i];
+		void *v = args[i];
 		int pad;
-		int tsize = hl_type_size(dt);
+		int tsize = hl_type_size(at);
 		size += tsize;
-		pad = hl_pad_size(size,dt);
+		pad = hl_pad_size(size,at);
 		if( pad ) {
 			pos += pad;
 			size += pad;
 		}
-		switch( tsize ) {
+		if( hl_is_ptr(at) )
+			stack.p[pos/HL_WSIZE] = v;
+		else switch( tsize ) {
 		case 0:
 			continue;
 		case 1:
-			stack.b[pos] = d->v.b;
+			stack.b[pos] = *(char*)v;
+			break;
+		case 2:
+			stack.s[pos>>1] = *(short*)v;
 			break;
 		case 4:
-			stack.i[pos>>2] = (IS_64 && dt->kind == HI32) ? d->v.i : (int)(int_val)d;
+			stack.i[pos>>2] = *(int*)v;
 			break;
 		case 8:
-			if( !IS_64 || dt->kind == HF64 ) 
-				stack.d[pos>>3] = d->v.d;
-			else
-				stack.i64[pos>>3] = (int_val)d;
+			stack.d[pos>>3] = *(double*)v;
 			break;
 		default:
 			hl_error("Invalid callback arg");
 		}
 		pos += tsize;
 	}
-	return ((void *(*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+	switch( t->fun->ret->kind ) {
+	case HI8:
+	case HI16:
+	case HI32:
+		ret->v.i = ((int (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		return &ret->v.i;
+	case HF32:
+		ret->v.f = ((float (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		return &ret->v.f;
+	case HF64:
+		ret->v.d = ((double (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		return &ret->v.d;
+	default:
+		return ((void *(*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+	}
+}
+
+static void *hl_call_wrapper_ptr( vclosure_wrapper *c ) {
+	hl_debug_break();
+	return NULL;
+}
+
+static void *hl_call_wrapper_all_ptr( vclosure_wrapper *c ) {
+	return hl_wrapper_call(c,&c + 1, NULL);
+}
+
+static void *hl_get_wrapper( hl_type *t ) {
+#	ifndef HL_64
+	int i;
+	for(i=0;i<t->fun->nargs;i++)
+		if( !hl_is_ptr(t->fun->args[i]) )
+			break;
+	if( i == t->fun->nargs ) {
+		switch( t->fun->ret->kind ) {
+		case HF32:
+		case HF64:
+			hl_error("TODO");
+			break;
+		case HI8:
+		case HI16:
+		case HI32:
+			hl_error("TODO");
+			break;			
+		default:
+			return hl_call_wrapper_all_ptr;
+		}
+	} else 
+#	endif
+	{
+		switch( t->fun->ret->kind ) {
+		case HF32:
+		case HF64:
+			hl_error("TODO");
+			break;
+		case HI8:
+		case HI16:
+		case HI32:
+			hl_error("TODO");
+			break;			
+		default:
+			return hl_call_wrapper_ptr;
+		}
+	}
+	return NULL;
+}
+
+void hl_callback_init( void *e ) {
+	hl_callback_entry = e;
+	hl_setup_callbacks(hl_callback, hl_get_wrapper);
 }

+ 1 - 0
src/hl.h

@@ -483,6 +483,7 @@ HL_API void *hl_wrapper_call( void *value, void **args, vdynamic *ret );
 #define MEM_KIND_NOPTR		2
 #define MEM_KIND_FINALIZER	3
 #define MEM_ALIGN_DOUBLE	128
+#define MEM_ZERO			256
 
 HL_API void *hl_gc_alloc_gen( int size, int flags );
 HL_API void hl_add_root( void **ptr );

+ 0 - 1
src/hlmodule.h

@@ -97,7 +97,6 @@ jit_ctx *hl_jit_alloc();
 void hl_jit_free( jit_ctx *ctx );
 void hl_jit_init( jit_ctx *ctx, hl_module *m );
 int hl_jit_init_callback( jit_ctx *ctx );
-int hl_jit_init_get_wrapper( 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, int *codesize );
 

+ 65 - 14
src/jit.c

@@ -86,6 +86,7 @@ typedef enum {
 	CVTPD2PS,
 	// 8 bits
 	MOV8,
+	TEST8,
 	// --
 	_CPU_LAST
 } CpuOp;
@@ -371,6 +372,7 @@ static opform OP_FORMS[_CPU_LAST] = {
 	{ "CVTPD2PS", 0x660F5A },
 	// 8 bits,
 	{ "MOV8", 0x8A, 0x88, 0, 0xB0, RM(0xC6,0) },
+	{ "TEST8", 0x84, 0x84, RM(0xF6,0) },
 };
 
 #ifdef OP_LOG
@@ -1589,18 +1591,6 @@ int hl_jit_init_callback( jit_ctx *ctx ) {
 	return pos;
 }
 
-int hl_jit_init_get_wrapper( jit_ctx *ctx ) {
-	int pos = BUF_POS();
-	jit_buf(ctx);
-	
-	BREAK();
-	jit_buf(ctx);
-	while( BUF_POS() & 15 )
-		op32(ctx, NOP, UNUSED, UNUSED);
-
-	return pos;
-}
-
 static void *get_dyncast( hl_type *t ) {
 	switch( t->kind ) {
 	case HF32:
@@ -1813,7 +1803,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		case OJNull:
 			{
 				preg *r = alloc_cpu(ctx, dst, true);
-				op32(ctx, TEST, r, r);
+				op32(ctx, dst->t->kind == HBOOL ? TEST8 : TEST, r, r);
 				XJump( o->op == OJFalse || o->op == OJNull ? JZero : JNotZero,jump);
 				register_jump(ctx,jump,(opCount + 1) + o->p2);
 			}
@@ -1976,6 +1966,30 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				store(ctx, dst, PEAX, true);
 			}
 			break;
+		case OInstanceClosure:
+			{
+#				ifdef HL_64
+				jit_error("TODO");
+#				else
+				preg *r = alloc_cpu(ctx, rb, true);
+				jlist *j = (jlist*)hl_malloc(&ctx->galloc,sizeof(jlist));
+				size = pad_stack(ctx,HL_WSIZE*3);
+				op64(ctx,PUSH,r,UNUSED);
+
+				j->pos = BUF_POS();
+				j->target = o->p2;
+				j->next = ctx->calls;
+				ctx->calls = j;
+
+				op64(ctx,MOV,r,pconst64(&p,0));
+				op64(ctx,PUSH,r,UNUSED);
+				op64(ctx,MOV,r,pconst64(&p,(int_val)m->code->functions[m->functions_indexes[o->p2]].type));
+				op64(ctx,PUSH,r,UNUSED);
+				call_native(ctx,hl_alloc_closure_ptr,size);
+				store(ctx,dst,PEAX,true);
+#				endif
+			}
+			break;
 		case OCallClosure:
 			if( ra->t->kind == HDYN ) {
 				jit_error("TODO");
@@ -2276,6 +2290,40 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				}
 			}
 			break;
+		case OEnumAlloc:
+			{
+				hl_enum_construct *c = &dst->t->tenum->constructs[o->p2];
+				int_val args[] = { c->size, (c->hasptr?MEM_KIND_RAW:MEM_KIND_NOPTR) | MEM_ZERO };
+				call_native_consts(ctx, hl_gc_alloc_gen, args, 2);
+				store(ctx, dst, PEAX, true);
+				op32(ctx,MOV,REG_AT(Ecx),pconst(&p,o->p2));
+				op32(ctx,MOV,pmem(&p,Eax,0),REG_AT(Ecx));
+			}
+			break;
+		case OSetEnumField:
+			{
+				hl_enum_construct *c = &dst->t->tenum->constructs[0];
+				int i;
+				int pos = sizeof(int);
+				preg *r = alloc_cpu(ctx,dst,true);
+				for(i=0;i<o->p2;i++) {
+					hl_type *t = c->params[i];
+					pos += hl_pad_size(pos,t);
+					pos += hl_type_size(t);
+				}
+				switch( rb->t->kind ) {
+				case HF64:
+					{
+						preg *d = alloc_fpu(ctx,rb,true);
+						copy(ctx,pmem(&p,r->id,pos),d,8);
+						break;
+					}
+				default:
+					copy(ctx,pmem(&p,r->id,pos),alloc_cpu(ctx,rb,true),hl_type_size(c->params[o->p2]));
+					break;
+				}
+			}
+			break;
 		case ONullCheck:
 			{
 				int jz;
@@ -2508,7 +2556,10 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize ) {
 	c = ctx->calls;
 	while( c ) {
 		int fpos = (int)(int_val)m->functions_ptrs[c->target];
-		*(int*)(code + c->pos + 1) = fpos - (c->pos + 5);
+		if( code[c->pos] == 0xB8 ) // MOV : absolute
+			*(int_val*)(code + c->pos + 1) = (int_val)(code + fpos);
+		else
+			*(int*)(code + c->pos + 1) = fpos - (c->pos + 5);
 		c = c->next;
 	}
 	// patch switchs

+ 2 - 2
src/main.c

@@ -39,7 +39,7 @@ typedef char pchar;
 #define pfopen fopen
 #endif
 
-extern void *hl_callback( void *f, int nargs, vdynamic **args );
+extern void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret );
 
 static hl_code *load_code( const pchar *file ) {
 	hl_code *code;
@@ -99,7 +99,7 @@ int main(int argc, char *argv[]) {
 	if( !hl_module_init(ctx.m) )
 		return 3;
 	hl_trap(trap, ctx.exc, on_exception);
-	hl_callback(ctx.m->functions_ptrs[ctx.m->code->entrypoint],0,NULL);
+	hl_callback(ctx.m->functions_ptrs[ctx.m->code->entrypoint],ctx.code->functions[ctx.m->functions_indexes[ctx.m->code->entrypoint]].type,NULL,NULL);
 	hl_module_free(ctx.m);
 	hl_free(&ctx.code->alloc);
 	hl_global_free();

+ 1 - 9
src/module.c

@@ -123,13 +123,8 @@ static void append_type( char **p, hl_type *t ) {
 	}
 }
 
-static void *module_wrapper_func;
-static void *module_get_wrapper( hl_type * t ) {
-	return module_wrapper_func;
-}
-
 int hl_module_init( hl_module *m ) {
-	int i, entry, wrapper;
+	int i, entry;
 	jit_ctx *ctx;
 	// RESET globals
 	for(i=0;i<m->code->nglobals;i++) {
@@ -204,7 +199,6 @@ int hl_module_init( hl_module *m ) {
 		return 0;
 	hl_jit_init(ctx, m);
 	entry = hl_jit_init_callback(ctx);
-	wrapper = hl_jit_init_get_wrapper(ctx);
 	for(i=0;i<m->code->nfunctions;i++) {
 		hl_function *f = m->code->functions + i;
 		int fpos = hl_jit_function(ctx, m, f);
@@ -219,9 +213,7 @@ int hl_module_init( hl_module *m ) {
 		hl_function *f = m->code->functions + i;
 		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);
 	}
-	module_wrapper_func = ((unsigned char*)m->jit_code) + wrapper;
 	hl_callback_init(((unsigned char*)m->jit_code) + entry);
-	hl_setup_callbacks(NULL, module_get_wrapper);
 	hl_jit_free(ctx);
 	return 1;
 }

+ 1 - 0
src/std/error.c

@@ -91,6 +91,7 @@ HL_PRIM void hl_throw( vdynamic *v ) {
 	if( v != stack_last_exc ) {
 		stack_last_exc = v;
 		stack_count = CaptureStackBackTrace(1, 0x1000, stack_trace, NULL) - 8; // 8 startup
+		if( stack_count < 0 ) stack_count = 0;
 	}
 #endif
 	hl_current_exc = v;