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

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
parent dbfe1311ef
commit 61148bce5f

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 {};
}