mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 07:03:36 +08:00
Implement extensible object attribute.
This commit is contained in:
+109
-6
@@ -292,6 +292,109 @@ static int O_keys(js_State *J, int argc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_preventExtensions(js_State *J, int argc)
|
||||
{
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
js_toobject(J, 1)->extensible = 0;
|
||||
js_copy(J, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_isExtensible(js_State *J, int argc)
|
||||
{
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
js_pushboolean(J, js_toobject(J, 1)->extensible);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_seal(js_State *J, int argc)
|
||||
{
|
||||
js_Object *obj;
|
||||
js_Property *ref;
|
||||
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
|
||||
obj = js_toobject(J, 1);
|
||||
obj->extensible = 0;
|
||||
|
||||
for (ref = obj->head; ref; ref = ref->next)
|
||||
ref->atts |= JS_DONTCONF;
|
||||
|
||||
js_copy(J, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_isSealed(js_State *J, int argc)
|
||||
{
|
||||
js_Object *obj;
|
||||
js_Property *ref;
|
||||
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
|
||||
obj = js_toobject(J, 1);
|
||||
if (obj->extensible) {
|
||||
js_pushboolean(J, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (ref = obj->head; ref; ref = ref->next) {
|
||||
if (!(ref->atts & JS_DONTCONF)) {
|
||||
js_pushboolean(J, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
js_pushboolean(J, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_freeze(js_State *J, int argc)
|
||||
{
|
||||
js_Object *obj;
|
||||
js_Property *ref;
|
||||
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
|
||||
obj = js_toobject(J, 1);
|
||||
obj->extensible = 0;
|
||||
|
||||
for (ref = obj->head; ref; ref = ref->next)
|
||||
ref->atts |= JS_READONLY | JS_DONTCONF;
|
||||
|
||||
js_copy(J, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int O_isFrozen(js_State *J, int argc)
|
||||
{
|
||||
js_Object *obj;
|
||||
js_Property *ref;
|
||||
|
||||
if (!js_isobject(J, 1))
|
||||
js_typeerror(J, "not an object");
|
||||
|
||||
obj = js_toobject(J, 1);
|
||||
if (obj->extensible) {
|
||||
js_pushboolean(J, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (ref = obj->head; ref; ref = ref->next) {
|
||||
if (!(ref->atts & (JS_READONLY | JS_DONTCONF))) {
|
||||
js_pushboolean(J, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
js_pushboolean(J, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void jsB_initobject(js_State *J)
|
||||
{
|
||||
js_pushobject(J, J->Object_prototype);
|
||||
@@ -312,12 +415,12 @@ void jsB_initobject(js_State *J)
|
||||
jsB_propf(J, "create", O_create, 2);
|
||||
jsB_propf(J, "defineProperty", O_defineProperty, 3);
|
||||
jsB_propf(J, "defineProperties", O_defineProperties, 2);
|
||||
//jsB_propf(J, "seal", O_seal, 1);
|
||||
//jsB_propf(J, "freeze", O_freeze, 1);
|
||||
//jsB_propf(J, "preventExtensions", O_preventExtensions, 1);
|
||||
//jsB_propf(J, "isSealed", O_isSealed, 1);
|
||||
//jsB_propf(J, "isFrozen", O_isFrozen, 1);
|
||||
//jsB_propf(J, "isExtensible", O_isExtensible, 1);
|
||||
jsB_propf(J, "seal", O_seal, 1);
|
||||
jsB_propf(J, "freeze", O_freeze, 1);
|
||||
jsB_propf(J, "preventExtensions", O_preventExtensions, 1);
|
||||
jsB_propf(J, "isSealed", O_isSealed, 1);
|
||||
jsB_propf(J, "isFrozen", O_isFrozen, 1);
|
||||
jsB_propf(J, "isExtensible", O_isExtensible, 1);
|
||||
jsB_propf(J, "keys", O_keys, 1);
|
||||
}
|
||||
js_defglobal(J, "Object", JS_DONTENUM);
|
||||
|
||||
@@ -155,6 +155,7 @@ js_Object *jsV_newobject(js_State *J, js_Class type, js_Object *prototype)
|
||||
obj->type = type;
|
||||
obj->properties = &sentinel;
|
||||
obj->prototype = prototype;
|
||||
obj->extensible = 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -190,6 +191,10 @@ js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name)
|
||||
js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name)
|
||||
{
|
||||
js_Property *result;
|
||||
|
||||
if (!obj->extensible)
|
||||
return lookup(obj->properties, name);
|
||||
|
||||
obj->properties = insert(J, obj->properties, name, &result);
|
||||
if (!result->prevp) {
|
||||
if (!obj->head) {
|
||||
|
||||
@@ -467,7 +467,7 @@ static void jsR_setproperty(js_State *J, js_Object *obj, const char *name, const
|
||||
if (!ref || !own)
|
||||
ref = jsV_setproperty(J, obj, name);
|
||||
|
||||
if (!(ref->atts & JS_READONLY))
|
||||
if (ref && !(ref->atts & JS_READONLY))
|
||||
ref->value = *value;
|
||||
}
|
||||
|
||||
@@ -491,13 +491,15 @@ static void jsR_defproperty(js_State *J, js_Object *obj, const char *name,
|
||||
}
|
||||
|
||||
ref = jsV_setproperty(J, obj, name);
|
||||
if (value && !(ref->atts & JS_READONLY))
|
||||
ref->value = *value;
|
||||
if (getter && !(ref->atts & JS_DONTCONF))
|
||||
ref->getter = getter;
|
||||
if (setter && !(ref->atts & JS_DONTCONF))
|
||||
ref->setter = setter;
|
||||
ref->atts |= atts;
|
||||
if (ref) {
|
||||
if (value && !(ref->atts & JS_READONLY))
|
||||
ref->value = *value;
|
||||
if (getter && !(ref->atts & JS_DONTCONF))
|
||||
ref->getter = getter;
|
||||
if (setter && !(ref->atts & JS_DONTCONF))
|
||||
ref->setter = setter;
|
||||
ref->atts |= atts;
|
||||
}
|
||||
}
|
||||
|
||||
static int jsR_delproperty(js_State *J, js_Object *obj, const char *name)
|
||||
|
||||
Reference in New Issue
Block a user