diff runtime/func.h @ 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 52d9948def24
children 31f8182f3433
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