Implement Object.seal/freeze/preventExtensions

And the corresponding getters.

Change-Id: I5038ec3f87f932d65c67cafd36ec00b9970a5f51
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2012-11-28 23:10:03 +01:00 committed by Simon Hausmann
parent 4035e103cb
commit e75251e72b
1 changed files with 69 additions and 9 deletions

View File

@ -627,38 +627,98 @@ Value ObjectPrototype::method_defineProperties(ExecutionContext *ctx)
Value ObjectPrototype::method_seal(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.seal"));
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
if (o->members) {
PropertyTable::iterator it = o->members->begin();
while (it != o->members->end()) {
(*it)->descriptor.configurable = PropertyDescriptor::Unset;
++it;
}
}
return Value::undefinedValue();
}
Value ObjectPrototype::method_freeze(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.freeze"));
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
if (o->members) {
PropertyTable::iterator it = o->members->begin();
while (it != o->members->end()) {
if ((*it)->descriptor.isData())
(*it)->descriptor.writable = PropertyDescriptor::Unset;
(*it)->descriptor.configurable = PropertyDescriptor::Unset;
++it;
}
}
return Value::undefinedValue();
}
Value ObjectPrototype::method_preventExtensions(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.preventExtensions"));
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
return Value::undefinedValue();
}
Value ObjectPrototype::method_isSealed(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.isSealed"));
return Value::undefinedValue();
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
return Value::fromBoolean(false);
if (o->members) {
PropertyTable::iterator it = o->members->begin();
while (it != o->members->end()) {
if ((*it)->descriptor.configurable != PropertyDescriptor::Unset)
return Value::fromBoolean(false);
++it;
}
}
return Value::fromBoolean(true);
}
Value ObjectPrototype::method_isFrozen(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.isFrozen"));
return Value::undefinedValue();
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
return Value::fromBoolean(false);
if (o->members) {
PropertyTable::iterator it = o->members->begin();
while (it != o->members->end()) {
if ((*it)->descriptor.isData() &&
((*it)->descriptor.writable != PropertyDescriptor::Unset))
return Value::fromBoolean(false);
if ((*it)->descriptor.configurable != PropertyDescriptor::Unset)
return Value::fromBoolean(false);
++it;
}
}
return Value::fromBoolean(true);
}
Value ObjectPrototype::method_isExtensible(ExecutionContext *ctx)
{
ctx->throwUnimplemented(QStringLiteral("Object.isExtensible"));
return Value::undefinedValue();
if (!ctx->argument(0).isObject())
__qmljs_throw_type_error(ctx);
Object *o = ctx->argument(0).objectValue();
return Value::fromBoolean(o->extensible);
}
Value ObjectPrototype::method_keys(ExecutionContext *ctx)