LibJS/Bytecode: Use the correct this value in GetById

The fix for this was to port the "don't create unnecessary FooObject
for property access on primitives" optimization from Reference,
which also brings us the correct behavior.
This commit is contained in:
Andreas Kling 2023-06-16 18:36:42 +02:00
commit 61148bce5f
Notes: sideshowbarker 2024-07-17 08:36:27 +09:00

View file

@ -489,8 +489,28 @@ ThrowCompletionOr<void> SetVariable::execute_impl(Bytecode::Interpreter& interpr
ThrowCompletionOr<void> GetById::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
auto object = TRY(interpreter.accumulator().to_object(vm));
interpreter.accumulator() = TRY(object->get(interpreter.current_executable().get_identifier(m_property)));
auto const& name = interpreter.current_executable().get_identifier(m_property);
auto base_value = interpreter.accumulator();
// OPTIMIZATION: For various primitives we can avoid actually creating a new object for them.
GCPtr<Object> base_obj;
if (base_value.is_string()) {
auto string_value = TRY(base_value.as_string().get(vm, name));
if (string_value.has_value()) {
interpreter.accumulator() = *string_value;
return {};
}
base_obj = vm.current_realm()->intrinsics().string_prototype();
} else if (base_value.is_number()) {
base_obj = vm.current_realm()->intrinsics().number_prototype();
} else if (base_value.is_boolean()) {
base_obj = vm.current_realm()->intrinsics().boolean_prototype();
} else {
base_obj = TRY(base_value.to_object(vm));
}
interpreter.accumulator() = TRY(base_obj->internal_get(name, base_value));
return {};
}