mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibJS: Add Value::get() and Object::get() overloads with lookup cache
To speed up property access, callers of get() can now provide a lookup
cache like so:
static Bytecode::PropertyLookupCache cache;
auto value = TRY(object.get(property, cache));
Note that the cache has to be `static` or it won't make sense!
This basically brings the inline caches from our bytecode VM straight
into C++ land, allowing us to gain serious performance improvements.
The implementation shares code with the GetById bytecode instruction.
This commit is contained in:
parent
26c1dea22a
commit
0fb9ba1e3a
|
|
@ -125,6 +125,13 @@ ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const
|
|||
return TRY(internal_get(property_key, this));
|
||||
}
|
||||
|
||||
// 7.3.2 Get ( O, P ), https://tc39.es/ecma262/#sec-get-o-p
|
||||
ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key, Bytecode::PropertyLookupCache& cache) const
|
||||
{
|
||||
// 1. Return ? O.[[Get]](P, O).
|
||||
return TRY(Value(this).get(vm(), property_key, cache));
|
||||
}
|
||||
|
||||
// NOTE: 7.3.3 GetV ( V, P ) is implemented as Value::get().
|
||||
|
||||
// 7.3.4 Set ( O, P, V, Throw ), https://tc39.es/ecma262/#sec-set-o-p-v-throw
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ public:
|
|||
// 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects
|
||||
|
||||
ThrowCompletionOr<Value> get(PropertyKey const&) const;
|
||||
ThrowCompletionOr<Value> get(PropertyKey const&, Bytecode::PropertyLookupCache&) const;
|
||||
ThrowCompletionOr<void> set(PropertyKey const&, Value, ShouldThrowExceptions);
|
||||
ThrowCompletionOr<bool> create_data_property(PropertyKey const&, Value, Optional<u32>* new_property_offset = nullptr);
|
||||
void create_method_property(PropertyKey const&, Value);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2020-2025, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2022, David Tuin <davidot@serenityos.org>
|
||||
*
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#include <AK/Utf16String.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
||||
#include <LibJS/Bytecode/PropertyAccess.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Accessor.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
|
|
@ -1306,6 +1307,13 @@ ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property_key) con
|
|||
return TRY(object->internal_get(property_key, *this));
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property, Bytecode::PropertyLookupCache& cache) const
|
||||
{
|
||||
if (is_nullish())
|
||||
return vm.throw_completion<TypeError>(ErrorType::ToObjectNullOrUndefined);
|
||||
return Bytecode::get_by_id<Bytecode::GetByIdMode::Normal>(vm, [&]() { return Optional<Utf16FlyString const&> {}; }, [&]() { return property; }, *this, *this, cache);
|
||||
}
|
||||
|
||||
// 7.3.11 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
|
||||
ThrowCompletionOr<GC::Ptr<FunctionObject>> Value::get_method(VM& vm, PropertyKey const& property_key) const
|
||||
{
|
||||
|
|
@ -1324,6 +1332,24 @@ ThrowCompletionOr<GC::Ptr<FunctionObject>> Value::get_method(VM& vm, PropertyKey
|
|||
return function.as_function();
|
||||
}
|
||||
|
||||
// 7.3.11 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
|
||||
ThrowCompletionOr<GC::Ptr<FunctionObject>> Value::get_method(VM& vm, PropertyKey const& property_key, Bytecode::PropertyLookupCache& cache) const
|
||||
{
|
||||
// 1. Let func be ? GetV(V, P).
|
||||
auto function = TRY(get(vm, property_key, cache));
|
||||
|
||||
// 2. If func is either undefined or null, return undefined.
|
||||
if (function.is_nullish())
|
||||
return nullptr;
|
||||
|
||||
// 3. If IsCallable(func) is false, throw a TypeError exception.
|
||||
if (!function.is_function())
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function.to_string_without_side_effects());
|
||||
|
||||
// 4. Return func.
|
||||
return function.as_function();
|
||||
}
|
||||
|
||||
// 13.10 Relational Operators, https://tc39.es/ecma262/#sec-relational-operators
|
||||
// RelationalExpression : RelationalExpression > ShiftExpression
|
||||
ThrowCompletionOr<bool> greater_than(VM& vm, Value lhs, Value rhs)
|
||||
|
|
|
|||
|
|
@ -382,7 +382,10 @@ public:
|
|||
bool to_boolean() const;
|
||||
|
||||
ThrowCompletionOr<Value> get(VM&, PropertyKey const&) const;
|
||||
ThrowCompletionOr<Value> get(VM&, PropertyKey const&, Bytecode::PropertyLookupCache&) const;
|
||||
|
||||
ThrowCompletionOr<GC::Ptr<FunctionObject>> get_method(VM&, PropertyKey const&) const;
|
||||
ThrowCompletionOr<GC::Ptr<FunctionObject>> get_method(VM&, PropertyKey const&, Bytecode::PropertyLookupCache&) const;
|
||||
|
||||
[[nodiscard]] String to_string_without_side_effects() const;
|
||||
[[nodiscard]] Utf16String to_utf16_string_without_side_effects() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user