changeset 11:3021dac0d8f5

Stack unwind is so close I can almost taste it
author Mike Pavone <pavone@retrodev.com>
date Tue, 19 May 2009 23:29:55 -0400
parents 0f2c4ee070fe
children 31f8182f3433
files runtime/func.h runtime/integer.c test/fib.c test/test.c
diffstat 4 files changed, 212 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/func.h	Sat May 16 23:24:24 2009 -0400
+++ b/runtime/func.h	Tue May 19 23:29:55 2009 -0400
@@ -15,25 +15,101 @@
 
 #define MethodName(name,type) _f_ ## name ## _AT_ ## type
 
-#define Func(name,numparams,locals) returntype _f_ ## name (calldata * cdata) { locals; calldata *call; returntype ret; int idx; for(idx = numparams; idx < cdata->num_params; ++idx) release_ref(cdata->params[idx]); cdata->num_params = numparams;
-#define FuncNoLocals(name,numparams) returntype _f_ ## name (calldata * cdata) {calldata *call; returntype ret; int idx; for(idx = numparams; idx < cdata->num_params; ++idx) release_ref(cdata->params[idx]); cdata->num_params = numparams;
-#define EndFunc	return NORMAL_RETURN; }
-#define Method(name,type,numparams,locals) returntype MethodName(name,type) (calldata * cdata) { locals; calldata *call; returntype ret; int idx; for(idx = numparams; idx < cdata->num_params; ++idx) release_ref(cdata->params[idx]); cdata->num_params = numparams;
-#define MethodNoLocals(name,type,numparams) returntype MethodName(name,type) (calldata * cdata) { calldata *call; returntype ret; int idx; for(idx = numparams; idx < cdata->num_params; ++idx) release_ref(cdata->params[idx]); cdata->num_params = numparams;
+#define Func(name,numparams,callspace,localtype) \
+	returntype _f_ ## name (calldata * cdata)\
+	{\
+		localtype *locals;\
+		calldata *call;\
+		returntype ret;\
+		int idx;\
+		if(cdata->resume)\
+		{\
+			locals = cdata->locals;\
+			call = (calldata *)(((char *)cdata->locals) + sizeof(localtype));\
+		}\
+		switch(cdata->resume)\
+		{\
+		case 0:\
+			for(idx = numparams; idx < cdata->num_params; ++idx)\
+				release_ref(cdata->params[idx]); cdata->num_params = numparams;\
+			cdata->num_params = numparams;\
+			cdata->locals = call = alloc_cdata(cdata->ct, callspace);
+
+#define FuncNoLocals(name,numparams,callspace) \
+	returntype _f_ ## name (calldata * cdata)\
+	{\
+		calldata *call;\
+		returntype ret;\
+		int idx;\
+		if(cdata->resume)\
+			call = cdata->locals;\
+		switch(cdata->resume)\
+		{\
+		case 0:\
+			for(idx = numparams; idx < cdata->num_params; ++idx)\
+				release_ref(cdata->params[idx]);\
+			cdata->num_params = numparams;\
+			cdata->locals = call = alloc_cdata(cdata->ct, callspace);
+
+#define EndFunc	\
+			return NORMAL_RETURN;\
+		}\
+	}
+
+#define Method(name,type,numparams,callspace,localtype) \
+	returntype MethodName(name,type) (calldata * cdata)\
+	{\
+		localtype *locals;\
+		calldata *call;\
+		returntype ret;\
+		int idx;\
+		if(cdata->resume)\
+		{\
+			locals = cdata->locals;\
+			call = (calldata *)(((char *)cdata->locals) + sizeof(localtype));\
+		}\
+		switch(cdata->resume)\
+		{\
+		case 0:\
+			for(idx = numparams; idx < cdata->num_params; ++idx)\
+				release_ref(cdata->params[idx]); cdata->num_params = numparams;\
+			cdata->num_params = numparams;\
+			cdata->locals = call = alloc_cdata(cdata->ct, callspace);
+
+#define MethodNoLocals(name,type,numparams,callspace) \
+	returntype MethodName(name,type) (calldata * cdata)\
+	{\
+		calldata *call;\
+		returntype ret;\
+		int idx;\
+		if(cdata->resume)\
+			call = cdata->locals;\
+		switch(cdata->resume)\
+		{\
+		case 0:\
+			for(idx = numparams; idx < cdata->num_params; ++idx)\
+				release_ref(cdata->params[idx]);\
+			cdata->num_params = numparams;\
+			cdata->locals = call = alloc_cdata(cdata->ct, callspace);
+	
+#define NumParams
+#define CallSpace
+
 #define ParamBase(num,var,type,convtypeid) \
-call->params[0] = cdata->params[num];\
-ret = coerce_value(convtypeid, call);\
-while(ret == TAIL_RETURN)\
-	ret = call->tail_func(call);\
-if(ret == EXCEPTION_RETURN)\
-{\
-	for(idx = 0; idx < cdata->num_params; ++idx)\
-		if(idx != num)\
-			release_ref(cdata->params[idx]);\
-	cdata->params[0] = call->params[0];\
-	return ret;\
-}\
-cdata->params[num] = call->params[0];
+	call->params[0] = cdata->params[num];\
+	call->resume = 0;\
+	ret = coerce_value(convtypeid, call);\
+	while(ret == TAIL_RETURN)\
+		ret = call->tail_func(call);\
+	if(ret == EXCEPTION_RETURN)\
+	{\
+		for(idx = 0; idx < cdata->num_params; ++idx)\
+			if(idx != num)\
+				release_ref(cdata->params[idx]);\
+		cdata->params[0] = call->params[0];\
+		return ret;\
+	}\
+	cdata->params[num] = call->params[0];
 
 #define Param(num,var,type,convtypeid) ParamBase(num,var,type,convtypeid) var = (_t_##type *)(cdata->params[num]);
 #define CopiedParam(num,var,type,convtypeid) ParamBase(num,var,type,convtypeid) cdata->params[num] = copy_object(cdata->params[num]); var = (_t_##type *)(cdata->params[num]);
@@ -43,5 +119,32 @@
 #define FuncDef(name) returntype _f_ ## name (calldata * cdata);
 #define MethodDef(name,type) returntype MethodName(name,type) (calldata * cdata);
 
+#define Call(func, numparams)\
+	call->num_params = numparams;\
+	call->resume = 0;\
+	ret = _f_ ## func (call);\
+	while(ret == TAIL_RETURN)\
+		ret = call->tail_func(call);\
+	if(ret == EXCEPTION_RETURN)\
+	{\
+		for(idx = 0; idx < cdata->num_params; ++idx)\
+			release_ref(cdata->params[idx]);\
+		cdata->params[0] = call->params[0];\
+		return ret;\
+	}
+	
+#define MCall(methodid, numparams)\
+	call->num_params = numparams;\
+	call->resume = 0;\
+	ret = call_method(methodid, call);\
+	while(ret == TAIL_RETURN)\
+		ret = call->tail_func(call);\
+	if(ret == EXCEPTION_RETURN)\
+	{\
+		for(idx = 0; idx < cdata->num_params; ++idx)\
+			release_ref(cdata->params[idx]);\
+		cdata->params[0] = call->params[0];\
+		return ret;\
+	}
 
 #endif //_FUNC_H_
\ No newline at end of file
--- a/runtime/integer.c	Sat May 16 23:24:24 2009 -0400
+++ b/runtime/integer.c	Tue May 19 23:29:55 2009 -0400
@@ -5,8 +5,10 @@
 #define left ((_t_Int32 *)cdata->params[0])
 #define right ((_t_Int32 *)cdata->params[1])
 
-MethodNoLocals(_PL_,Int32,2)
-	call = alloc_cdata(cdata->ct, 1);
+MethodNoLocals(_PL_,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
 	CopiedParam(0, left, Int32, TYPE_INT32)
 	Param(1, right, Int32, TYPE_INT32)
 	
@@ -15,8 +17,10 @@
 	release_ref((object *)right);
 EndFunc
 
-MethodNoLocals(_MN_,Int32,2)
-	call = alloc_cdata(cdata->ct, 1);
+MethodNoLocals(_MN_,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
 	CopiedParam(0, left, Int32, TYPE_INT32)
 	Param(1, right, Int32, TYPE_INT32)
 	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fib.c	Tue May 19 23:29:55 2009 -0400
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include "builtin.h"
+#include "object.h"
+#include "integer.h"
+#include "context.h"
+#include "func.h"
+
+typedef struct
+{
+	object * work1;
+	object * work2;
+} fib_t;
+
+object * const_1;
+object * const_2;
+
+Func(Fib,
+	NumParams 1,
+	CallSpace 2,
+	fib_t);
+	
+	MCall(METHOD_SUB, 
+EndFunc
+
+FuncNoLocals(Main,
+	NumParams 0,
+	CallSpace 2)
+	
+	call->params[0] = make_Int32(2);
+	call->params[1] = make_Int32(3);
+	call->num_params = 2;
+	call->resume = 0;
+	ret = call_method(METHOD_ADD, call);
+	while(ret == TAIL_RETURN)
+		ret = call->tail_func(call);
+	if(ret == EXCEPTION_RETURN) {
+		Ret(0,call->params[0]);
+		return ret;
+	}
+	call->params[1] = make_Int32(1);
+	call->resume = 0;
+	ret = call_method(METHOD_SUB, call);
+	while(ret == TAIL_RETURN)
+		ret = call->tail_func(call);
+	if(ret == EXCEPTION_RETURN) {
+		Ret(0,call->params[0]);
+		return ret;
+	}
+	Ret(0,call->params[0])
+EndFunc
+
+
+int main(int argc, char ** argv)
+{
+	returntype ret;
+	calldata *cdata;
+	context * ct;
+	register_builtin_types();
+	ct = new_context();
+	cdata = alloc_cdata(ct, 1);
+	cdata->num_params = 0;
+	cdata->resume = 0;
+	
+	const_1 = make_Int32(1);
+	const_2 = make_Int32(2);
+	ret = _f_Main(cdata);
+	while(ret == TAIL_RETURN)
+		ret = cdata->tail_func(cdata);
+	if(ret == EXCEPTION_RETURN) {
+		puts("Exception!");
+		return -1;
+	}
+	printf("Result: %d\n", ((_t_Int32 *)cdata->params[0])->num);
+	return 0;
+}
+
--- a/test/test.c	Sat May 16 23:24:24 2009 -0400
+++ b/test/test.c	Tue May 19 23:29:55 2009 -0400
@@ -5,26 +5,15 @@
 #include "context.h"
 #include "func.h"
 
-FuncNoLocals(Main,0)
-	call = alloc_cdata(cdata->ct,2);
+FuncNoLocals(Main,
+	NumParams 0,
+	CallSpace 2)
 	call->params[0] = make_Int32(2);
 	call->params[1] = make_Int32(3);
-	call->num_params = 2;
-	ret = call_method(METHOD_ADD, call);
-	while(ret == TAIL_RETURN)
-		ret = call->tail_func(call);
-	if(ret == EXCEPTION_RETURN) {
-		Ret(0,call->params[0]);
-		return ret;
-	}
+	MCall(METHOD_ADD, 2)
+	
 	call->params[1] = make_Int32(1);
-	ret = call_method(METHOD_SUB, call);
-	while(ret == TAIL_RETURN)
-		ret = call->tail_func(call);
-	if(ret == EXCEPTION_RETURN) {
-		Ret(0,call->params[0]);
-		return ret;
-	}
+	MCall(METHOD_SUB, 2)
 	Ret(0,call->params[0])
 EndFunc
 
@@ -38,6 +27,7 @@
 	ct = new_context();
 	cdata = alloc_cdata(ct, 1);
 	cdata->num_params = 0;
+	cdata->resume = 0;
 	ret = _f_Main(cdata);
 	while(ret == TAIL_RETURN)
 		ret = cdata->tail_func(cdata);