From 55043320b8ef419b0af39c458065fc7366052f50 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 26 Mar 2006 16:36:30 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.c | 3 +- ase/awk/awk.h | 3 +- ase/awk/run.c | 118 +++++++++++++++++++++++++++++++++++++++++++------- ase/awk/val.c | 46 ++++++++++++++------ ase/awk/val.h | 4 +- 5 files changed, 142 insertions(+), 32 deletions(-) diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 4d7df0e0..61995ae6 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.31 2006-03-24 06:33:36 bacon Exp $ + * $Id: awk.c,v 1.32 2006-03-26 16:36:30 bacon Exp $ */ #include @@ -89,6 +89,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) awk->run.stack_top = 0; awk->run.stack_base = 0; awk->run.stack_limit = 0; + awk->run.exit_level = 0; awk->lex.curc = XP_CHAR_EOF; awk->lex.ungotc_count = 0; diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 35e20ce2..cfec625c 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.35 2006-03-25 17:04:36 bacon Exp $ + * $Id: awk.h,v 1.36 2006-03-26 16:36:30 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -97,6 +97,7 @@ struct xp_awk_t xp_size_t stack_top; xp_size_t stack_base; xp_size_t stack_limit; + int exit_level; } run; /* source buffer management */ diff --git a/ase/awk/run.c b/ase/awk/run.c index 70b75b1a..12c7f803 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.18 2006-03-26 14:03:08 bacon Exp $ + * $Id: run.c,v 1.19 2006-03-26 16:36:30 bacon Exp $ */ #include @@ -16,6 +16,11 @@ #define STACK_NARGS(awk) ((xp_size_t)STACK_AT(awk,3)) #define STACK_ARG(awk,n) STACK_AT(awk,3+1+(n)) #define STACK_LOCAL(awk,n) STACK_AT(awk,3+STACK_NARGS(awk)+1+(n)) +#define STACK_RETVAL(awk) STACK_AT(awk,2) + +#define EXIT_NONE 0 +#define EXIT_FUNCTION 1 +#define EXIT_GLOBAL 2 static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde); static int __run_statement (xp_awk_t* awk, xp_awk_nde_t* nde); @@ -33,7 +38,7 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde); static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde); static int __raw_push (xp_awk_t* awk, void* val); -static int __raw_pop (xp_awk_t* awk); +static void __raw_pop (xp_awk_t* awk); int __printval (xp_awk_pair_t* pair) { @@ -45,6 +50,9 @@ int __printval (xp_awk_pair_t* pair) int xp_awk_run (xp_awk_t* awk) { + // TODO: clear run stack/exit_level + awk->run.exit_level = EXIT_NONE; + if (awk->tree.begin != XP_NULL) { xp_assert (awk->tree.begin->type == XP_AWK_NDE_BLK); @@ -89,7 +97,7 @@ static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde) } //xp_printf (XP_TEXT("executing block statements\n")); - while (p != XP_NULL) + while (p != XP_NULL && awk->run.exit_level == EXIT_NONE) { if (__run_statement(awk,p) == -1) return -1; p = p->next; @@ -336,10 +344,14 @@ static int __run_return_statement (xp_awk_t* awk, xp_awk_nde_return_t* nde) //xp_printf (XP_TEXT("returning....\n")); val = __eval_expression(awk, nde->val); if (val == XP_NULL) return -1; - awk->run.stack[awk->run.stack_base+2] = val; + + STACK_RETVAL(awk) = val; + xp_awk_refupval (val); /* see run_funccall for the trick */ + //xp_printf (XP_TEXT("set return value....\n")); } -// TODO: make the function exit.... + + awk->run.exit_level = EXIT_FUNCTION; return 0; } @@ -480,14 +492,21 @@ static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde) } else if (tgt->type == XP_AWK_NDE_GLOBAL) { + /* + xp_awk_refdownval(STACK_GLOBAL(awk,tgt->id.idxa)); + STACK_GLOBAL(awk,tgt->id.idxa) = val; + xp_awk_refupval (val); + */ } else if (tgt->type == XP_AWK_NDE_LOCAL) { + xp_awk_refdownval(STACK_LOCAL(awk,tgt->id.idxa)); STACK_LOCAL(awk,tgt->id.idxa) = val; xp_awk_refupval (val); } else if (tgt->type == XP_AWK_NDE_ARG) { + xp_awk_refdownval(STACK_ARG(awk,tgt->id.idxa)); STACK_ARG(awk,tgt->id.idxa) = val; xp_awk_refupval (val); } @@ -544,7 +563,24 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) xp_long_t r = ((xp_awk_val_int_t*)left)->val + ((xp_awk_val_int_t*)right)->val; - res = xp_awk_makeintval (r); + + // TODO: consider the code segement commented out below for optimization.... + /* + if (!xp_awk_isbuiltinval(left) && left->ref <= 1) + { + ((xp_awk_val_int_t*)left)->val = r; + res = left; + } + else if (!xp_awk_isbuiltinval(right) && right->ref <= 1) + { + ((xp_awk_val_int_t*)right)->val = r; + res = right; + } + else + { + */ + res = xp_awk_makeintval (r); + //} } } else if (nde->opcode == XP_AWK_BINOP_MINUS) @@ -555,12 +591,43 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) xp_long_t r = ((xp_awk_val_int_t*)left)->val - ((xp_awk_val_int_t*)right)->val; - res = xp_awk_makeintval (r); + + /* + if (!xp_awk_isbuiltinval(left) && left->ref <= 1) + { + ((xp_awk_val_int_t*)left)->val = r; + res = left; + } + else if (!xp_awk_isbuiltinval(right) && right->ref <= 1) + { + ((xp_awk_val_int_t*)right)->val = r; + res = right; + } + else + { + */ + res = xp_awk_makeintval (r); + //} } } - - xp_awk_refdownval(left); - xp_awk_refdownval(right); + + /* + if (res == left) + { + xp_awk_refdownval_nofree (left); + xp_awk_refdownval (right); + } + else if (res == right) + { + xp_awk_refdownval (left); + xp_awk_refdownval_nofree (right); + } + else + { + */ + xp_awk_refdownval (left); + xp_awk_refdownval (right); + //} return res; } @@ -579,7 +646,13 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) /* * --------------------- - * argn <- stack top + * locn <- stack top + * --------------------- + * .... + * --------------------- + * loc0 local variables are pushed by __run_block + * --------------------- + * argn * --------------------- * .... * --------------------- @@ -593,7 +666,7 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) * --------------------- * previous stack top * --------------------- - * previous stack base <- stack base + * previous stack base <- stack base * --------------------- */ @@ -657,7 +730,12 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) //xp_printf (XP_TEXT("running function body\n")); xp_assert (func->body->type == XP_AWK_NDE_BLK); - if (__run_block(awk,(xp_awk_nde_blk_t*)func->body) == -1) return XP_NULL; + if (__run_block(awk,(xp_awk_nde_blk_t*)func->body) == -1) + { + // TODO: handle error properly.... + return XP_NULL; + } + //xp_printf (XP_TEXT("block run complete\n")); /* refdown args in the run.stack */ @@ -668,11 +746,21 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) xp_awk_refdownval (STACK_ARG(awk,i)); } //xp_printf (XP_TEXT("got return value\n")); - v = awk->run.stack[awk->run.stack_base+2]; + + /* adjust the reference count of the return value. + * the value must not be freeed event if the reference count + * is decremented to zero. */ + v = STACK_RETVAL(awk); + xp_awk_refdownval_nofree (v); awk->run.stack_top = (xp_size_t)awk->run.stack[awk->run.stack_base+1]; awk->run.stack_base = (xp_size_t)awk->run.stack[awk->run.stack_base+0]; + if (awk->run.exit_level == EXIT_FUNCTION) + { + awk->run.exit_level = EXIT_NONE; + } + //xp_printf (XP_TEXT("returning from function stack_top=%ld, stack_base=%ld\n"), awk->run.stack_top, awk->run.stack_base); return v; } @@ -696,7 +784,7 @@ static int __raw_push (xp_awk_t* awk, void* val) return 0; } -static int __raw_pop (xp_awk_t* awk) +static void __raw_pop (xp_awk_t* awk) { xp_assert (awk->run.stack_top > awk->run.stack_base); awk->run.stack_top--; diff --git a/ase/awk/val.c b/ase/awk/val.c index d88aedad..53922679 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.9 2006-03-23 15:36:20 bacon Exp $ + * $Id: val.c,v 1.10 2006-03-26 16:36:30 bacon Exp $ */ #include @@ -41,6 +41,7 @@ xp_awk_val_t* xp_awk_makeintval (xp_long_t v) if (val == XP_NULL) return XP_NULL; val->type = XP_AWK_VAL_INT; + val->ref = 0; val->val = v; return (xp_awk_val_t*)val; @@ -54,6 +55,7 @@ xp_awk_val_t* xp_awk_makerealval (xp_real_t v) if (val == XP_NULL) return XP_NULL; val->type = XP_AWK_VAL_REAL; + val->ref = 0; val->val = v; return (xp_awk_val_t*)val; @@ -67,6 +69,7 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len) if (val == XP_NULL) return XP_NULL; val->type = XP_AWK_VAL_STR; + val->ref = 0; val->len = len; val->buf = xp_strxdup (str, len); if (val->buf == XP_NULL) { @@ -77,11 +80,16 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len) return (xp_awk_val_t*)val; } +xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val) +{ + return val == XP_NULL || val == xp_awk_val_nil || + (val >= (xp_awk_val_t*)&__awk_int[0] && + val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]); +} + void xp_awk_freeval (xp_awk_val_t* val) { - if (val == XP_NULL || val == xp_awk_val_nil) return; - if (val >= (xp_awk_val_t*)&__awk_int[0] && - val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return; + if (xp_awk_isbuiltinval(val)) return; switch (val->type) { @@ -94,34 +102,44 @@ void xp_awk_freeval (xp_awk_val_t* val) void xp_awk_refupval (xp_awk_val_t* val) { - if (val == XP_NULL || val == xp_awk_val_nil) return; - if (val >= (xp_awk_val_t*)&__awk_int[0] && - val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return; - + if (xp_awk_isbuiltinval(val)) return; /* xp_printf (XP_TEXT("ref up ")); xp_awk_printval (val); xp_printf (XP_TEXT("\n")); */ - val->ref++; } void xp_awk_refdownval (xp_awk_val_t* val) { - if (val == XP_NULL || val == xp_awk_val_nil) return; - if (val >= (xp_awk_val_t*)&__awk_int[0] && - val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return; + if (xp_awk_isbuiltinval(val)) return; /* -xp_printf (XP_TEXT("ref down ")); +xp_printf (XP_TEXT("ref down [count=>%d]\n"), val->ref); xp_awk_printval (val); xp_printf (XP_TEXT("\n")); */ xp_assert (val->ref > 0); val->ref--; - if (val->ref <= 0) xp_awk_freeval(val); + if (val->ref <= 0) + { +/* +xp_printf (XP_TEXT("**FREEING ")); +xp_awk_printval (val); +xp_printf (XP_TEXT("\n")); +*/ + xp_awk_freeval(val); + } +} + +void xp_awk_refdownval_nofree (xp_awk_val_t* val) +{ + if (xp_awk_isbuiltinval(val)) return; + + xp_assert (val->ref > 0); + val->ref--; } xp_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val) diff --git a/ase/awk/val.h b/ase/awk/val.h index c5b53cbf..15b433ad 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.7 2006-03-23 13:26:04 bacon Exp $ + * $Id: val.h,v 1.8 2006-03-26 16:36:30 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -69,9 +69,11 @@ extern xp_awk_val_t* xp_awk_val_nil; xp_awk_val_t* xp_awk_makeintval (xp_long_t v); xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len); +xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val); void xp_awk_freeval (xp_awk_val_t* val); void xp_awk_refupval (xp_awk_val_t* val); void xp_awk_refdownval (xp_awk_val_t* val); +void xp_awk_refdownval_nofree (xp_awk_val_t* val); xp_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val); xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val);