LibJS: Add direct (indexed) binding accessors to DeclarativeEnvironment

This patch adds two DeclarativeEnvironment APIs:

- get_binding_value_direct()
- set_mutable_binding_direct()

These work identically to their non-direct-suffixed counterparts, but
take an index instead of a bound name. This will allow someone who has
a binding index to get/set that binding directly without any additional
hash lookups.
This commit is contained in:
Andreas Kling 2021-10-07 00:10:00 +02:00
parent cb696eff08
commit 540ce075b6
Notes: sideshowbarker 2024-07-18 02:59:22 +09:00
2 changed files with 29 additions and 5 deletions

View file

@ -98,12 +98,17 @@ void DeclarativeEnvironment::set_mutable_binding(GlobalObject& global_object, Fl
return;
}
auto& binding = m_bindings[it->value];
set_mutable_binding_direct(global_object, it->value, value, strict);
}
void DeclarativeEnvironment::set_mutable_binding_direct(GlobalObject& global_object, size_t index, Value value, bool strict)
{
auto& binding = m_bindings[index];
if (binding.strict)
strict = true;
if (!binding.initialized) {
global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::BindingNotInitialized, name);
global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::BindingNotInitialized, name_from_index(index));
return;
}
@ -117,13 +122,18 @@ void DeclarativeEnvironment::set_mutable_binding(GlobalObject& global_object, Fl
}
// 9.1.1.1.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-getbindingvalue-n-s
Value DeclarativeEnvironment::get_binding_value(GlobalObject& global_object, FlyString const& name, bool)
Value DeclarativeEnvironment::get_binding_value(GlobalObject& global_object, FlyString const& name, bool strict)
{
auto it = m_names.find(name);
VERIFY(it != m_names.end());
auto& binding = m_bindings[it->value];
return get_binding_value_direct(global_object, it->value, strict);
}
Value DeclarativeEnvironment::get_binding_value_direct(GlobalObject& global_object, size_t index, bool)
{
auto& binding = m_bindings[index];
if (!binding.initialized) {
global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::BindingNotInitialized, name);
global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::BindingNotInitialized, name_from_index(index));
return {};
}
return binding.value;
@ -163,4 +173,13 @@ Vector<String> DeclarativeEnvironment::bindings() const
return names;
}
FlyString const& DeclarativeEnvironment::name_from_index(size_t index) const
{
for (auto& it : m_names) {
if (it.value == index)
return it.key;
}
VERIFY_NOT_REACHED();
}
}

View file

@ -34,10 +34,15 @@ public:
// This is not a method defined in the spec! Do not use this in any LibJS (or other spec related) code.
[[nodiscard]] Vector<String> bindings() const;
Value get_binding_value_direct(GlobalObject&, size_t index, bool strict);
void set_mutable_binding_direct(GlobalObject&, size_t index, Value, bool strict);
protected:
virtual void visit_edges(Visitor&) override;
private:
FlyString const& name_from_index(size_t) const;
virtual bool is_declarative_environment() const override { return true; }
struct Binding {