Commit df8b8117 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by Commit Bot

Add use counter for var redeclarations of catch bindings

Bug: v8:10516
Change-Id: I0a75b32ca4b90dc5a6c2f2f3ec66b183dc3ff99e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2191411
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67724}
parent 9d825428
...@@ -8449,6 +8449,7 @@ class V8_EXPORT Isolate { ...@@ -8449,6 +8449,7 @@ class V8_EXPORT Isolate {
kInvalidatedStringLengthOverflowLookupChainProtector = 104, kInvalidatedStringLengthOverflowLookupChainProtector = 104,
kInvalidatedTypedArraySpeciesLookupChainProtector = 105, kInvalidatedTypedArraySpeciesLookupChainProtector = 105,
kWasmSimdOpcodes = 106, kWasmSimdOpcodes = 106,
kVarRedeclaredCatchBinding = 107,
// If you add new values here, you'll also need to update Chromium's: // If you add new values here, you'll also need to update Chromium's:
// web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to
......
...@@ -1138,7 +1138,8 @@ Variable* Scope::NewTemporary(const AstRawString* name, ...@@ -1138,7 +1138,8 @@ Variable* Scope::NewTemporary(const AstRawString* name,
return var; return var;
} }
Declaration* DeclarationScope::CheckConflictingVarDeclarations() { Declaration* DeclarationScope::CheckConflictingVarDeclarations(
bool* allowed_catch_binding_var_redeclaration) {
if (has_checked_syntax_) return nullptr; if (has_checked_syntax_) return nullptr;
for (Declaration* decl : decls_) { for (Declaration* decl : decls_) {
// Lexical vs lexical conflicts within the same scope have already been // Lexical vs lexical conflicts within the same scope have already been
...@@ -1152,11 +1153,12 @@ Declaration* DeclarationScope::CheckConflictingVarDeclarations() { ...@@ -1152,11 +1153,12 @@ Declaration* DeclarationScope::CheckConflictingVarDeclarations() {
// Iterate through all scopes until the declaration scope. // Iterate through all scopes until the declaration scope.
do { do {
// There is a conflict if there exists a non-VAR binding. // There is a conflict if there exists a non-VAR binding.
Variable* other_var = current->LookupLocal(decl->var()->raw_name());
if (current->is_catch_scope()) { if (current->is_catch_scope()) {
*allowed_catch_binding_var_redeclaration |= other_var != nullptr;
current = current->outer_scope(); current = current->outer_scope();
continue; continue;
} }
Variable* other_var = current->LookupLocal(decl->var()->raw_name());
if (other_var != nullptr) { if (other_var != nullptr) {
DCHECK(IsLexicalVariableMode(other_var->mode())); DCHECK(IsLexicalVariableMode(other_var->mode()));
return decl; return decl;
......
...@@ -909,7 +909,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { ...@@ -909,7 +909,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// Check if the scope has conflicting var // Check if the scope has conflicting var
// declarations, i.e. a var declaration that has been hoisted from a nested // declarations, i.e. a var declaration that has been hoisted from a nested
// scope over a let binding of the same name. // scope over a let binding of the same name.
Declaration* CheckConflictingVarDeclarations(); Declaration* CheckConflictingVarDeclarations(
bool* allowed_catch_binding_var_redeclaration);
void set_has_checked_syntax(bool has_checked_syntax) { void set_has_checked_syntax(bool has_checked_syntax) {
has_checked_syntax_ = has_checked_syntax; has_checked_syntax_ = has_checked_syntax;
......
...@@ -1247,7 +1247,12 @@ class ParserBase { ...@@ -1247,7 +1247,12 @@ class ParserBase {
// hoisted over such a scope. // hoisted over such a scope.
void CheckConflictingVarDeclarations(DeclarationScope* scope) { void CheckConflictingVarDeclarations(DeclarationScope* scope) {
if (has_error()) return; if (has_error()) return;
Declaration* decl = scope->CheckConflictingVarDeclarations(); bool allowed_catch_binding_var_redeclaration = false;
Declaration* decl = scope->CheckConflictingVarDeclarations(
&allowed_catch_binding_var_redeclaration);
if (allowed_catch_binding_var_redeclaration) {
impl()->CountUsage(v8::Isolate::kVarRedeclaredCatchBinding);
}
if (decl != nullptr) { if (decl != nullptr) {
// In ES6, conflicting variable bindings are early errors. // In ES6, conflicting variable bindings are early errors.
const AstRawString* name = decl->var()->raw_name(); const AstRawString* name = decl->var()->raw_name();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment