# HG changeset patch # User Mike Pavone # Date 1242272239 14400 # Node ID 8d74ef7fa357cd64fdf5633df3895d51a053ebfa # Parent d61550e2c0010ccba15b04052f738f2abe25c8c4 Improved helper macros and added separate Rhope stack in runtime diff -r d61550e2c001 -r 8d74ef7fa357 runtime/context.c --- /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 +#include +#include + +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; +} + diff -r d61550e2c001 -r 8d74ef7fa357 runtime/context.h --- /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_ diff -r d61550e2c001 -r 8d74ef7fa357 runtime/func.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 diff -r d61550e2c001 -r 8d74ef7fa357 runtime/integer.c --- 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) { diff -r d61550e2c001 -r 8d74ef7fa357 runtime/object.h --- 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; diff -r d61550e2c001 -r 8d74ef7fa357 test/test.c --- 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; }