LibJS: Stop propagating is_inside_scope_with_eval across functions

Previously, when a nested function contained eval(), the parser would
mark all identifiers in parent functions as "inside scope with eval".
This prevented those identifiers from being marked as global, forcing
them to use GetBinding instead of GetGlobal.

However, eval() can only inject variables into its containing function's
scope, not into parent function scopes. So a parent function's reference
to a global like `Number` should still be able to use GetGlobal even if
a nested function contains eval().

This change adds a new flag `m_eval_in_current_function` that propagates
through block scopes within the same function but stops at function
boundaries. This flag is used for marking identifiers, while the
existing `m_screwed_by_eval_in_scope_chain` continues to propagate
across functions for local variable deoptimization (since eval can
access closure variables).

Before: `new Number(42)` in outer() with eval in inner() -> GetBinding
After:  `new Number(42)` in outer() with eval in inner() -> GetGlobal
This commit is contained in:
Andreas Kling
2026-01-26 21:17:28 +01:00
committed by Andreas Kling
parent 273c657a88
commit 871d93355b
Notes: github-actions[bot] 2026-02-06 11:02:02 +00:00
5 changed files with 67 additions and 1 deletions

View File

@@ -0,0 +1,10 @@
// Test that eval in the same function prevents using GetGlobal
// for potentially shadowable identifiers.
// The function should use GetBinding for Number, not GetGlobal.
function foo() {
eval("var x = 1");
return new Number(42);
}
foo();