mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +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
Notes:
sideshowbarker
2024-07-17 02:59:43 +09:00
Author: https://github.com/awesomekling
Commit: 8905682a16
Pull-request: https://github.com/SerenityOS/serenity/pull/21619
Reviewed-by: https://github.com/Hendiadyoin1
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