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