1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:17:45 +00:00

LibJS: Add Object::get_without_side_effects()

Similar to Value::to_string_without_side_effects() this is mostly a
regular object property lookup, but with the guarantee that it will be
side-effect free, i.e. no accessors or native property functions will
be called. This is needed when we want to access user-controlled object
properties for debug logging, for example. The specific use case will be
error objects which will soon no longer have internal name/message
properties, so we need to guarantee that printing an error, which may
already be the result of an exception, won't blow up in our face :^)
This commit is contained in:
Linus Groh 2021-04-11 22:52:25 +02:00 committed by Andreas Kling
parent 9ec4defdd2
commit 6e9eb0a284
4 changed files with 23 additions and 11 deletions

View file

@ -234,7 +234,7 @@ bool Object::test_integrity_level(IntegrityLevel level)
return true;
}
Value Object::get_own_property(const PropertyName& property_name, Value receiver) const
Value Object::get_own_property(const PropertyName& property_name, Value receiver, bool without_side_effects) const
{
VERIFY(property_name.is_valid());
VERIFY(!receiver.is_empty());
@ -254,10 +254,12 @@ Value Object::get_own_property(const PropertyName& property_name, Value receiver
}
VERIFY(!value_here.is_empty());
if (value_here.is_accessor())
return value_here.as_accessor().call_getter(receiver);
if (value_here.is_native_property())
return call_native_property_getter(value_here.as_native_property(), receiver);
if (!without_side_effects) {
if (value_here.is_accessor())
return value_here.as_accessor().call_getter(receiver);
if (value_here.is_native_property())
return call_native_property_getter(value_here.as_native_property(), receiver);
}
return value_here;
}
@ -769,7 +771,7 @@ Value Object::get_by_index(u32 property_index) const
return {};
}
Value Object::get(const PropertyName& property_name, Value receiver) const
Value Object::get(const PropertyName& property_name, Value receiver, bool without_side_effects) const
{
VERIFY(property_name.is_valid());
@ -788,7 +790,7 @@ Value Object::get(const PropertyName& property_name, Value receiver) const
const Object* object = this;
while (object) {
auto value = object->get_own_property(property_name, receiver);
auto value = object->get_own_property(property_name, receiver, without_side_effects);
if (vm().exception())
return {};
if (!value.is_empty())
@ -800,6 +802,11 @@ Value Object::get(const PropertyName& property_name, Value receiver) const
return {};
}
Value Object::get_without_side_effects(const PropertyName& property_name) const
{
return get(property_name, {}, true);
}
bool Object::put_by_index(u32 property_index, Value value)
{
VERIFY(!value.is_empty());