Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index cf907ce0a5c88d081be37a3b07bafa2e1d1c99ff..b367c2846c45432c7103d24fa60d266e268936dc 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -647,6 +647,11 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| if (ok && top_scope_->is_strict_mode()) { |
| CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| } |
| + |
| + if (ok && harmony_block_scoping_) { |
| + CheckConflictingVarDeclarations(scope, &ok); |
| + } |
| + |
| if (ok) { |
| result = new(zone()) FunctionLiteral( |
| isolate(), |
| @@ -1345,12 +1350,24 @@ VariableProxy* Parser::Declare(Handle<String> name, |
| } else { |
| // The name was declared before; check for conflicting re-declarations. |
| // We have a conflict if either of the declarations is not a var. There |
| - // is similar code in runtime.cc in the Declare functions. |
| + // is similar code in runtime.cc in the Declare functions. Also the |
| + // function CheckNonConflictingScope checks for conflicting hoisting |
| + // of var declared variables. |
|
Lasse Reichstein
2011/09/01 07:34:04
This checks only for a redeclaration in the same s
Steven
2011/09/01 15:01:33
Yes. Clarified it in the comment.
On 2011/09/01 07
|
| if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { |
| // We only have vars, consts and lets in declarations. |
| ASSERT(var->mode() == Variable::VAR || |
| var->mode() == Variable::CONST || |
| var->mode() == Variable::LET); |
| + if (harmony_block_scoping_) { |
| + // In harmony mode we treat re-declarations as early errors. See |
| + // ES5 16 for a definition of early errors. |
| + SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| + const char* elms[2] = { "Variable", *c_string }; |
| + Vector<const char*> args(elms, 2); |
| + ReportMessage("redeclaration", args); |
| + *ok = false; |
| + return NULL; |
| + } |
| const char* type = (var->mode() == Variable::VAR) ? "var" : |
| (var->mode() == Variable::CONST) ? "const" : "let"; |
| Handle<String> type_string = |
| @@ -1380,7 +1397,8 @@ VariableProxy* Parser::Declare(Handle<String> name, |
| // a performance issue since it may lead to repeated |
| // Runtime::DeclareContextSlot() calls. |
| VariableProxy* proxy = declaration_scope->NewUnresolved(name, false); |
| - declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); |
| + declaration_scope->AddDeclaration( |
| + new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
| // For global const variables we bind the proxy to a variable. |
| if (mode == Variable::CONST && declaration_scope->is_global_scope()) { |
| @@ -2207,7 +2225,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
| if (top_scope_->is_strict_mode()) { |
| catch_scope->EnableStrictMode(); |
| } |
| - catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); |
| + Variable::Mode mode = harmony_block_scoping_ |
| + ? Variable::LET : Variable::VAR; |
| + catch_variable = catch_scope->DeclareLocal(name, mode); |
| catch_block = new(zone()) Block(isolate(), NULL, 2, false); |
| Scope* saved_scope = top_scope_; |
| @@ -3736,7 +3756,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
| reserved_loc = scanner().location(); |
| } |
| - top_scope_->DeclareParameter(param_name); |
| + top_scope_->DeclareParameter(param_name, |
| + harmony_block_scoping_ |
| + ? Variable::LET |
| + : Variable::VAR); |
| num_parameters++; |
| if (num_parameters > kMaxNumFunctionParameters) { |
| ReportMessageAt(scanner().location(), "too_many_parameters", |
| @@ -3863,6 +3886,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
| } |
| } |
| + if (harmony_block_scoping_) { |
| + CheckConflictingVarDeclarations(scope, CHECK_OK); |
| + } |
| + |
| FunctionLiteral* function_literal = |
| new(zone()) FunctionLiteral(isolate(), |
| function_name, |
| @@ -4069,6 +4096,21 @@ void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| } |
| +void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| + Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| + if (decl != NULL) { |
| + // In harmony mode we treat conflicting variable bindinds as early |
| + // errors. See ES5 16 for a definition of early errors. |
| + Handle<String> name = decl->proxy()->name(); |
| + SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| + const char* elms[2] = { "Variable", *c_string }; |
| + Vector<const char*> args(elms, 2); |
| + ReportMessage("redeclaration", args); |
|
Steven
2011/08/31 21:33:00
This ReportMessage should rather be a ReportMessag
|
| + *ok = false; |
| + } |
| +} |
| + |
| + |
| // This function reads an identifier name and determines whether or not it |
| // is 'get' or 'set'. |
| Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, |