Pārlūkot izejas kodu

started prototyping hl interp (see #186)

Nicolas Cannasse 6 gadi atpakaļ
vecāks
revīzija
cea6ae1421
8 mainītis faili ar 236 papildinājumiem un 35 dzēšanām
  1. 1 0
      hl.vcxproj
  2. 15 14
      hl.vcxproj.filters
  3. 160 0
      interp.c
  4. 2 2
      src/debugger.c
  5. 23 4
      src/hlmodule.h
  6. 3 0
      src/jit.c
  7. 2 1
      src/main.c
  8. 30 14
      src/module.c

+ 1 - 0
hl.vcxproj

@@ -258,6 +258,7 @@
     </Manifest>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="interp.c" />
     <ClCompile Include="src\code.c" />
     <ClCompile Include="src\debugger.c" />
     <ClCompile Include="src\jit.c" />

+ 15 - 14
hl.vcxproj.filters

@@ -1,15 +1,16 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <ClCompile Include="src\main.c" />
-    <ClCompile Include="src\code.c" />
-    <ClCompile Include="src\module.c" />
-    <ClCompile Include="src\jit.c" />
-    <ClCompile Include="src\debugger.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\hlmodule.h" />
-    <ClInclude Include="src\opcodes.h" />
-    <ClInclude Include="src\hl.h" />
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="src\main.c" />
+    <ClCompile Include="src\code.c" />
+    <ClCompile Include="src\module.c" />
+    <ClCompile Include="src\jit.c" />
+    <ClCompile Include="src\debugger.c" />
+    <ClCompile Include="interp.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\hlmodule.h" />
+    <ClInclude Include="src\opcodes.h" />
+    <ClInclude Include="src\hl.h" />
+  </ItemGroup>
 </Project>

+ 160 - 0
interp.c

@@ -0,0 +1,160 @@
+/*
+ * Copyright (C)2015-2016 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>
+#include <hlmodule.h>
+
+#ifdef HL_INTERP_ENABLE
+
+#define HL_INTERP_DEBUG
+
+#define OP_BEGIN
+#define OP(name,_)
+
+struct interp_ctx {
+	hl_alloc alloc;
+	hl_module *m;
+	int **fregs;
+};
+
+static interp_ctx *interp = NULL;
+
+#define REG_KIND(rid)	f->regs[rid]->kind
+#define REG(rid,T)		*((T*)(regs + regsPos[rid]))
+#define interp_error(err)	{ hl_debug_break(); hl_fatal(err); }
+
+void *hl_interp_run( interp_ctx *ctx, hl_function *f, vdynamic *ret ) {
+	hl_opcode *o = f->ops;
+	hl_module *m = ctx->m;
+	int *regsPos = ctx->fregs[f->findex];
+	char *regs = (char*)malloc(regsPos[f->nregs]);
+	void *pret = NULL;
+#	ifdef HL_INTERP_DEBUG
+	memset(regs,0xCD,regsPos[f->nregs]);
+#	endif
+	while( true ) {
+		switch( o->op ) {
+		case OCall0:
+			{
+				int fidx = m->functions_indexes[o->p2];
+				if( fidx < m->code->nfunctions ) {
+					pret = hl_interp_run(ctx, m->code->functions + fidx, ret);
+					if( hl_is_ptr(f->regs[o->p1]) )
+						REG(o->p1,void*) = pret;
+					else
+						memcpy(&REG(o->p1,void*),&ret->v,hl_type_size(f->regs[o->p1]));
+				} else {
+					switch( REG_KIND(o->p1) ) {
+					case HABSTRACT:
+						REG(o->p1,void*) = ((void*(*)())m->functions_ptrs[o->p2])();
+						break;
+					default:
+						interp_error("TODO");
+						break;
+					}
+				}
+			}
+			break;
+		case OCall3:
+			{
+				interp_error("TODO");
+			}
+			break;
+		case OInt:
+			REG(o->p1,int) = o->p2; 
+			break;
+		case OSetGlobal:
+			{
+				void *addr = m->globals_data + m->globals_indexes[o->p1];
+				memcpy(addr,&REG(o->p2,void*),hl_type_size(f->regs[o->p2]));
+			}
+			break;
+		case ORet:
+			{
+				switch( REG_KIND(o->p1) ) {
+				case HVOID:
+					return NULL;
+				default:
+					interp_error("TODO");
+					break;
+				}
+			}
+			break;
+		case OType:
+			REG(o->p1,hl_type*) = m->code->types + o->p2;
+			break;
+		case OString:
+			REG(o->p1,const uchar*) = hl_get_ustring(m->code,o->p2);
+			break;
+		default:
+			interp_error(hl_op_name(o->op));
+			break;
+		}
+		o++;
+	}
+	free(regs);
+	return pret;
+}
+
+static void *callback_c2hl( void *fptr, hl_type *t, void **args, vdynamic *ret ) {
+	hl_code *code = interp->m->code;
+	hl_function *f = (hl_function*)fptr;
+	if( f >= code->functions && f < code->functions + code->nfunctions )
+		return hl_interp_run(interp, f, ret); 
+	interp_error("assert");
+	return NULL;
+}
+
+interp_ctx *hl_interp_alloc() {
+	interp_ctx *i = (interp_ctx*)malloc(sizeof(interp_ctx));
+	memset(i,0,sizeof(interp_ctx));
+	hl_alloc_init(&i->alloc);
+	return i;
+}
+
+void hl_interp_init( interp_ctx *ctx, hl_module *m ) {
+	int i;
+	m->codeptr = ctx;
+	m->isinterp = true;
+	ctx->m = m;
+	interp = ctx;
+	ctx->fregs = (int**)hl_zalloc(&ctx->alloc, sizeof(int*)*(m->code->nfunctions + m->code->nnatives) );
+	for(i=0;i<m->code->nfunctions;i++) {
+		hl_function *f = m->code->functions + i;
+		int *regs = hl_malloc(&ctx->alloc,(f->nregs+1)*sizeof(int));
+		int regPos = 0;
+		int j;
+		for(j=0;j<f->nregs;j++) {
+			regs[j] = regPos;
+			regPos += hl_type_size(f->regs[j]);
+		}
+		regs[j] = regPos;
+		ctx->fregs[f->findex] = regs;
+	}
+	hl_setup_callbacks(callback_c2hl, NULL);
+}
+
+void *hl_interp_function( interp_ctx *i, hl_module *m, hl_function *f ) {
+	return f;
+}
+
+#endif
+

+ 2 - 2
src/debugger.c

@@ -72,7 +72,7 @@ static void hl_debug_loop( hl_module *m ) {
 		send(&pid,4);
 		send(&inf_addr, sizeof(void*));
 		send(&m->globals_data,sizeof(void*));
-		send(&m->jit_code,sizeof(void*));
+		send(&m->codeptr,sizeof(void*));
 		send(&m->codesize,4);
 		send(&m->code->types,sizeof(void*));
 
@@ -85,7 +85,7 @@ static void hl_debug_loop( hl_module *m ) {
 		send(&m->code->nfunctions,4);
 		for(i=0;i<m->code->nfunctions;i++) {
 			hl_function *f = m->code->functions + i;
-			hl_debug_infos *d = m->jit_debug + i;
+			hl_debug_infos *d = m->debug + i;
 			struct {
 				int nops;
 				int start;

+ 23 - 4
src/hlmodule.h

@@ -22,6 +22,15 @@
 #include <hl.h>
 #include "opcodes.h"
 
+#if defined(__arm__) || defined(HL_VERSION) 
+#	define HL_NO_JIT
+#	define HL_INTERP_ENABLE
+#endif
+
+#ifndef HL_NO_JIT
+#	define HL_JIT_ENABLE
+#endif
+
 typedef struct {
 	const char *lib;
 	const char *name;
@@ -98,13 +107,12 @@ typedef struct {
 	unsigned char *globals_data;
 	void **functions_ptrs;
 	int *functions_indexes;
-	void *jit_code;
-	hl_debug_infos *jit_debug;
+	void *codeptr;
+	bool isinterp;
+	hl_debug_infos *debug;
 	hl_module_context ctx;
 } hl_module;
 
-typedef struct jit_ctx jit_ctx;
-
 hl_code *hl_code_read( const unsigned char *data, int size );
 void hl_code_free( hl_code *c );
 const uchar *hl_get_ustring( hl_code *c, int index );
@@ -115,8 +123,19 @@ int hl_module_init( hl_module *m );
 void hl_module_free( hl_module *m );
 bool hl_module_debug( hl_module *m, int port, bool wait );
 
+#ifdef HL_JIT_ENABLE
+typedef struct jit_ctx jit_ctx;
+
 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_function( jit_ctx *ctx, hl_module *m, hl_function *f );
 void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, hl_debug_infos **debug );
+#endif
+
+#ifdef HL_INTERP_ENABLE
+typedef struct interp_ctx interp_ctx;
+interp_ctx *hl_interp_alloc();
+void hl_interp_init( interp_ctx *ctx, hl_module *m );
+void *hl_interp_function( interp_ctx *ctx, hl_module *m, hl_function *f );
+#endif

+ 3 - 0
src/jit.c

@@ -25,6 +25,8 @@
 #include <math.h>
 #include <hlmodule.h>
 
+#ifdef HL_JIT_ENABLE
+
 #ifdef __arm__
 #	error "JIT does not support ARM processors, only x86 and x86-64 are supported, please use HashLink/C native compilation instead"
 #endif
@@ -4124,3 +4126,4 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, hl_debug_infos **d
 	return code;
 }
 
+#endif // HL_JIT_ENABLE

+ 2 - 1
src/main.c

@@ -145,7 +145,8 @@ int main(int argc, pchar *argv[]) {
 		return 2;
 	if( !hl_module_init(ctx.m) )
 		return 3;
-	hl_code_free(ctx.code);
+	if( !ctx.m->isinterp )
+		hl_code_free(ctx.code);
 	if( debug_port > 0 && !hl_module_debug(ctx.m,debug_port,debug_wait) ) {
 		fprintf(stderr,"Could not start debugger on port %d",debug_port);
 		return 4;

+ 30 - 14
src/module.c

@@ -32,18 +32,18 @@
 static hl_module *cur_module;
 
 static bool module_resolve_pos( void *addr, int *fidx, int *fpos ) {
-	int code_pos = ((int)(int_val)((unsigned char*)addr - (unsigned char*)cur_module->jit_code));
+	int code_pos = ((int)(int_val)((unsigned char*)addr - (unsigned char*)cur_module->codeptr));
 	int min, max;
 	hl_debug_infos *dbg;
 	hl_function *fdebug;
-	if( cur_module->jit_debug == NULL )
+	if( cur_module->debug == NULL )
 		return false;
 	// lookup function from code pos
 	min = 0;
 	max = cur_module->code->nfunctions;
 	while( min < max ) {
 		int mid = (min + max) >> 1;
-		hl_debug_infos *p = cur_module->jit_debug + mid;
+		hl_debug_infos *p = cur_module->debug + mid;
 		if( p->start <= code_pos )
 			min = mid + 1;
 		else
@@ -52,7 +52,7 @@ static bool module_resolve_pos( void *addr, int *fidx, int *fpos ) {
 	if( min == 0 )
 		return false; // hl_callback
 	*fidx = (min - 1);
-	dbg = cur_module->jit_debug + (min - 1);
+	dbg = cur_module->debug + (min - 1);
 	fdebug = cur_module->code->functions + (min - 1);
 	// lookup inside function
 	min = 0;
@@ -101,10 +101,10 @@ static int module_capture_stack( void **stack, int size ) {
 	void *stack_bottom = stack_ptr;
 	void *stack_top = hl_get_thread()->stack_top;
 	int count = 0;
-	unsigned char *code = cur_module->jit_code;
+	unsigned char *code = cur_module->codeptr;
 	int code_size = cur_module->codesize;
-	if( cur_module->jit_debug ) {
-		int s = cur_module->jit_debug[0].start;
+	if( cur_module->debug ) {
+		int s = cur_module->debug[0].start;
 		code += s;
 		code_size -= s;
 	}
@@ -275,7 +275,6 @@ static void disabled_primitive() {
 
 int hl_module_init( hl_module *m ) {
 	int i;
-	jit_ctx *ctx;
 	// RESET globals
 	for(i=0;i<m->code->nglobals;i++) {
 		hl_type *t = m->code->globals[i];
@@ -372,8 +371,20 @@ int hl_module_init( hl_module *m ) {
 			break;
 		}
 	}
+	// INTERP
+#	ifdef HL_INTERP_ENABLE
+	interp_ctx *ctx = hl_interp_alloc();
+	if( ctx == NULL )
+		return 0;
+	hl_interp_init(ctx,m);
+	for(i=0;i<m->code->nfunctions;i++) {
+		hl_function *f = m->code->functions + i;
+		m->functions_ptrs[f->findex] = hl_interp_function(ctx,m,f);
+	}
+#	endif
 	// JIT
-	ctx = hl_jit_alloc();
+#	ifdef HL_JIT_ENABLE
+	jit_ctx *ctx = hl_jit_alloc();
 	if( ctx == NULL )
 		return 0;
 	hl_jit_init(ctx, m);
@@ -386,11 +397,14 @@ int hl_module_init( hl_module *m ) {
 		}
 		m->functions_ptrs[f->findex] = (void*)(int_val)fpos;
 	}
-	m->jit_code = hl_jit_code(ctx, m, &m->codesize, &m->jit_debug);
+	m->codeptr = hl_jit_code(ctx, m, &m->codesize, &m->debug);
 	for(i=0;i<m->code->nfunctions;i++) {
 		hl_function *f = m->code->functions + i;
-		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);
+		m->functions_ptrs[f->findex] = ((unsigned char*)m->codeptr) + ((int_val)m->functions_ptrs[f->findex]);
 	}
+#	endif
+	if( !m->codeptr )
+		return false;
 	// INIT constants
 	for (i = 0; i<m->code->nconstants; i++) {
 		int j;
@@ -440,7 +454,9 @@ int hl_module_init( hl_module *m ) {
 	cur_module = m;
 	hl_setup_exception(module_resolve_symbol, module_capture_stack);
 	hl_gc_set_dump_types(hl_module_types_dump);
+#	ifdef HL_JIT_ENABLE
 	hl_jit_free(ctx);
+#	endif
 	return 1;
 }
 
@@ -452,11 +468,11 @@ void hl_module_free( hl_module *m ) {
 	free(m->ctx.functions_types);
 	free(m->globals_indexes);
 	free(m->globals_data);
-	if( m->jit_debug ) {
+	if( m->debug ) {
 		int i;
 		for(i=0;i<m->code->nfunctions;i++)
-			free(m->jit_debug[i].offsets);
-		free(m->jit_debug);
+			free(m->debug[i].offsets);
+		free(m->debug);
 	}
 	free(m);
 }