1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 08:35:09 +00:00

LibJS: Add Proxy objects

Includes all traps except the following: [[Call]], [[Construct]],
[[OwnPropertyKeys]].

An important implication of this commit is that any call to any virtual
Object method has the potential to throw an exception. These methods
were not checked in this commit -- a future commit will have to protect
these various method calls throughout the codebase.
This commit is contained in:
Matthew Olsson 2020-06-03 14:34:52 -07:00 committed by Andreas Kling
parent 58a72e9b81
commit 39ad42defd
29 changed files with 1697 additions and 54 deletions

View file

@ -98,7 +98,7 @@ Value ObjectConstructor::get_prototype_of(Interpreter& interpreter)
Value ObjectConstructor::set_prototype_of(Interpreter& interpreter)
{
if (interpreter.argument_count() < 2)
interpreter.throw_exception<TypeError>("Object.setPrototypeOf requires at least two arguments");
return interpreter.throw_exception<TypeError>("Object.setPrototypeOf requires at least two arguments");
auto* object = interpreter.argument(0).to_object(interpreter);
if (interpreter.exception())
return {};
@ -113,7 +113,8 @@ Value ObjectConstructor::set_prototype_of(Interpreter& interpreter)
return {};
}
if (!object->set_prototype(prototype)) {
interpreter.throw_exception<TypeError>("Can't set prototype of non-extensible object");
if (!interpreter.exception())
interpreter.throw_exception<TypeError>("Object's setPrototypeOf method returned false");
return {};
}
return object;
@ -133,7 +134,8 @@ Value ObjectConstructor::prevent_extensions(Interpreter& interpreter)
if (!argument.is_object())
return argument;
if (!argument.as_object().prevent_extensions()) {
interpreter.throw_exception<TypeError>("Proxy preventExtensions handler returned false");
if (!interpreter.exception())
interpreter.throw_exception<TypeError>("Proxy preventExtensions handler returned false");
return {};
}
return argument;
@ -161,7 +163,16 @@ Value ObjectConstructor::define_property_(Interpreter& interpreter)
if (interpreter.exception())
return {};
auto& descriptor = interpreter.argument(2).as_object();
object.define_property(property_key, descriptor);
if (!object.define_property(property_key, descriptor)) {
if (!interpreter.exception()) {
if (object.is_proxy_object()) {
interpreter.throw_exception<TypeError>("Proxy handler's defineProperty method returned false");
} else {
interpreter.throw_exception<TypeError>("Unable to define property on non-extensible object");
}
}
return {};
}
return &object;
}
@ -179,7 +190,7 @@ Value ObjectConstructor::keys(Interpreter& interpreter)
if (interpreter.exception())
return {};
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::Key, Attribute::Enumerable);
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::Key, true);
}
Value ObjectConstructor::values(Interpreter& interpreter)
@ -191,7 +202,7 @@ Value ObjectConstructor::values(Interpreter& interpreter)
if (interpreter.exception())
return {};
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::Value, Attribute::Enumerable);
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::Value, true);
}
Value ObjectConstructor::entries(Interpreter& interpreter)
@ -203,7 +214,7 @@ Value ObjectConstructor::entries(Interpreter& interpreter)
if (interpreter.exception())
return {};
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::KeyAndValue, Attribute::Enumerable);
return obj_arg->get_own_properties(*obj_arg, GetOwnPropertyMode::KeyAndValue, true);
}
}