1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:17:35 +00:00

LibJS: Make eval() prevent GetGlobal usage less aggressively

Before usage of GetGlobal was prevented whenever eval() is present in
the scope chain.

With this change GetGlobal is emitted for `g` in the following program:
```js
function screw_everything_up() {
    eval("");
}

var g;
g;
```

It makes Octane/mandreel.js benchmark run 2x faster :)
This commit is contained in:
Aliaksandr Kalenik 2023-11-08 06:11:33 +01:00 committed by Andreas Kling
parent 1ca46afa2f
commit c170dd323e

View file

@ -276,15 +276,15 @@ public:
m_parent_scope->m_contains_await_expression |= m_contains_await_expression; m_parent_scope->m_contains_await_expression |= m_contains_await_expression;
} }
if (m_parent_scope && m_contains_direct_call_to_eval) {
m_parent_scope->m_screwed_by_eval_in_scope_chain = true;
}
if (!m_node) { if (!m_node) {
m_parser.m_state.current_scope_pusher = m_parent_scope; m_parser.m_state.current_scope_pusher = m_parent_scope;
return; return;
} }
if (m_parent_scope && m_contains_direct_call_to_eval) {
m_parent_scope->m_screwed_by_eval_in_scope_chain = true;
}
for (auto& it : m_identifier_groups) { for (auto& it : m_identifier_groups) {
auto const& identifier_group_name = it.key; auto const& identifier_group_name = it.key;
auto& identifier_group = it.value; auto& identifier_group = it.value;
@ -343,16 +343,7 @@ public:
} }
if (m_type == ScopeType::Program) { if (m_type == ScopeType::Program) {
auto can_use_global_for_identifier = true; auto can_use_global_for_identifier = !(identifier_group.used_inside_with_statement || identifier_group.might_be_variable_in_lexical_scope_in_named_function_assignment || identifier_group.used_inside_scope_with_eval || m_parser.m_state.initiated_by_eval);
if (identifier_group.used_inside_with_statement)
can_use_global_for_identifier = false;
else if (identifier_group.might_be_variable_in_lexical_scope_in_named_function_assignment)
can_use_global_for_identifier = false;
else if (m_screwed_by_eval_in_scope_chain)
can_use_global_for_identifier = false;
else if (m_parser.m_state.initiated_by_eval)
can_use_global_for_identifier = false;
if (can_use_global_for_identifier) { if (can_use_global_for_identifier) {
for (auto& identifier : identifier_group.identifiers) for (auto& identifier : identifier_group.identifiers)
identifier->set_is_global(); identifier->set_is_global();
@ -380,6 +371,9 @@ public:
if (m_type == ScopeType::With) if (m_type == ScopeType::With)
identifier_group.used_inside_with_statement = true; identifier_group.used_inside_with_statement = true;
if (m_contains_direct_call_to_eval)
identifier_group.used_inside_scope_with_eval = true;
if (m_parent_scope) { if (m_parent_scope) {
if (auto maybe_parent_scope_identifier_group = m_parent_scope->m_identifier_groups.get(identifier_group_name); maybe_parent_scope_identifier_group.has_value()) { if (auto maybe_parent_scope_identifier_group = m_parent_scope->m_identifier_groups.get(identifier_group_name); maybe_parent_scope_identifier_group.has_value()) {
maybe_parent_scope_identifier_group.value().identifiers.extend(identifier_group.identifiers); maybe_parent_scope_identifier_group.value().identifiers.extend(identifier_group.identifiers);
@ -389,6 +383,8 @@ public:
maybe_parent_scope_identifier_group.value().used_inside_with_statement = true; maybe_parent_scope_identifier_group.value().used_inside_with_statement = true;
if (identifier_group.might_be_variable_in_lexical_scope_in_named_function_assignment) if (identifier_group.might_be_variable_in_lexical_scope_in_named_function_assignment)
maybe_parent_scope_identifier_group.value().might_be_variable_in_lexical_scope_in_named_function_assignment = true; maybe_parent_scope_identifier_group.value().might_be_variable_in_lexical_scope_in_named_function_assignment = true;
if (identifier_group.used_inside_scope_with_eval)
maybe_parent_scope_identifier_group.value().used_inside_scope_with_eval = true;
} else { } else {
m_parent_scope->m_identifier_groups.set(identifier_group_name, identifier_group); m_parent_scope->m_identifier_groups.set(identifier_group_name, identifier_group);
} }
@ -467,6 +463,7 @@ private:
struct IdentifierGroup { struct IdentifierGroup {
bool captured_by_nested_function { false }; bool captured_by_nested_function { false };
bool used_inside_with_statement { false }; bool used_inside_with_statement { false };
bool used_inside_scope_with_eval { false };
bool might_be_variable_in_lexical_scope_in_named_function_assignment { false }; bool might_be_variable_in_lexical_scope_in_named_function_assignment { false };
Vector<NonnullRefPtr<Identifier>> identifiers; Vector<NonnullRefPtr<Identifier>> identifiers;
}; };