shithub: libmujs

Download patch

ref: 195816c208ff272861e3d7f71f0837a147a18aea
parent: 2b209d3f55fb75fc2e6ce50e5fe89b4507cdd67a
author: Tor Andersson <[email protected]>
date: Thu Jan 23 12:53:22 EST 2014

Set property attributes on built-in objects and respect DontEnum.

--- a/js.h
+++ b/js.h
@@ -81,10 +81,12 @@
 
 void js_getglobal(js_State *J, const char *name);
 void js_setglobal(js_State *J, const char *name);
+void js_defglobal(js_State *J, const char *name, int atts);
 
 void js_getownproperty(js_State *J, int idx, const char *name);
 void js_getproperty(js_State *J, int idx, const char *name);
 void js_setproperty(js_State *J, int idx, const char *name);
+void js_defproperty(js_State *J, int idx, const char *name, int atts);
 void js_delproperty(js_State *J, int idx, const char *name);
 
 void js_pushglobal(js_State *J);
--- a/jsarray.c
+++ b/jsarray.c
@@ -24,5 +24,5 @@
 		/* ECMA-262-5 */
 		jsB_propf(J, "isArray", A_isArray, 1);
 	}
-	js_setglobal(J, "Array");
+	js_defglobal(J, "Array", JS_DONTENUM);
 }
--- a/jsboolean.c
+++ b/jsboolean.c
@@ -40,5 +40,5 @@
 		jsB_propf(J, "valueOf", Bp_valueOf, 0);
 	}
 	js_newcconstructor(J, jsB_Boolean, jsB_new_Boolean);
-	js_setglobal(J, "Boolean");
+	js_defglobal(J, "Boolean", JS_DONTENUM);
 }
--- a/jsbuiltin.c
+++ b/jsbuiltin.c
@@ -6,25 +6,25 @@
 static void jsB_globalf(js_State *J, const char *name, js_CFunction cfun, int n)
 {
 	js_newcfunction(J, cfun, n);
-	js_setglobal(J, name);
+	js_defglobal(J, name, JS_DONTENUM);
 }
 
 void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n)
 {
 	js_newcfunction(J, cfun, n);
-	js_setproperty(J, -2, name);
+	js_defproperty(J, -2, name, JS_DONTENUM);
 }
 
 void jsB_propn(js_State *J, const char *name, double number)
 {
 	js_pushnumber(J, number);
-	js_setproperty(J, -2, name);
+	js_defproperty(J, -2, name, JS_DONTENUM);
 }
 
 void jsB_props(js_State *J, const char *name, const char *string)
 {
 	js_pushliteral(J, string);
-	js_setproperty(J, -2, name);
+	js_defproperty(J, -2, name, JS_DONTENUM);
 }
 
 static int jsB_eval(js_State *J, int argc)
@@ -78,7 +78,7 @@
 	return 0;
 }
 
-static int jsB_collectGarbage(js_State *J, int argc)
+static int jsB_gc(js_State *J, int argc)
 {
 	int report = js_toboolean(J, 1);
 	js_gc(J, report);
@@ -116,13 +116,13 @@
 
 	/* Initialize the global object */
 	js_pushnumber(J, NAN);
-	js_setglobal(J, "NaN");
+	js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 
 	js_pushnumber(J, INFINITY);
-	js_setglobal(J, "Infinity");
+	js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 
 	js_pushundefined(J);
-	js_setglobal(J, "undefined");
+	js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 
 	jsB_globalf(J, "eval", jsB_eval, 1);
 	jsB_globalf(J, "parseInt", jsB_parseInt, 1);
@@ -130,6 +130,9 @@
 	jsB_globalf(J, "isNaN", jsB_isNaN, 1);
 	jsB_globalf(J, "isFinite", jsB_isFinite, 1);
 
-	jsB_globalf(J, "collectGarbage", jsB_collectGarbage, 0);
-	jsB_globalf(J, "print", jsB_print, 0);
+	/* Non-standard */
+	js_newcfunction(J, jsB_gc, 0);
+	js_setglobal(J, "gc");
+	js_newcfunction(J, jsB_print, 1);
+	js_setglobal(J, "print");
 }
--- a/jserror.c
+++ b/jserror.c
@@ -68,13 +68,13 @@
 			jsB_propf(J, "toString", Ep_toString, 0);
 	}
 	js_newcconstructor(J, jsB_Error, jsB_Error);
-	js_setglobal(J, "Error");
+	js_defglobal(J, "Error", JS_DONTENUM);
 
 	#define IERROR(NAME) \
 		js_pushobject(J, J->NAME##_prototype); \
 		jsB_props(J, "name", Q(NAME)); \
 		js_newcconstructor(J, jsB_##NAME, jsB_##NAME); \
-		js_setglobal(J, Q(NAME));
+		js_defglobal(J, Q(NAME), JS_DONTENUM);
 
 	IERROR(EvalError);
 	IERROR(RangeError);
--- a/jsfunction.c
+++ b/jsfunction.c
@@ -99,5 +99,5 @@
 		jsB_propf(J, "call", Fp_call, 1);
 	}
 	js_newcconstructor(J, jsB_Function, jsB_Function);
-	js_setglobal(J, "Function");
+	js_defglobal(J, "Function", JS_DONTENUM);
 }
--- a/jsmath.c
+++ b/jsmath.c
@@ -154,5 +154,5 @@
 		jsB_propf(J, "sqrt", Math_sqrt, 1);
 		jsB_propf(J, "tan", Math_tan, 1);
 	}
-	js_setglobal(J, "Math");
+	js_defglobal(J, "Math", JS_DONTENUM);
 }
--- a/jsnumber.c
+++ b/jsnumber.c
@@ -84,5 +84,5 @@
 		jsB_propn(J, "NEGATIVE_INFINITY", -INFINITY);
 		jsB_propn(J, "POSITIVE_INFINITY", INFINITY);
 	}
-	js_setglobal(J, "Number");
+	js_defglobal(J, "Number", JS_DONTENUM);
 }
--- a/jsobject.c
+++ b/jsobject.c
@@ -95,5 +95,5 @@
 		jsB_propf(J, "propertyIsEnumerable", Op_propertyIsEnumerable, 1);
 	}
 	js_newcconstructor(J, jsB_Object, jsB_new_Object);
-	js_setglobal(J, "Object");
+	js_defglobal(J, "Object", JS_DONTENUM);
 }
--- a/jsproperty.c
+++ b/jsproperty.c
@@ -144,11 +144,13 @@
 {
 	if (prop->right != &sentinel)
 		iter = itwalk(J, iter, prop->right, seen);
-	if (!seen || !jsV_getenumproperty(J, seen, prop->name)) {
-		js_Iterator *head = malloc(sizeof *head);
-		head->name = prop->name;
-		head->next = iter;
-		iter = head;
+	if (!(prop->atts & JS_DONTENUM)) {
+		if (!seen || !jsV_getenumproperty(J, seen, prop->name)) {
+			js_Iterator *head = malloc(sizeof *head);
+			head->name = prop->name;
+			head->next = iter;
+			iter = head;
+		}
 	}
 	if (prop->left != &sentinel)
 		iter = itwalk(J, iter, prop->left, seen);
--- a/jsrun.c
+++ b/jsrun.c
@@ -262,6 +262,16 @@
 	js_pop(J, 1);
 }
 
+void js_defglobal(js_State *J, const char *name, int atts)
+{
+	js_Property *ref = jsV_setproperty(J, J->G, name);
+	if (ref) {
+		ref->value = js_tovalue(J, -1);
+		ref->atts = atts;
+	}
+	js_pop(J, 1);
+}
+
 void js_getownproperty(js_State *J, int idx, const char *name)
 {
 	js_Object *obj = js_toobject(J, idx);
@@ -288,6 +298,17 @@
 	js_Property *ref = jsV_setproperty(J, obj, name);
 	if (ref)
 		ref->value = js_tovalue(J, -1);
+	js_pop(J, 1);
+}
+
+void js_defproperty(js_State *J, int idx, const char *name, int atts)
+{
+	js_Object *obj = js_toobject(J, idx);
+	js_Property *ref = jsV_setproperty(J, obj, name);
+	if (ref) {
+		ref->value = js_tovalue(J, -1);
+		ref->atts = atts;
+	}
 	js_pop(J, 1);
 }
 
--- a/jsstring.c
+++ b/jsstring.c
@@ -116,5 +116,5 @@
 	{
 		jsB_propf(J, "fromCharCode", S_fromCharCode, 1);
 	}
-	js_setglobal(J, "String");
+	js_defglobal(J, "String", JS_DONTENUM);
 }
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -241,13 +241,13 @@
 	js_pushobject(J, obj);
 	{
 		js_pushnumber(J, fun->numparams);
-		js_setproperty(J, -2, "length");
+		js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 		js_newobject(J);
 		{
 			js_copy(J, -2);
-			js_setproperty(J, -2, "constructor");
+			js_defproperty(J, -2, "constructor", JS_DONTENUM);
 		}
-		js_setproperty(J, -2, "prototype");
+		js_defproperty(J, -2, "prototype", JS_DONTDELETE);
 	}
 }
 
@@ -267,13 +267,13 @@
 	js_pushobject(J, obj);
 	{
 		js_pushnumber(J, length);
-		js_setproperty(J, -2, "length");
+		js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 		js_newobject(J);
 		{
 			js_copy(J, -2);
-			js_setproperty(J, -2, "constructor");
+			js_defproperty(J, -2, "constructor", JS_DONTENUM);
 		}
-		js_setproperty(J, -2, "prototype");
+		js_defproperty(J, -2, "prototype", JS_DONTDELETE);
 	}
 }
 
@@ -286,11 +286,11 @@
 	js_pushobject(J, obj); /* proto obj */
 	{
 		js_pushnumber(J, 1);
-		js_setproperty(J, -2, "length");
+		js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 		js_rot2(J); /* obj proto */
 		js_copy(J, -2); /* obj proto obj */
-		js_setproperty(J, -2, "constructor");
-		js_setproperty(J, -2, "prototype");
+		js_defproperty(J, -2, "constructor", JS_DONTENUM);
+		js_defproperty(J, -2, "prototype", JS_READONLY | JS_DONTENUM | JS_DONTDELETE);
 	}
 }