summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp7
-rw-r--r--Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Environment.cpp9
-rw-r--r--Userland/Libraries/LibJS/Runtime/Environment.h7
4 files changed, 24 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
index 6df25398f3..5630d28f51 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
@@ -444,6 +444,13 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
if (strict_eval)
variable_environment = lexical_environment;
+ if (direct == EvalMode::Direct && !strict_eval) {
+ // NOTE: Non-strict direct eval() forces us to deoptimize variable accesses.
+ // Mark the variable environment chain as screwed since we will not be able
+ // to rely on cached environment coordinates from this point on.
+ variable_environment->set_permanently_screwed_by_eval();
+ }
+
// 18. If runningContext is not already suspended, suspend runningContext.
// FIXME: We don't have this concept yet.
diff --git a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp
index 3514143757..5c4d83d8e4 100644
--- a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp
+++ b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp
@@ -40,7 +40,7 @@ bool DeclarativeEnvironment::has_binding(FlyString const& name, Optional<size_t>
auto it = m_names.find(name);
if (it == m_names.end())
return false;
- if (out_index)
+ if (!is_permanently_screwed_by_eval() && out_index)
*out_index = it->value;
return true;
}
diff --git a/Userland/Libraries/LibJS/Runtime/Environment.cpp b/Userland/Libraries/LibJS/Runtime/Environment.cpp
index bfebf54718..fa650d9f26 100644
--- a/Userland/Libraries/LibJS/Runtime/Environment.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Environment.cpp
@@ -28,4 +28,13 @@ void Environment::visit_edges(Visitor& visitor)
visitor.visit(m_outer_environment);
}
+void Environment::set_permanently_screwed_by_eval()
+{
+ if (m_permanently_screwed_by_eval)
+ return;
+ m_permanently_screwed_by_eval = true;
+ if (outer_environment())
+ outer_environment()->set_permanently_screwed_by_eval();
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/Environment.h b/Userland/Libraries/LibJS/Runtime/Environment.h
index 69d27bf31e..e4e9ad0e52 100644
--- a/Userland/Libraries/LibJS/Runtime/Environment.h
+++ b/Userland/Libraries/LibJS/Runtime/Environment.h
@@ -53,6 +53,11 @@ public:
virtual char const* class_name() const override { return "Environment"; }
+ // This flag is set on the entire variable environment chain when direct eval() is performed.
+ // It is used to disable non-local variable access caching.
+ bool is_permanently_screwed_by_eval() const { return m_permanently_screwed_by_eval; }
+ void set_permanently_screwed_by_eval();
+
protected:
explicit Environment(Environment* parent);
@@ -63,6 +68,8 @@ private:
GlobalObject* m_global_object { nullptr };
Environment* m_outer_environment { nullptr };
+
+ bool m_permanently_screwed_by_eval { false };
};
}