changeset 8:8d74ef7fa357

Improved helper macros and added separate Rhope stack in runtime
author Mike Pavone <pavone@retrodev.com>
date Wed, 13 May 2009 23:37:19 -0400
parents d61550e2c001
children 52d9948def24
files runtime/context.c runtime/context.h runtime/func.h runtime/integer.c runtime/object.h test/test.c
diffstat 6 files changed, 185 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/context.c	Wed May 13 23:37:19 2009 -0400
@@ -0,0 +1,64 @@
+#include "context.h"
+#include "object.h"
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+
+stackchunk * new_stack()
+{
+	stackchunk * st = malloc(sizeof(stackchunk));
+	st->prev = NULL;
+	st->next = NULL;
+	st->used = 0;
+	return st;
+}
+
+context * new_context()
+{
+	context * c = malloc(sizeof(context));
+	c->stack_begin = new_stack();
+	c->current_stack = c->stack_begin;
+	c->unwind = NULL;
+	return c;
+}
+
+void * alloc_stack(context * ct, uint32_t size)
+{
+	void * ret;
+	stackchunk * current = ct->current_stack;
+	if(size > STACK_CHUNK_SIZE)
+		return NULL;
+	while(current && STACK_CHUNK_SIZE - current->used < size)
+	{
+		if(!current->next)
+			current->next = new_stack();
+		current = current->next;
+	}
+	if(!current)
+		return NULL;
+	ct->current_stack = current;
+	ret = current->data + current->used;
+	current->used += size;
+	return ret;
+}
+
+calldata * alloc_cdata(context * ct, uint32_t num_params)
+{
+	calldata * out = alloc_stack(ct, sizeof(calldata)+(num_params-1)*sizeof(object *));
+	if(out)
+		out->ct = ct;
+	return out;
+}
+
+void free_stack(context * ct, void * data)
+{
+	char * cdata = data;
+	if(cdata < ct->current_stack->data || cdata >= ct->current_stack->data+STACK_CHUNK_SIZE) {
+		fputs("Tried to free stack data from outside of current stack chunk!", stderr);
+		exit(-1);
+	}
+	ct->current_stack->used = cdata-ct->current_stack->data;
+	if(!ct->current_stack->used && ct->current_stack->prev)
+		ct->current_stack = ct->current_stack->prev;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/context.h	Wed May 13 23:37:19 2009 -0400
@@ -0,0 +1,33 @@
+#ifndef _CONTEXT_H_
+#define _CONTEXT_H_
+
+#include "thread.h"
+#include "plat_types.h"
+#include "func.h"
+
+#define STACK_CHUNK_SIZE 4096-(sizeof(struct stackchunk *)*2+sizeof(uint32_t))
+
+typedef struct stackchunk {
+	struct    stackchunk * next;
+	struct    stackchunk * prev;
+	uint32_t  used;
+	char      data[STACK_CHUNK_SIZE];
+} stackchunk;
+
+typedef struct {
+	rhope_func       func;
+	struct calldata  *params;
+} unwind_cell;
+
+typedef struct context {
+	stackchunk   *stack_begin;
+	stackchunk   *current_stack;
+	unwind_cell  *unwind;
+} context;
+
+stackchunk * new_stack();
+context * new_context();
+void * alloc_stack(context * ct, uint32_t size);
+struct calldata * alloc_cdata(context * ct, uint32_t num_params);
+void free_stack(context * ct, void * data);
+#endif //_CONTEXT_H_
--- a/runtime/func.h	Wed May 13 00:47:40 2009 -0400
+++ b/runtime/func.h	Wed May 13 23:37:19 2009 -0400
@@ -1,12 +1,41 @@
 #ifndef _FUNC_H_
 #define _FUNC_H_
 
+typedef enum {
+	NORMAL_RETURN=0,
+	EXCEPTION_RETURN,
+	TAIL_RETURN,
+	NO_CONVERSION,
+	STACK_UNWIND
+} returntype;
+
+
+typedef returntype (*rhope_func)(struct calldata *);
+typedef void (*special_func) (struct object *);
+
 #define MethodName(name,type) _f_ ## name ## _AT_ ## type
 
-#define Func(name,numparams,locals) returntype _f_ ## name (calldata * cdata) { locals;
+#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;
-#define Param(num,var,type) var = (_t_##type *)(
+#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 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];
+
+#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]);
 #define Ret(num,val) cdata->params[num] = (object *)(val);
 #define Return return NORMAL_RETURN;
 #define Exception
--- a/runtime/integer.c	Wed May 13 00:47:40 2009 -0400
+++ b/runtime/integer.c	Wed May 13 23:37:19 2009 -0400
@@ -1,111 +1,28 @@
 #include "integer.h"
 #include "builtin.h"
+#include "context.h"
 
 Method(_PL_,Int32,2,
-	_t_Int32 * left; _t_Int32 * right; calldata convd; returntype ret; int i)
-	convd.params[0] = cdata->params[0];
-	convd.num_params = 1;
-	switch(coerce_value(TYPE_INT32, &convd))
-	{
-	case TAIL_RETURN:
-		do {
-			ret = convd.tail_func(&convd);
-		} while(ret == TAIL_RETURN);
-		//TODO: Support STACK_UNWIND
-		if(ret == EXCEPTION_RETURN)
-			goto exception_convert_left;
-	case EXCEPTION_RETURN:
-		goto exception_convert_left;
-	}
-	left = (_t_Int32 *)copy_object(convd.params[0]);
-	cdata->params[0] = (object *)left;
-	convd.params[0] = cdata->params[1];
-	switch(coerce_value(TYPE_INT32, &convd))
-	{
-	case TAIL_RETURN:
-		do {
-			ret = convd.tail_func(&convd);
-		} while(ret == TAIL_RETURN);
-		//TODO: Support STACK_UNWIND
-		if(ret == EXCEPTION_RETURN)
-			goto exception_convert_right;
-	case EXCEPTION_RETURN:
-		goto exception_convert_right;
-	}
-	right = (_t_Int32 *)convd.params[0];
+	_t_Int32 * left; _t_Int32 * right)
+	call = alloc_cdata(cdata->ct, 1);
+	CopiedParam(0, left, Int32, TYPE_INT32)
+	Param(1, right, Int32, TYPE_INT32)
+	
 	left->num += right->num;
+	
 	release_ref((object *)right);
-	return NORMAL_RETURN;
-	
-exception_convert_left:
-	//The first params hould have been released when the exception occurred
-	for(i = 1; i < cdata->num_params; ++i)
-		release_ref(cdata->params[i]);
-	//Move exception to our calldata struct
-	cdata->params[0] = convd.params[0];
-	return EXCEPTION_RETURN;
-exception_convert_right:
-	//The second param hould have been released when the exception occurred
-	for(i = 0; i < cdata->num_params; ++i)
-		if(i != 1)
-			release_ref(cdata->params[i]);
-	//Move exception to our calldata struct
-	cdata->params[0] = convd.params[0];
-	return EXCEPTION_RETURN;
-}
+EndFunc
 
 Method(_MN_,Int32,2,
-	_t_Int32 * left; _t_Int32 * right; calldata convd; returntype ret; int i)
-	convd.params[0] = cdata->params[0];
-	convd.num_params = 1;
-	switch(coerce_value(TYPE_INT32, &convd))
-	{
-	case TAIL_RETURN:
-		do {
-			ret = convd.tail_func(&convd);
-		} while(ret == TAIL_RETURN);
-		//TODO: Support STACK_UNWIND
-		if(ret == EXCEPTION_RETURN)
-			goto exception_convert_left;
-	case EXCEPTION_RETURN:
-		goto exception_convert_left;
-	}
-	left = (_t_Int32 *)copy_object(convd.params[0]);
-	cdata->params[0] = (object *)left;
-	convd.params[0] = cdata->params[1];
-	switch(coerce_value(TYPE_INT32, &convd))
-	{
-	case TAIL_RETURN:
-		do {
-			ret = convd.tail_func(&convd);
-		} while(ret == TAIL_RETURN);
-		//TODO: Support STACK_UNWIND
-		if(ret == EXCEPTION_RETURN)
-			goto exception_convert_right;
-	case EXCEPTION_RETURN:
-		goto exception_convert_right;
-	}
-	right = (_t_Int32 *)convd.params[0];
+	_t_Int32 * left; _t_Int32 * right)
+	call = alloc_cdata(cdata->ct, 1);
+	CopiedParam(0, left, Int32, TYPE_INT32)
+	Param(1, right, Int32, TYPE_INT32)
+	
 	left->num -= right->num;
+	
 	release_ref((object *)right);
-	return NORMAL_RETURN;
-	
-exception_convert_left:
-	//The first params hould have been released when the exception occurred
-	for(i = 1; i < cdata->num_params; ++i)
-		release_ref(cdata->params[i]);
-	//Move exception to our calldata struct
-	cdata->params[0] = convd.params[0];
-	return EXCEPTION_RETURN;
-exception_convert_right:
-	//The second param hould have been released when the exception occurred
-	for(i = 0; i < cdata->num_params; ++i)
-		if(i != 1)
-			release_ref(cdata->params[i]);
-	//Move exception to our calldata struct
-	cdata->params[0] = convd.params[0];
-	return EXCEPTION_RETURN;
-}
+EndFunc
 
 object * make_Int32(int32_t val)
 {
--- a/runtime/object.h	Wed May 13 00:47:40 2009 -0400
+++ b/runtime/object.h	Wed May 13 23:37:19 2009 -0400
@@ -3,18 +3,7 @@
 
 #include "plat_types.h"
 #include "thread.h"
-
-typedef enum {
-	NORMAL_RETURN=0,
-	EXCEPTION_RETURN,
-	TAIL_RETURN,
-	NO_CONVERSION,
-	STACK_UNWIND
-} returntype;
-
-
-typedef returntype (*rhope_func)(struct calldata *);
-typedef void (*special_func) (struct object *);
+#include "func.h"
 
 typedef struct{
 	rhope_func     *method_lookup;
@@ -52,10 +41,11 @@
 
 
 typedef struct calldata {
-	rhope_func  tail_func;
-	uint32_t    num_params;
-	uint32_t    original_methodid;
-	object      *params[32];
+	rhope_func     tail_func;
+	struct context *ct;
+	uint32_t       num_params;
+	uint32_t       original_methodid;
+	object         *params[1];
 } calldata;
 
 #define OBegin typedef struct { object header;
--- a/test/test.c	Wed May 13 00:47:40 2009 -0400
+++ b/test/test.c	Wed May 13 23:37:19 2009 -0400
@@ -2,32 +2,50 @@
 #include "builtin.h"
 #include "object.h"
 #include "integer.h"
+#include "context.h"
+#include "func.h"
+
+FuncNoLocals(Main,0)
+	call = alloc_cdata(cdata->ct,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;
+	}
+	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;
+	}
+	Ret(0,call->params[0])
+EndFunc
+
 
 int main(int argc, char ** argv)
 {
 	returntype ret;
-	calldata cdata;
+	calldata *cdata;
+	context * ct;
 	register_builtin_types();
-	cdata.params[0] = make_Int32(2);
-	cdata.params[1] = make_Int32(3);
-	cdata.num_params = 2;
-	ret = call_method(METHOD_ADD, &cdata);
+	ct = new_context();
+	cdata = alloc_cdata(ct, 1);
+	cdata->num_params = 0;
+	ret = _f_Main(cdata);
 	while(ret == TAIL_RETURN)
-		ret = cdata.tail_func(&cdata);
+		ret = cdata->tail_func(cdata);
 	if(ret == EXCEPTION_RETURN) {
 		puts("Exception!");
-		exit(-1);
+		return -1;
 	}
-	printf("After METHOD_ADD: %d\n", ((_t_Int32 *)cdata.params[0])->num);
-	cdata.params[1] = make_Int32(1);
-	ret = call_method(METHOD_SUB, &cdata);
-	while(ret == TAIL_RETURN)
-		ret = cdata.tail_func(&cdata);
-	if(ret == EXCEPTION_RETURN) {
-		puts("Exception!");
-		exit(-1);
-	}
-	printf("After METHOD_ADD: %d\n", ((_t_Int32 *)cdata.params[0])->num);
+	printf("Result: %d\n", ((_t_Int32 *)cdata->params[0])->num);
 	return 0;
 }