소스 검색

more hot reload: handled natives and functions signs/reindexes

ncannasse 6 년 전
부모
커밋
6c6fcdcae1
3개의 변경된 파일158개의 추가작업 그리고 60개의 파일을 삭제
  1. 104 20
      src/code.c
  2. 4 1
      src/hlmodule.h
  3. 50 39
      src/module.c

+ 104 - 20
src/code.c

@@ -604,10 +604,51 @@ static const unsigned int crc32_table[] =
 
 #define H(b) hash = (hash >> 8) ^ crc32_table[(hash ^ b) & 0xFF]
 #define H32(i) { H(i&0xFF); H((i>>8)&0xFF); H((i>>16)&0xFF); H(((unsigned int)i)>>24); }
+#define HFUN(idx) H32(functions_signs[functions_indexes[idx]]); 
+#define HSTR(s) { const char *_c = s; while( *_c ) H(*_c++); }
+#define HUSTR(s) { const uchar *_c = s; while( *_c ) H(*_c++); }
 
-int hl_code_hash_fun( hl_code *c, hl_function *f ) {
+int hl_code_hash_type( hl_type *t ) {
 	int hash = -1;
-	int k;
+	int i;
+	switch( t->kind ) {
+	case HFUN:
+		H(t->fun->nargs);
+		for(i=0;i<t->fun->nargs;i++)
+			H32(hl_code_hash_type(t->fun->args[i]));
+		H32(hl_code_hash_type(t->fun->ret));
+		break;
+	// TODO
+	default:
+		break;
+	}
+	H(t->kind);
+	return hash;
+}
+
+int hl_code_hash_native( hl_native *n ) {
+	int hash = -1;
+	HSTR(n->lib);
+	HSTR(n->name);
+	H32(hl_code_hash_type(n->t));
+	return hash;
+}
+
+int hl_code_hash_fun_sign( hl_function *f ) {
+	int hash = -1;
+	H32(hl_code_hash_type(f->type));
+	if( f->obj ) {
+		HUSTR(f->obj->name);
+		HUSTR(f->field);
+	}
+	return hash;
+}
+
+int hl_code_hash_fun( hl_code *c, hl_function *f, int *functions_indexes, int *functions_signs ) {
+	int hash = -1;
+	int i, k;
+	for(i=0;i<f->nregs;i++)
+		H32(hl_code_hash_type(f->regs[i]));
 	for(k=0;k<f->nops;k++) {
 		hl_opcode *o = f->ops + k;
 		H(o->op);
@@ -621,6 +662,55 @@ int hl_code_hash_fun( hl_code *c, hl_function *f ) {
 			H32( ((int*)c->floats)[o->p2<<1] );
 			H32( ((int*)c->floats)[(o->p2<<1)|1] );
 			break;
+		//case OString:
+		//case OBytes:
+		case OType:
+			H32(o->p1);
+			H32(hl_code_hash_type(c->types + o->p2));
+			break;
+		case OCall0:
+			H32(o->p1);
+			HFUN(o->p2);
+			break;
+		case OCall1:
+			H32(o->p1);
+			HFUN(o->p2);
+			H32(o->p3);
+			break;
+		case OCall2:
+			H32(o->p1);
+			HFUN(o->p2);
+			H32(o->p3);
+			H32((int)(int_val)o->extra);
+			break;
+		case OCall3:
+			H32(o->p1);
+			HFUN(o->p2);
+			H32(o->p3);
+			H32(o->extra[0]);
+			H32(o->extra[1]);
+			break;
+		case OCall4:
+			H32(o->p1);
+			HFUN(o->p2);
+			H32(o->p3);
+			H32(o->extra[0]);
+			H32(o->extra[1]);
+			H32(o->extra[2]);
+			break;
+		case OCallN:
+			H32(o->p1);
+			HFUN(o->p2);
+			H32(o->p3);
+			for(i=0;i<o->p3;i++)
+				H32(o->extra[i]);
+			break;
+		case OStaticClosure:
+			break;
+		case OInstanceClosure:
+			break;
+		//case ODynGet:
+		//case ODynSet:
 		default:
 			switch( hl_op_nargs[o->op] ) {
 			case 0:
@@ -650,24 +740,18 @@ int hl_code_hash_fun( hl_code *c, hl_function *f ) {
 				case OCallMethod:
 				case OCallThis:
 				case OMakeEnum:
-					{
-						int i;
-						H32(o->p1);
-						H32(o->p2);
-						H32(o->p3);
-						for(i=0;i<o->p3;i++)
-							H32(o->extra[i]);
-					}
+					H32(o->p1);
+					H32(o->p2);
+					H32(o->p3);
+					for(i=0;i<o->p3;i++)
+						H32(o->extra[i]);
 					break;
 				case OSwitch:
-					{
-						int i;
-						H32(o->p1);
-						H32(o->p2);
-						for(i=0;i<o->p2;i++)
-							H32(o->extra[i]);
-						H32(o->p3);
-					}
+					H32(o->p1);
+					H32(o->p2);
+					for(i=0;i<o->p2;i++)
+						H32(o->extra[i]);
+					H32(o->p3);
 					break;
 				default:
 					printf("Don't know how to process opcode %d",o->op);
@@ -676,7 +760,7 @@ int hl_code_hash_fun( hl_code *c, hl_function *f ) {
 				break;
 			default:
 				{
-					int i, size = hl_op_nargs[o->op] - 3;
+					int size = hl_op_nargs[o->op] - 3;
 					H32(o->p1);
 					H32(o->p2);
 					H32(o->p3);
@@ -687,5 +771,5 @@ int hl_code_hash_fun( hl_code *c, hl_function *f ) {
 			}
 		}
 	}
-	return hash ^ -1;
+	return hash;
 }

+ 4 - 1
src/hlmodule.h

@@ -103,6 +103,7 @@ typedef struct {
 	unsigned char *globals_data;
 	void **functions_ptrs;
 	int *functions_indexes;
+	int *functions_signs;
 	int *functions_hashes;
 	void *jit_code;
 	hl_debug_infos *jit_debug;
@@ -111,7 +112,9 @@ typedef struct {
 } hl_module;
 
 hl_code *hl_code_read( const unsigned char *data, int size, char **error_msg );
-int hl_code_hash_fun( hl_code *c, hl_function *f );
+int hl_code_hash_fun_sign( hl_function *f );
+int hl_code_hash_fun( hl_code *c, hl_function *f, int *functions_indexes, int *functions_signs );
+int hl_code_hash_native( hl_native *n );
 void hl_code_free( hl_code *c );
 const uchar *hl_get_ustring( hl_code *c, int index );
 const char* hl_op_name( int op );

+ 50 - 39
src/module.c

@@ -381,10 +381,53 @@ static void hl_module_init_indexes( hl_module *m ) {
 
 static void hl_module_hash( hl_module *m ) {
 	int i;
+	m->functions_signs = malloc(sizeof(int) * (m->code->nfunctions + m->code->nnatives));
+	for(i=0;i<m->code->nfunctions;i++) {
+		hl_function *f = m->code->functions + i;
+		m->functions_signs[i] = hl_code_hash_fun_sign(f);
+	}
+	for(i=0;i<m->code->nnatives;i++) {
+		hl_native *n = m->code->natives + i;
+		m->functions_signs[i + m->code->nfunctions] = hl_code_hash_native(n);
+	}
 	m->functions_hashes = malloc(sizeof(int) * m->code->nfunctions);
 	for(i=0;i<m->code->nfunctions;i++) {
 		hl_function *f = m->code->functions + i;
-		m->functions_hashes[i] = hl_code_hash_fun(m->code,f);
+		m->functions_hashes[i] = hl_code_hash_fun(m->code,f, m->functions_indexes, m->functions_signs);
+	}
+}
+
+static void hl_module_init_natives( hl_module *m ) {
+	char tmp[256];
+	int i;
+	void *libHandler = NULL;
+	const char *curlib = NULL, *sign;
+	for(i=0;i<m->code->nnatives;i++) {
+		hl_native *n = m->code->natives + i;
+		char *p = tmp;
+		void *f;
+		if( curlib != n->lib ) {
+			curlib = n->lib;
+			libHandler = resolve_library(n->lib);
+		}
+		if( libHandler == DISABLED_LIB_PTR ) {
+			m->functions_ptrs[n->findex] = disabled_primitive;
+			continue;
+		}
+		strcpy(p,"hlp_");
+		p += 4;
+		strcpy(p,n->name);
+		p += strlen(n->name);
+		*p++ = 0;
+		f = dlsym(libHandler,tmp);
+		if( f == NULL )
+			hl_fatal2("Failed to load function %s@%s",n->lib,n->name);
+		m->functions_ptrs[n->findex] = ((void *(*)( const char **p ))f)(&sign);
+		p = tmp;
+		append_type(&p,n->t);
+		*p++ = 0;
+		if( memcmp(sign,tmp,strlen(sign)+1) != 0 )
+			hl_fatal4("Invalid signature for function %s@%s : %s required but %s found in hdll",n->lib,n->name,tmp,sign);
 	}
 }
 
@@ -398,41 +441,8 @@ int hl_module_init( hl_module *m, h_bool hot_reload ) {
 		if( hl_is_ptr(t) )
 			hl_add_root(m->globals_data+m->globals_indexes[i]);
 	}
-	// INIT natives
-	{
-		char tmp[256];
-		void *libHandler = NULL;
-		const char *curlib = NULL, *sign;
-		for(i=0;i<m->code->nnatives;i++) {
-			hl_native *n = m->code->natives + i;
-			char *p = tmp;
-			void *f;
-			if( curlib != n->lib ) {
-				curlib = n->lib;
-				libHandler = resolve_library(n->lib);
-			}
-			if( libHandler == DISABLED_LIB_PTR ) {
-				m->functions_ptrs[n->findex] = disabled_primitive;
-				continue;
-			}
-
-			strcpy(p,"hlp_");
-			p += 4;
-			strcpy(p,n->name);
-			p += strlen(n->name);
-			*p++ = 0;
-			f = dlsym(libHandler,tmp);
-			if( f == NULL )
-				hl_fatal2("Failed to load function %s@%s",n->lib,n->name);
-			m->functions_ptrs[n->findex] = ((void *(*)( const char **p ))f)(&sign);
-			p = tmp;
-			append_type(&p,n->t);
-			*p++ = 0;
-			if( memcmp(sign,tmp,strlen(sign)+1) != 0 )
-				hl_fatal4("Invalid signature for function %s@%s : %s required but %s found in hdll",n->lib,n->name,tmp,sign);
-		}
-	}
-	// INIT indexes
+	// inits
+	hl_module_init_natives(m);
 	hl_module_init_indexes(m);
 	// JIT
 	ctx = hl_jit_alloc();
@@ -454,7 +464,7 @@ int hl_module_init( hl_module *m, h_bool hot_reload ) {
 		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);
 	}
 	// INIT constants
-	for (i = 0; i<m->code->nconstants; i++) {
+	for(i=0;i<m->code->nconstants;i++) {
 		int j;
 		hl_constant *c = m->code->constants + i;
 		hl_type *t = m->code->globals[c->global];
@@ -524,9 +534,9 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 	jit_ctx *ctx = m1->jit_ctx;
 
 	hl_module *m2 = hl_module_alloc(c);
+	hl_module_init_natives(m2);
 	hl_module_init_indexes(m2);
-	hl_module_hash(m2);
-	
+	hl_module_hash(m2);	
 	hl_jit_reset(ctx, m2);
 
 	for(i2=0;i2<m2->code->nfunctions;i2++) {
@@ -589,6 +599,7 @@ void hl_module_free( hl_module *m ) {
 	free(m->globals_indexes);
 	free(m->globals_data);
 	free(m->functions_hashes);
+	free(m->functions_signs);
 	if( m->jit_debug ) {
 		int i;
 		for(i=0;i<m->code->nfunctions;i++)