1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-11 18:20:43 +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:
Andreas Kling 2023-06-02 08:17:28 +02:00
parent 0eddee44f3
commit 5617dd1c83
Notes: sideshowbarker 2024-07-16 23:13:25 +09:00
3 changed files with 14 additions and 19 deletions

View file

@ -1735,13 +1735,13 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluatio
switch (kind()) {
case Kind::Method:
set_function_name();
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Method, method_value } };
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Method, make_handle(method_value) } };
case Kind::Getter:
set_function_name("get");
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, Accessor::create(interpreter.vm(), &method_function, nullptr) } };
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, make_handle(Value(Accessor::create(interpreter.vm(), &method_function, nullptr))) } };
case Kind::Setter:
set_function_name("set");
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, Accessor::create(interpreter.vm(), nullptr, &method_function) } };
return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, make_handle(Value(Accessor::create(interpreter.vm(), nullptr, &method_function))) } };
default:
VERIFY_NOT_REACHED();
}
@ -2043,11 +2043,11 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_e
if (existing.key == private_element.key) {
VERIFY(existing.kind == PrivateElement::Kind::Accessor);
VERIFY(private_element.kind == PrivateElement::Kind::Accessor);
auto& accessor = private_element.value.as_accessor();
auto& accessor = private_element.value.value().as_accessor();
if (!accessor.getter())
existing.value.as_accessor().set_setter(accessor.setter());
existing.value.value().as_accessor().set_setter(accessor.setter());
else
existing.value.as_accessor().set_getter(accessor.getter());
existing.value.value().as_accessor().set_getter(accessor.getter());
added_to_existing = true;
}
}