ref: d5b83c3bf2d15a5f037088e53a6ef5f4c67656e0
parent: 979c7bc1bd282ff5a6158ea984557fbf5f51af6d
author: Tor Andersson <tor@ccxvii.net>
date: Fri Feb 7 06:44:39 EST 2014
Implement Function constructor.
--- a/jscompile.c
+++ b/jscompile.c
@@ -1109,6 +1109,11 @@
}
}
+js_Function *jsC_compilefunction(js_State *J, js_Ast *prog)
+{
+ return newfun(J, prog->a, prog->b, prog->c, 0);
+}
+
js_Function *jsC_compile(js_State *J, js_Ast *prog)
{
return newfun(J, NULL, NULL, prog, 1);
--- a/jscompile.h
+++ b/jscompile.h
@@ -138,6 +138,7 @@
int gcmark;
};
+js_Function *jsC_compilefunction(js_State *J, js_Ast *prog);
js_Function *jsC_compile(js_State *J, js_Ast *prog);
const char *jsC_opcodestring(int opcode);
void jsC_dumpfunction(js_State *J, js_Function *fun);
--- a/jsfunction.c
+++ b/jsfunction.c
@@ -1,4 +1,5 @@
#include "jsi.h"
+#include "jsparse.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
@@ -5,7 +6,41 @@
static int jsB_Function(js_State *J, int argc)
{
- return 0;
+ const char *source;
+ struct sbuffer *sb;
+ js_Ast *parse;
+ js_Function *fun;
+ int i;
+
+ if (argc == 0)
+ source = "";
+ else {
+ source = js_tostring(J, argc);
+ sb = NULL;
+ if (argc > 1) {
+ for (i = 1; i < argc; ++i) {
+ if (i > 1) sb = sb_putc(sb, ',');
+ sb = sb_puts(sb, js_tostring(J, i));
+ }
+ sb = sb_putc(sb, ')');
+ }
+ }
+
+ if (js_try(J)) {
+ free(sb);
+ jsP_freeparse(J);
+ js_throw(J);
+ }
+
+ parse = jsP_parsefunction(J, "Function", sb->s, source);
+ fun = jsC_compilefunction(J, parse);
+
+ js_endtry(J);
+ free(sb);
+ jsP_freeparse(J);
+
+ js_newfunction(J, fun, J->GE);
+ return 1;
}
static int jsB_Function_prototype(js_State *J, int argc)
--- a/jsi.h
+++ b/jsi.h
@@ -116,6 +116,7 @@
js_Object *R; /* registry of hidden values */
js_Object *G; /* the global object */
js_Environment *E; /* current environment scope */
+ js_Environment *GE; /* global environment scope (at the root) */
/* execution stack */
int top, bot;
--- a/jsparse.c
+++ b/jsparse.c
@@ -967,3 +967,14 @@
return p;
}
+
+js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body)
+{
+ js_Ast *p = NULL;
+ if (params) {
+ jsY_initlex(J, filename, params);
+ next(J);
+ p = parameters(J);
+ }
+ return EXP3(FUN, NULL, p, jsP_parse(J, filename, body));
+}
--- a/jsparse.h
+++ b/jsparse.h
@@ -136,6 +136,7 @@
js_Ast *gcnext; /* next in alloc list */
};
+js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body);
js_Ast *jsP_parse(js_State *J, const char *filename, const char *source);
void jsP_freeparse(js_State *J);
--- a/jsstate.c
+++ b/jsstate.c
@@ -114,6 +114,7 @@
J->R = jsV_newobject(J, JS_COBJECT, NULL);
J->G = jsV_newobject(J, JS_COBJECT, NULL);
J->E = jsR_newenvironment(J, J->G, NULL);
+ J->GE = J->E;
jsB_init(J);