mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 18:10:56 +09:00
LibJS: Store PrivateElement values in Handle<Value>
This fixes an issue where private element values were not always protected from GC. I found two instances where this was happening: - ECMAScriptFunctionObject did not mark m_private_methods - ClassDefinitionEvaluation had two Vector<PrivateElement> that were opaque to the garbage collector, and so if GC occurred while constructing a class instance, some or all of its private elements could get incorrectly collected.
This commit is contained in:
parent
0eddee44f3
commit
5617dd1c83
Notes:
sideshowbarker
2024-07-16 23:13:25 +09:00
Author: https://github.com/awesomekling
Commit: 5617dd1c83
Pull-request: https://github.com/SerenityOS/serenity/pull/19219
3 changed files with 14 additions and 19 deletions
|
@ -508,7 +508,7 @@ ThrowCompletionOr<void> Object::private_field_add(PrivateName const& name, Value
|
|||
m_private_elements = make<Vector<PrivateElement>>();
|
||||
|
||||
// 4. Append PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } to O.[[PrivateElements]].
|
||||
m_private_elements->empend(name, PrivateElement::Kind::Field, value);
|
||||
m_private_elements->empend(name, PrivateElement::Kind::Field, make_handle(value));
|
||||
|
||||
// 5. Return unused.
|
||||
return {};
|
||||
|
@ -559,14 +559,14 @@ ThrowCompletionOr<Value> Object::private_get(PrivateName const& name)
|
|||
// 3. If entry.[[Kind]] is either field or method, then
|
||||
if (entry->kind != PrivateElement::Kind::Accessor) {
|
||||
// a. Return entry.[[Value]].
|
||||
return value;
|
||||
return value.value();
|
||||
}
|
||||
|
||||
// Assert: entry.[[Kind]] is accessor.
|
||||
VERIFY(value.is_accessor());
|
||||
VERIFY(value.value().is_accessor());
|
||||
|
||||
// 6. Let getter be entry.[[Get]].
|
||||
auto* getter = value.as_accessor().getter();
|
||||
auto* getter = value.value().as_accessor().getter();
|
||||
|
||||
// 5. If entry.[[Get]] is undefined, throw a TypeError exception.
|
||||
if (!getter)
|
||||
|
@ -591,7 +591,7 @@ ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value
|
|||
// 3. If entry.[[Kind]] is field, then
|
||||
if (entry->kind == PrivateElement::Kind::Field) {
|
||||
// a. Set entry.[[Value]] to value.
|
||||
entry->value = value;
|
||||
entry->value = make_handle(value);
|
||||
return {};
|
||||
}
|
||||
// 4. Else if entry.[[Kind]] is method, then
|
||||
|
@ -606,10 +606,10 @@ ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value
|
|||
VERIFY(entry->kind == PrivateElement::Kind::Accessor);
|
||||
|
||||
auto& accessor = entry->value;
|
||||
VERIFY(accessor.is_accessor());
|
||||
VERIFY(accessor.value().is_accessor());
|
||||
|
||||
// c. Let setter be entry.[[Set]].
|
||||
auto* setter = accessor.as_accessor().setter();
|
||||
auto* setter = accessor.value().as_accessor().setter();
|
||||
|
||||
// b. If entry.[[Set]] is undefined, throw a TypeError exception.
|
||||
if (!setter)
|
||||
|
@ -1350,11 +1350,6 @@ void Object::visit_edges(Cell::Visitor& visitor)
|
|||
m_indexed_properties.for_each_value([&visitor](auto& value) {
|
||||
visitor.visit(value);
|
||||
});
|
||||
|
||||
if (m_private_elements) {
|
||||
for (auto& private_element : *m_private_elements)
|
||||
visitor.visit(private_element.value);
|
||||
}
|
||||
}
|
||||
|
||||
// 7.1.1.1 OrdinaryToPrimitive ( O, hint ), https://tc39.es/ecma262/#sec-ordinarytoprimitive
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue