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