diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index de4b57a4c2..313a5d6071 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -1387,13 +1387,13 @@ ThrowCompletionOr Expression::to_reference(Interpreter&) const ThrowCompletionOr Identifier::to_reference(Interpreter& interpreter) const { - if (m_cached_environment_coordinate.has_value()) { + if (m_cached_environment_coordinate.is_valid()) { Environment* environment = nullptr; - if (m_cached_environment_coordinate->index == EnvironmentCoordinate::global_marker) { + if (m_cached_environment_coordinate.index == EnvironmentCoordinate::global_marker) { environment = &interpreter.vm().current_realm()->global_environment(); } else { environment = interpreter.vm().running_execution_context().lexical_environment; - for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i) + for (size_t i = 0; i < m_cached_environment_coordinate.hops; ++i) environment = environment->outer_environment(); VERIFY(environment); VERIFY(environment->is_declarative_environment()); @@ -1406,7 +1406,7 @@ ThrowCompletionOr Identifier::to_reference(Interpreter& interpreter) auto reference = TRY(interpreter.vm().resolve_binding(string())); if (reference.environment_coordinate().has_value()) - m_cached_environment_coordinate = reference.environment_coordinate(); + m_cached_environment_coordinate = reference.environment_coordinate().value(); return reference; } diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 0f0a0ffa14..1ef0d71692 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -1222,7 +1222,7 @@ private: virtual bool is_identifier() const override { return true; } FlyString m_string; - mutable Optional m_cached_environment_coordinate; + mutable EnvironmentCoordinate m_cached_environment_coordinate; }; class PrivateIdentifier final : public Expression { diff --git a/Userland/Libraries/LibJS/Runtime/EnvironmentCoordinate.h b/Userland/Libraries/LibJS/Runtime/EnvironmentCoordinate.h index 54eb605215..679652ec46 100644 --- a/Userland/Libraries/LibJS/Runtime/EnvironmentCoordinate.h +++ b/Userland/Libraries/LibJS/Runtime/EnvironmentCoordinate.h @@ -12,10 +12,13 @@ namespace JS { struct EnvironmentCoordinate { - size_t hops { 0 }; - size_t index { 0 }; + u32 hops { invalid_marker }; + u32 index { invalid_marker }; - static constexpr size_t global_marker = 0xffffffff; + bool is_valid() const { return hops != invalid_marker && index != invalid_marker; } + + static constexpr u32 global_marker = 0xffffffff; + static constexpr u32 invalid_marker = 0xfffffffe; }; } diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index ccf701f154..1d42828c2b 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -565,8 +565,11 @@ ThrowCompletionOr VM::get_identifier_reference(Environment* environme // Note: This is an optimization for looking up the same reference. Optional environment_coordinate; - if (index.has_value()) - environment_coordinate = EnvironmentCoordinate { .hops = hops, .index = index.value() }; + if (index.has_value()) { + VERIFY(hops <= NumericLimits::max()); + VERIFY(index.value() <= NumericLimits::max()); + environment_coordinate = EnvironmentCoordinate { .hops = static_cast(hops), .index = static_cast(index.value()) }; + } // 3. If exists is true, then if (exists) {