shithub: libmujs

Download patch

ref: 3fe66354265ae2a78c71df02808acf427a47c5c2
parent: 7d771cb0d93c7331b866af3a4bf2d9503a18d8d0
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Oct 27 12:11:23 EDT 2014

Differentiate between "global code" and "eval code" scripts.

Add a separate js_loadeval for "eval code" scripts, and let
js_do/loadstring create "global code" scripts.

js_newscript called with the NULL scope is equivalent to 'eval code'.
js_newscript called with the J->GE scape is equivalent to 'global code'.
js_newfunction is created with the lexical scope, i.e. 'function code'.

--- a/jsbuiltin.c
+++ b/jsbuiltin.c
@@ -34,7 +34,7 @@
 		js_copy(J, 1);
 		return;
 	}
-	js_loadstring(J, "(eval)", js_tostring(J, -1));
+	js_loadeval(J, "(eval)", js_tostring(J, -1));
 	js_pushglobal(J);
 	js_call(J, 0);
 }
--- a/jsi.h
+++ b/jsi.h
@@ -71,7 +71,8 @@
 /* Private stack functions */
 
 void js_newfunction(js_State *J, js_Function *function, js_Environment *scope);
-void js_newscript(js_State *J, js_Function *function);
+void js_newscript(js_State *J, js_Function *function, js_Environment *scope);
+void js_loadeval(js_State *J, const char *filename, const char *source);
 
 js_Regexp *js_toregexp(js_State *J, int idx);
 int js_isarrayindex(js_State *J, const char *str, unsigned int *idx);
--- a/jsrun.c
+++ b/jsrun.c
@@ -890,14 +890,21 @@
 	jsR_restorescope(J);
 }
 
-static void jsR_callscript(js_State *J, unsigned int n, js_Function *F)
+static void jsR_callscript(js_State *J, unsigned int n, js_Function *F, js_Environment *scope)
 {
 	js_Value v;
+
+	if (scope)
+		jsR_savescope(J, scope);
+
 	js_pop(J, n);
 	jsR_run(J, F);
 	v = js_tovalue(J, -1);
 	TOP = --BOT; /* clear stack */
 	js_pushvalue(J, v);
+
+	if (scope)
+		jsR_restorescope(J);
 }
 
 static void jsR_callcfunction(js_State *J, unsigned int n, unsigned int min, js_CFunction F)
@@ -933,7 +940,7 @@
 		else
 			jsR_callfunction(J, n, obj->u.f.function, obj->u.f.scope);
 	} else if (obj->type == JS_CSCRIPT)
-		jsR_callscript(J, n, obj->u.f.function);
+		jsR_callscript(J, n, obj->u.f.function, obj->u.f.scope);
 	else if (obj->type == JS_CCFUNCTION)
 		jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.function);
 
--- a/jsstate.c
+++ b/jsstate.c
@@ -40,7 +40,7 @@
 	return 0;
 }
 
-void js_loadstring(js_State *J, const char *filename, const char *source)
+static void js_loadstringx(js_State *J, const char *filename, const char *source, int iseval)
 {
 	js_Ast *P;
 	js_Function *F;
@@ -53,9 +53,19 @@
 	P = jsP_parse(J, filename, source);
 	F = jsC_compile(J, P);
 	jsP_freeparse(J);
-	js_newscript(J, F);
+	js_newscript(J, F, iseval ? NULL : J->GE);
 
 	js_endtry(J);
+}
+
+void js_loadeval(js_State *J, const char *filename, const char *source)
+{
+	js_loadstringx(J, filename, source, 1);
+}
+
+void js_loadstring(js_State *J, const char *filename, const char *source)
+{
+	js_loadstringx(J, filename, source, 0);
 }
 
 void js_loadfile(js_State *J, const char *filename)
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -339,11 +339,11 @@
 	}
 }
 
-void js_newscript(js_State *J, js_Function *fun)
+void js_newscript(js_State *J, js_Function *fun, js_Environment *scope)
 {
 	js_Object *obj = jsV_newobject(J, JS_CSCRIPT, NULL);
 	obj->u.f.function = fun;
-	obj->u.f.scope = NULL;
+	obj->u.f.scope = scope;
 	js_pushobject(J, obj);
 }