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.
This commit is contained in:
Tor Andersson
2014-01-17 15:58:51 +01:00
parent f6c5c56b44
commit 10ffd559de
5 changed files with 33 additions and 30 deletions
+7
View File
@@ -9,6 +9,13 @@ js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *s
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);
+11 -9
View File
@@ -17,17 +17,18 @@ enum js_Type {
};
enum js_Class {
JS_CARRAY,
JS_CBOOLEAN,
JS_CCFUNCTION,
JS_CDATE,
JS_CERROR,
JS_CFUNCTION,
JS_CMATH,
JS_CNUMBER,
JS_COBJECT,
JS_CREGEXP,
JS_CARRAY,
JS_CFUNCTION,
JS_CSCRIPT, /* function created from global/eval code */
JS_CCFUNCTION, /* built-in function */
JS_CERROR,
JS_CBOOLEAN,
JS_CNUMBER,
JS_CSTRING,
JS_CREGEXP,
JS_CDATE,
JS_CMATH,
};
enum {
@@ -93,6 +94,7 @@ js_Property *jsR_nextproperty(js_State *J, js_Object *obj, const char *name);
/* 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);
+10 -15
View File
@@ -348,6 +348,13 @@ static void jsR_callfunction(js_State *J, int n, js_Function *F, js_Environment
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 @@ void js_call(js_State *J, int n)
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 @@ void js_call(js_State *J, int n)
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 @@ int jsR_loadscript(js_State *J, const char *filename, const char *source)
jsP_freeparse(J);
if (!F) return 1;
js_pushobject(J, jsR_newfunction(J, F, NULL));
js_pushobject(J, jsR_newscript(J, F));
return 0;
}
-1
View File
@@ -12,7 +12,6 @@ js_Environment *jsR_newenvironment(js_State *J, js_Object *variables, js_Environ
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);
+5 -5
View File
@@ -54,8 +54,8 @@ int js_dostring(js_State *J, const char *source)
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 @@ int js_dofile(js_State *J, const char *filename)
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 @@ static int jsB_eval(js_State *J, int argc)
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;
}