shithub: libmujs

Download patch

ref: 10ffd559dea1f37fe3f0b7d6a5b179b956ebd2b5
parent: f6c5c56b446123b1d3ee7865870091a060ddd7d1
author: Tor Andersson <tor@ccxvii.net>
date: Fri Jan 17 10:58:51 EST 2014

Compile global/eval code as script objects rather than regular functions.

Handle scoping rules ath the js_call level instead of having to use
separate functions to call on the objects.

--- a/jsobject.c
+++ b/jsobject.c
@@ -9,6 +9,13 @@
 	return obj;
 }
 
+js_Object *jsR_newscript(js_State *J, js_Function *function)
+{
+	js_Object *obj = jsR_newobject(J, JS_CSCRIPT);
+	obj->function = function;
+	return obj;
+}
+
 js_Object *jsR_newcfunction(js_State *J, js_CFunction cfunction)
 {
 	js_Object *obj = jsR_newobject(J, JS_CCFUNCTION);
--- a/jsobject.h
+++ b/jsobject.h
@@ -17,17 +17,18 @@
 };
 
 enum js_Class {
+	JS_COBJECT,
 	JS_CARRAY,
-	JS_CBOOLEAN,
-	JS_CCFUNCTION,
-	JS_CDATE,
-	JS_CERROR,
 	JS_CFUNCTION,
-	JS_CMATH,
+	JS_CSCRIPT, /* function created from global/eval code */
+	JS_CCFUNCTION, /* built-in function */
+	JS_CERROR,
+	JS_CBOOLEAN,
 	JS_CNUMBER,
-	JS_COBJECT,
-	JS_CREGEXP,
 	JS_CSTRING,
+	JS_CREGEXP,
+	JS_CDATE,
+	JS_CMATH,
 };
 
 enum {
@@ -93,6 +94,7 @@
 
 /* jsobject.c */
 js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *scope);
+js_Object *jsR_newscript(js_State *J, js_Function *function);
 js_Object *jsR_newcfunction(js_State *J, js_CFunction cfunction);
 js_Object *jsR_newboolean(js_State *J, int v);
 js_Object *jsR_newnumber(js_State *J, double v);
--- a/jsrun.c
+++ b/jsrun.c
@@ -348,6 +348,13 @@
 	J->E = saveE;
 }
 
+static void jsR_callscript(js_State *J, int n, js_Function *F)
+{
+	js_pop(J, n);
+	jsR_run(J, F);
+	js_rot3pop2(J);
+}
+
 static void jsR_callcfunction(js_State *J, int n, js_CFunction F)
 {
 	int rv = F(J, n + 1);
@@ -368,6 +375,8 @@
 	bot = top - n - 1;
 	if (obj->type == JS_CFUNCTION)
 		jsR_callfunction(J, n, obj->function, obj->scope);
+	else if (obj->type == JS_CSCRIPT)
+		jsR_callscript(J, n, obj->function);
 	else if (obj->type == JS_CCFUNCTION)
 		jsR_callcfunction(J, n, obj->cfunction);
 	else
@@ -375,20 +384,6 @@
 	bot = savebot;
 }
 
-void js_eval(js_State *J)
-{
-	js_Object *obj = js_toobject(J, -2);
-	int savebot = bot;
-	bot = top - 1;
-	if (obj->type == JS_CFUNCTION) {
-		jsR_run(J, obj->function);
-		js_rot3pop2(J);
-	}
-	else
-		jsR_error(J, "TypeError (not a script)");
-	bot = savebot;
-}
-
 /* Main interpreter loop */
 
 void js_dumpstack(js_State *J)
@@ -743,7 +738,7 @@
 	jsP_freeparse(J);
 	if (!F) return 1;
 
-	js_pushobject(J, jsR_newfunction(J, F, NULL));
+	js_pushobject(J, jsR_newscript(J, F));
 	return 0;
 }
 
--- a/jsrun.h
+++ b/jsrun.h
@@ -12,7 +12,6 @@
 int jsR_loadscript(js_State *J, const char *filename, const char *source);
 
 void js_call(js_State *J, int n);
-void js_eval(js_State *J);
 
 void js_getglobal(js_State *J, const char *name);
 void js_setglobal(js_State *J, const char *name);
--- a/jsstate.c
+++ b/jsstate.c
@@ -54,8 +54,8 @@
 	if (!rv) {
 		if (setjmp(J->jb))
 			return 1;
-		js_dup(J, 0);
-		js_eval(J);
+		js_pushglobal(J);
+		js_call(J, 0);
 		js_pop(J, 1);
 	}
 	return rv;
@@ -67,8 +67,8 @@
 	if (!rv) {
 		if (setjmp(J->jb))
 			return 1;
-		js_dup(J, 0);
-		js_eval(J);
+		js_pushglobal(J);
+		js_call(J, 0);
 		js_pop(J, 1);
 	}
 	return rv;
@@ -100,7 +100,7 @@
 		jsR_error(J, "SyntaxError (eval)");
 
 	js_dup(J, 0); /* copy this */
-	js_eval(J); /* call with current scope chain */
+	js_call(J, 0);
 	return 1;
 }