Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index dd9744e7f6314d72f1b3b91ad4b28218da7d1225..8dd9e0ea19b26178454a9c6936d08fe796f17249 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -1964,30 +1964,43 @@ Variable* Parser::Declare(Declaration* declaration, |
var = declaration_scope->DeclareLocal( |
name, mode, declaration->initialization(), kind, kNotAssigned, |
declaration_group_start); |
- } else if (((IsLexicalVariableMode(mode) || |
- IsLexicalVariableMode(var->mode())) && |
- // Allow duplicate function decls for web compat, see bug 4693. |
- (is_strict(language_mode()) || !is_function_declaration || |
- !var->is_function())) || |
- ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
- !declaration_scope->is_script_scope())) { |
- // The name was declared in this scope before; check for conflicting |
- // re-declarations. We have a conflict if either of the declarations is |
- // not a var (in script scope, we also have to ignore legacy const for |
- // compatibility). There is similar code in runtime.cc in the Declare |
- // functions. The function CheckConflictingVarDeclarations checks for |
- // var and let bindings from different scopes whereas this is a check for |
- // conflicting declarations within the same scope. This check also covers |
- // the special case |
- // |
- // function () { let x; { var x; } } |
- // |
- // because the var declaration is hoisted to the function scope where 'x' |
- // is already bound. |
- DCHECK(IsDeclaredVariableMode(var->mode())); |
- if (is_strict(language_mode()) || |
- (allow_harmony_sloppy() && mode != CONST_LEGACY && |
- var->mode() != CONST_LEGACY)) { |
+ } else if ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
+ !declaration_scope->is_script_scope()) { |
+ // Duplicate legacy const definitions throw at runtime. |
+ DCHECK(is_sloppy(language_mode())); |
+ Expression* expression = NewThrowSyntaxError( |
+ MessageTemplate::kVarRedeclaration, name, declaration->position()); |
+ declaration_scope->SetIllegalRedeclaration(expression); |
+ } else if ((IsLexicalVariableMode(mode) || |
+ IsLexicalVariableMode(var->mode())) && |
+ // Lexical bindings may appear for some parameters in sloppy |
+ // mode even with --harmony-sloppy off. |
+ (is_strict(language_mode()) || allow_harmony_sloppy())) { |
+ // Allow duplicate function decls for web compat, see bug 4693. |
+ if (is_sloppy(language_mode()) && is_function_declaration && |
+ var->is_function()) { |
+ DCHECK(IsLexicalVariableMode(mode) && |
+ IsLexicalVariableMode(var->mode())); |
+ ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; |
+ } else { |
+ // The name was declared in this scope before; check for conflicting |
+ // re-declarations. We have a conflict if either of the declarations |
+ // is |
adamk
2016/02/01 18:26:58
Please re-flow this whole comment to avoid lines
Dan Ehrenberg
2016/02/01 22:02:36
Done
Dan Ehrenberg
2016/02/01 22:02:36
Done
|
+ // not a var (in script scope, we also have to ignore legacy const for |
+ // compatibility). There is similar code in runtime.cc in the Declare |
+ // functions. The function CheckConflictingVarDeclarations checks for |
+ // var and let bindings from different scopes whereas this is a check |
+ // for |
+ // conflicting declarations within the same scope. This check also |
+ // covers |
+ // the special case |
+ // |
+ // function () { let x; { var x; } } |
+ // |
+ // because the var declaration is hoisted to the function scope where |
+ // 'x' |
+ // is already bound. |
+ DCHECK(IsDeclaredVariableMode(var->mode())); |
// In harmony we treat re-declarations as early errors. See |
// ES5 16 for a definition of early errors. |
if (declaration_kind == DeclarationDescriptor::NORMAL) { |
@@ -1998,9 +2011,6 @@ Variable* Parser::Declare(Declaration* declaration, |
*ok = false; |
return nullptr; |
} |
- Expression* expression = NewThrowSyntaxError( |
- MessageTemplate::kVarRedeclaration, name, declaration->position()); |
- declaration_scope->SetIllegalRedeclaration(expression); |
} else if (mode == VAR) { |
var->set_maybe_assigned(); |
} |
@@ -3643,6 +3653,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
// special case for legacy for (var/const x =.... in) |
if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && |
decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { |
+ ++use_counts_[v8::Isolate::kForInInitializer]; |
const AstRawString* name = |
decl.pattern->AsVariableProxy()->raw_name(); |
VariableProxy* single_var = scope_->NewUnresolved( |