Explorar el Código

added hl_stack_size to differentiate between struct and stack alignment

Nicolas Cannasse hace 9 años
padre
commit
93382b266e
Se han modificado 4 ficheros con 56 adiciones y 32 borrados
  1. 16 6
      src/callback.c
  2. 1 0
      src/hl.h
  3. 6 4
      src/jit.c
  4. 33 22
      src/std/types.c

+ 16 - 6
src/callback.c

@@ -39,18 +39,17 @@ void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret ) {
 	int i, size = 0, pad = 0, pos = 0;
 	for(i=0;i<t->fun->nargs;i++) {
 		hl_type *at = t->fun->args[i];
-		size += hl_type_size(at);
+		size += hl_stack_size(at);
 	}
 	if( size & 15 )
 		pad = 16 - (size&15);
-	size = pos = pad;
+	pos = pad;
 	for(i=0;i<t->fun->nargs;i++) {
 		// RTL
 		int j = t->fun->nargs - 1 - i;
 		hl_type *at = t->fun->args[j];
 		void *v = args[j];
-		int tsize = hl_type_size(at);
-		size += tsize;
+		int tsize = hl_stack_size(at);
 		if( hl_is_ptr(at) )
 			*(void**)&stack.b[pos] = v;
 		else switch( tsize ) {
@@ -63,7 +62,18 @@ void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret ) {
 			*(short*)&stack.b[pos] = *(short*)v;
 			break;
 		case 4:
-			*(int*)&stack.b[pos] = *(int*)v;
+			switch( at->kind ) {
+			case HBOOL:
+			case HI8:
+				*(int*)&stack.b[pos] = *(unsigned char*)v;
+				break;
+			case HI16:
+				*(int*)&stack.b[pos] = *(unsigned short*)v;
+				break;
+			default:
+				*(int*)&stack.b[pos] = *(int*)v;
+				break;
+			}
 			break;
 		case 8:
 			*(double*)&stack.b[pos] = *(double*)v;
@@ -105,7 +115,7 @@ static void *hl_call_wrapper_ptr( vclosure_wrapper *c ) {
 			args[i] = *(vdynamic**)stack;
 		else
 			args[i] = hl_make_dyn(stack,t);
-		stack += hl_type_size(t);
+		stack += hl_stack_size(t);
 	}
 	tret = c->cl.t->fun->ret;
 	if( tret->kind != HVOID )

+ 1 - 0
src/hl.h

@@ -302,6 +302,7 @@ struct hl_type {
 
 HL_API int hl_type_size( hl_type *t );
 HL_API int hl_pad_size( int size, hl_type *t );
+HL_API int hl_stack_size( hl_type *t );
 
 HL_API hl_runtime_obj *hl_get_obj_rt( hl_type *ot );
 HL_API hl_runtime_obj *hl_get_obj_proto( hl_type *ot );

+ 6 - 4
src/jit.c

@@ -1113,7 +1113,7 @@ static int pad_before_call( jit_ctx *ctx, int size ) {
 
 static void push_reg( jit_ctx *ctx, vreg *r ) {
 	preg p;
-	switch( r->size ) {
+	switch( hl_stack_size(r->t) ) {
 	case 1:
 		op64(ctx,SUB,PESP,pconst(&p,1));
 		op32(ctx,MOV8,pmem(&p,Esp,0),alloc_cpu(ctx,r,true));
@@ -1123,6 +1123,8 @@ static void push_reg( jit_ctx *ctx, vreg *r ) {
 		op32(ctx,MOV16,pmem(&p,Esp,0),alloc_cpu(ctx,r,true));
 		break;
 	case 4:
+		if( r->size < 4 )
+			alloc_cpu(ctx,r,true); // force fetch (higher bits set to 0)
 		if( !IS_64 ) {
 			if( r->current != NULL && r->current->kind == RFPU ) scratch(r->current);
 			op32(ctx,PUSH,fetch(r),UNUSED);
@@ -1178,7 +1180,7 @@ static int prepare_call_args( jit_ctx *ctx, int count, int *args, vreg *vregs, b
 #endif
 	for(i=count - stackRegs;i<count;i++) {
 		vreg *r = vregs + args[i];
-		size += r->size;
+		size += hl_stack_size(r->t);
 	}
 	paddedSize = pad_before_call(ctx,size);
 	for(i=0;i<stackRegs;i++) {
@@ -1979,13 +1981,13 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	for(i=0;i<nargs;i++) {
 		vreg *r = R(i);
 		r->stackPos = size + HL_WSIZE * 2;
-		size += r->size;
+		size += hl_stack_size(r->t);
 	}
 	size = 0;
 	for(i=nargs;i<f->nregs;i++) {
 		vreg *r = R(i);
 		size += r->size;
-		size += hl_pad_size(size,r->t);
+		size += hl_pad_size(size,r->t); // align local vars
 		r->stackPos = -size;
 	}
 	size += hl_pad_size(size,&hlt_dyn); // align on word size

+ 33 - 22
src/std/types.c

@@ -37,30 +37,41 @@ static const uchar *TSTR[] = {
 	NULL, NULL, NULL
 };
 
+static int T_SIZES[] = {
+	0, // VOID
+	1, // I8
+	2, // I16
+	4, // I32
+	4, // F32
+	8, // F64
+	1, // BOOL
+	HL_WSIZE, // BYTES
+	HL_WSIZE, // DYN
+	HL_WSIZE, // FUN
+	HL_WSIZE, // OBJ
+	HL_WSIZE, // ARRAY
+	HL_WSIZE, // TYPE
+	HL_WSIZE, // REF
+	HL_WSIZE, // VIRTUAL
+	HL_WSIZE, // DYNOBJ
+	HL_WSIZE, // ABSTRACT
+	HL_WSIZE, // ENUM
+	HL_WSIZE, // NULL
+};
 
 HL_PRIM int hl_type_size( hl_type *t ) {
-	static int SIZES[] = {
-		0, // VOID
-		1, // I8
-		2, // I16
-		4, // I32
-		4, // F32
-		8, // F64
-		1, // BOOL
-		HL_WSIZE, // BYTES
-		HL_WSIZE, // DYN
-		HL_WSIZE, // FUN
-		HL_WSIZE, // OBJ
-		HL_WSIZE, // ARRAY
-		HL_WSIZE, // TYPE
-		HL_WSIZE, // REF
-		HL_WSIZE, // VIRTUAL
-		HL_WSIZE, // DYNOBJ
-		HL_WSIZE, // ABSTRACT
-		HL_WSIZE, // ENUM
-		HL_WSIZE, // NULL
-	};
-	return SIZES[t->kind];
+	return T_SIZES[t->kind];
+}
+
+HL_PRIM int hl_stack_size( hl_type *t ) {
+	switch( t->kind ) {
+	case HI8:
+	case HI16:
+	case HBOOL:
+		return sizeof(int);
+	default:
+		return T_SIZES[t->kind];
+	}
 }
 
 HL_PRIM int hl_pad_size( int pos, hl_type *t ) {