shithub: libmujs

Download patch

ref: 4a3fdcef74fe15a1b36ef1185d9b825ab7fba26d
parent: ede0f888ced2b7334e23a6a6ccf21c149712c116
author: Tor Andersson <tor@ccxvii.net>
date: Wed Jan 15 19:10:57 EST 2014

Functions!

--- a/jscompile.c
+++ b/jscompile.c
@@ -11,7 +11,7 @@
 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,6 +21,14 @@
 	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);
@@ -27,7 +35,9 @@
 	memset(F, 0, sizeof *F);
 
 	F->name = name ? name->string : "<anonymous>";
-	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;
--- a/jscompile.h
+++ b/jscompile.h
@@ -90,6 +90,7 @@
 {
 	const char *name;
 	int numparams;
+	const char **params;
 
 	short *code;
 	int codecap, codelen;
--- a/jsdump.c
+++ b/jsdump.c
@@ -595,7 +595,10 @@
 	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++) {
--- a/jsrun.c
+++ b/jsrun.c
@@ -8,8 +8,18 @@
 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)
 {
 	double sign = n < 0 ? -1 : 1;
@@ -235,6 +245,7 @@
 
 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 @@
 	js_Object *obj;
 	js_Property *ref;
 	double x, y;
-	int b, argc;
+	int b;
 
 	while (1) {
 		opcode = *pc++;
@@ -353,6 +364,10 @@
 			}
 			break;
 
+		case OP_CALL:
+			js_call(J, *pc++);
+			break;
+
 		/* Unary expressions */
 
 		case OP_POS:
@@ -533,9 +548,34 @@
 	}
 }
 
-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;
@@ -547,16 +587,6 @@
 	fprintf(stderr, "\n");
 
 	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)