mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 00:55:06 +00:00
LibJS/Bytecode: Begin moving shareable (JIT+Interpreter) stuff somewhere
There are a lot of native C++ functions that will be used by both the bytecode interpreter and jitted code. Let's put them in their own file instead of having them in Interpreter.cpp.
This commit is contained in:
parent
b923ca392d
commit
8905682a16
4 changed files with 86 additions and 56 deletions
63
Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp
Normal file
63
Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Bytecode/CommonImplementations.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> base_object_for_get(Bytecode::Interpreter& interpreter, Value base_value)
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
if (base_value.is_object())
|
||||
return base_value.as_object();
|
||||
|
||||
// OPTIMIZATION: For various primitives we can avoid actually creating a new object for them.
|
||||
if (base_value.is_string())
|
||||
return vm.current_realm()->intrinsics().string_prototype();
|
||||
if (base_value.is_number())
|
||||
return vm.current_realm()->intrinsics().number_prototype();
|
||||
if (base_value.is_boolean())
|
||||
return vm.current_realm()->intrinsics().boolean_prototype();
|
||||
|
||||
return base_value.to_object(vm);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> get_by_id(Bytecode::Interpreter& interpreter, IdentifierTableIndex property, Value base_value, Value this_value, u32 cache_index)
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto const& name = interpreter.current_executable().get_identifier(property);
|
||||
auto& cache = interpreter.current_executable().property_lookup_caches[cache_index];
|
||||
|
||||
if (base_value.is_string()) {
|
||||
auto string_value = TRY(base_value.as_string().get(vm, name));
|
||||
if (string_value.has_value())
|
||||
return *string_value;
|
||||
}
|
||||
|
||||
auto base_obj = TRY(base_object_for_get(interpreter, base_value));
|
||||
|
||||
// OPTIMIZATION: If the shape of the object hasn't changed, we can use the cached property offset.
|
||||
// NOTE: Unique shapes don't change identity, so we compare their serial numbers instead.
|
||||
auto& shape = base_obj->shape();
|
||||
if (&shape == cache.shape
|
||||
&& (!shape.is_unique() || shape.unique_shape_serial_number() == cache.unique_shape_serial_number)) {
|
||||
return base_obj->get_direct(cache.property_offset.value());
|
||||
}
|
||||
|
||||
CacheablePropertyMetadata cacheable_metadata;
|
||||
auto value = TRY(base_obj->internal_get(name, this_value, &cacheable_metadata));
|
||||
|
||||
if (cacheable_metadata.type == CacheablePropertyMetadata::Type::OwnProperty) {
|
||||
cache.shape = shape;
|
||||
cache.property_offset = cacheable_metadata.property_offset.value();
|
||||
cache.unique_shape_serial_number = shape.unique_shape_serial_number();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue