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);
}