mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibJS: Make Reference aware of DeclarativeEnvironment indices
VM::resolve_binding() can now return a Reference that knows the exact binding index if it's pointing into a DeclarativeEnvironment. Reading/writing through the Reference will now use direct environment access when possible.
This commit is contained in:
parent
540ce075b6
commit
4444bcabde
Notes:
sideshowbarker
2024-07-18 02:59:19 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/4444bcabde9
3 changed files with 14 additions and 4 deletions
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibJS/AST.h>
|
#include <LibJS/AST.h>
|
||||||
|
#include <LibJS/Runtime/DeclarativeEnvironment.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/Reference.h>
|
#include <LibJS/Runtime/Reference.h>
|
||||||
|
@ -48,7 +49,10 @@ void Reference::put_value(GlobalObject& global_object, Value value)
|
||||||
|
|
||||||
VERIFY(m_base_type == BaseType::Environment);
|
VERIFY(m_base_type == BaseType::Environment);
|
||||||
VERIFY(m_base_environment);
|
VERIFY(m_base_environment);
|
||||||
m_base_environment->set_mutable_binding(global_object, m_name.as_string(), value, m_strict);
|
if (m_index_in_declarative_environment.has_value())
|
||||||
|
static_cast<DeclarativeEnvironment*>(m_base_environment)->set_mutable_binding_direct(global_object, m_index_in_declarative_environment.value(), value, m_strict);
|
||||||
|
else
|
||||||
|
m_base_environment->set_mutable_binding(global_object, m_name.as_string(), value, m_strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reference::throw_reference_error(GlobalObject& global_object) const
|
void Reference::throw_reference_error(GlobalObject& global_object) const
|
||||||
|
@ -77,6 +81,8 @@ Value Reference::get_value(GlobalObject& global_object) const
|
||||||
|
|
||||||
VERIFY(m_base_type == BaseType::Environment);
|
VERIFY(m_base_type == BaseType::Environment);
|
||||||
VERIFY(m_base_environment);
|
VERIFY(m_base_environment);
|
||||||
|
if (m_index_in_declarative_environment.has_value())
|
||||||
|
return static_cast<DeclarativeEnvironment*>(m_base_environment)->get_binding_value_direct(global_object, m_index_in_declarative_environment.value(), m_strict);
|
||||||
return m_base_environment->get_binding_value(global_object, m_name.as_string(), m_strict);
|
return m_base_environment->get_binding_value(global_object, m_name.as_string(), m_strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,11 +44,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference(Environment& base, FlyString referenced_name, bool strict = false)
|
Reference(Environment& base, FlyString referenced_name, bool strict = false, Optional<size_t> index_in_declarative_environment = {})
|
||||||
: m_base_type(BaseType::Environment)
|
: m_base_type(BaseType::Environment)
|
||||||
, m_base_environment(&base)
|
, m_base_environment(&base)
|
||||||
, m_name(move(referenced_name))
|
, m_name(move(referenced_name))
|
||||||
, m_strict(strict)
|
, m_strict(strict)
|
||||||
|
, m_index_in_declarative_environment(move(index_in_declarative_environment))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ private:
|
||||||
PropertyName m_name;
|
PropertyName m_name;
|
||||||
Value m_this_value;
|
Value m_this_value;
|
||||||
bool m_strict { false };
|
bool m_strict { false };
|
||||||
|
Optional<size_t> m_index_in_declarative_environment;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,12 +442,14 @@ Reference VM::get_identifier_reference(Environment* environment, FlyString name,
|
||||||
// a. Return the Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }.
|
// a. Return the Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }.
|
||||||
return Reference { Reference::BaseType::Unresolvable, move(name), strict };
|
return Reference { Reference::BaseType::Unresolvable, move(name), strict };
|
||||||
}
|
}
|
||||||
auto exists = environment->has_binding(name);
|
|
||||||
|
Optional<size_t> index;
|
||||||
|
auto exists = environment->has_binding(name, &index);
|
||||||
if (exception())
|
if (exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (exists)
|
if (exists)
|
||||||
return Reference { *environment, move(name), strict };
|
return Reference { *environment, move(name), strict, index };
|
||||||
else
|
else
|
||||||
return get_identifier_reference(environment->outer_environment(), move(name), strict);
|
return get_identifier_reference(environment->outer_environment(), move(name), strict);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue