shithub: libmujs

Download patch

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