diff --git a/jscompile.c b/jscompile.c index 1cb9dc7..d1eca43 100644 --- a/jscompile.c +++ b/jscompile.c @@ -11,7 +11,7 @@ static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body); static void cexp(JF, js_Ast *exp); static void cstmlist(JF, js_Ast *list); -static int listlen(js_Ast *list) +static int paramlen(js_Ast *list) { int n = 0; while (list) { @@ -21,13 +21,23 @@ static int listlen(js_Ast *list) return n; } +static void makeparams(JF, js_Ast *list, const char **params) +{ + while (list) { + *params++ = list->a->string; + list = list->b; + } +} + static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *body) { js_Function *F = malloc(sizeof *F); memset(F, 0, sizeof *F); F->name = name ? name->string : ""; - F->numparams = listlen(params); + F->numparams = paramlen(params); + F->params = malloc(F->numparams * sizeof *F->params); + makeparams(J, F, params, F->params); F->codecap = 256; F->codelen = 0; diff --git a/jscompile.h b/jscompile.h index 94dd1b6..a0ef95c 100644 --- a/jscompile.h +++ b/jscompile.h @@ -90,6 +90,7 @@ struct js_Function { const char *name; int numparams; + const char **params; short *code; int codecap, codelen; diff --git a/jsdump.c b/jsdump.c index b6b5ad5..4e20d3c 100644 --- a/jsdump.c +++ b/jsdump.c @@ -595,7 +595,10 @@ void jsC_dumpfunction(js_State *J, js_Function *F) short *end = F->code + F->codelen; int i; - printf("function %p %s(%d)\n", F, F->name, F->numparams); + printf("function %p %s(", F, F->name); + for (i = 0; i < F->numparams; i++) + printf("%s%s", i > 0 ? ", " : "", F->params[i]); + printf(")\n"); for (i = 0; i < F->funlen; i++) printf("\tfunction %p %s\n", F->funtab[i], F->funtab[i]->name); for (i = 0; i < F->strlen; i++) { diff --git a/jsrun.c b/jsrun.c index 0cac3f6..03be42a 100644 --- a/jsrun.c +++ b/jsrun.c @@ -8,7 +8,17 @@ static js_Value stack[256]; static int top = 0; static int bot = 0; -static void js_call(js_State *J, js_Object *obj, int argc); +static void js_call(js_State *J, int argc); + +static void js_dumpstack(js_State *J) +{ + int i; + for (i = 0; i < top; i++) { + printf("stack %d: ", i); + js_dumpvalue(J, stack[i]); + putchar('\n'); + } +} static inline double tointeger(double n) { @@ -235,6 +245,7 @@ void js_dup1rot4(js_State *J) void js_trap(js_State *J) { + js_dumpstack(J); } static void runfun(js_State *J, js_Function *F, js_Environment *E) @@ -250,7 +261,7 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E) js_Object *obj; js_Property *ref; double x, y; - int b, argc; + int b; while (1) { opcode = *pc++; @@ -353,6 +364,10 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E) } break; + case OP_CALL: + js_call(J, *pc++); + break; + /* Unary expressions */ case OP_POS: @@ -533,9 +548,34 @@ static void runfun(js_State *J, js_Function *F, js_Environment *E) } } -void jsR_error(js_State *J, const char *message) +static void js_call(js_State *J, int argc) { - fprintf(stderr, "runtime error: %s\n", message); + js_Environment *E; + js_Property *ref; + js_Function *F; + js_Object *obj; + int i; + int savebot = bot; + + bot = top - argc; + + obj = js_toobject(J, -argc - 1); + + F = obj->function; + E = js_newenvironment(J, obj->scope, js_newobject(J, JS_COBJECT)); + + for (i = 0; i < F->numparams; i++) { + ref = js_decvar(J, E, F->params[i]); + if (i + 1 < argc) + ref->value = js_tovalue(J, i + 1); + } + js_pop(J, argc + 1); + + runfun(J, F, E); + + bot = savebot; +} + void jsR_error(js_State *J, const char *fmt, ...) { va_list ap; @@ -549,16 +589,6 @@ void jsR_error(js_State *J, const char *fmt, ...) longjmp(J->jb, 1); } -static void js_dumpstack(js_State *J) -{ - int i; - for (i = 0; i < top; i++) { - printf("stack %d: ", i); - js_dumpvalue(J, stack[i]); - putchar('\n'); - } -} - void jsR_runfunction(js_State *J, js_Function *F) { if (setjmp(J->jb)) {