Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 if (strict_mode == kStrictMode) { | 640 if (strict_mode == kStrictMode) { |
| 641 top_scope_->EnableStrictMode(); | 641 top_scope_->EnableStrictMode(); |
| 642 } | 642 } |
| 643 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 643 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 644 bool ok = true; | 644 bool ok = true; |
| 645 int beg_loc = scanner().location().beg_pos; | 645 int beg_loc = scanner().location().beg_pos; |
| 646 ParseSourceElements(body, Token::EOS, &ok); | 646 ParseSourceElements(body, Token::EOS, &ok); |
| 647 if (ok && top_scope_->is_strict_mode()) { | 647 if (ok && top_scope_->is_strict_mode()) { |
| 648 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 648 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 649 } | 649 } |
| 650 | |
| 651 if (ok && harmony_block_scoping_) { | |
| 652 CheckConflictingVarDeclarations(scope, &ok); | |
| 653 } | |
| 654 | |
| 650 if (ok) { | 655 if (ok) { |
| 651 result = new(zone()) FunctionLiteral( | 656 result = new(zone()) FunctionLiteral( |
| 652 isolate(), | 657 isolate(), |
| 653 no_name, | 658 no_name, |
| 654 top_scope_, | 659 top_scope_, |
| 655 body, | 660 body, |
| 656 lexical_scope.materialized_literal_count(), | 661 lexical_scope.materialized_literal_count(), |
| 657 lexical_scope.expected_property_count(), | 662 lexical_scope.expected_property_count(), |
| 658 lexical_scope.only_simple_this_property_assignments(), | 663 lexical_scope.only_simple_this_property_assignments(), |
| 659 lexical_scope.this_property_assignments(), | 664 lexical_scope.this_property_assignments(), |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1338 declaration_scope->is_strict_mode_eval_scope() || | 1343 declaration_scope->is_strict_mode_eval_scope() || |
| 1339 declaration_scope->is_block_scope()) { | 1344 declaration_scope->is_block_scope()) { |
| 1340 // Declare the variable in the function scope. | 1345 // Declare the variable in the function scope. |
| 1341 var = declaration_scope->LocalLookup(name); | 1346 var = declaration_scope->LocalLookup(name); |
| 1342 if (var == NULL) { | 1347 if (var == NULL) { |
| 1343 // Declare the name. | 1348 // Declare the name. |
| 1344 var = declaration_scope->DeclareLocal(name, mode); | 1349 var = declaration_scope->DeclareLocal(name, mode); |
| 1345 } else { | 1350 } else { |
| 1346 // The name was declared before; check for conflicting re-declarations. | 1351 // The name was declared before; check for conflicting re-declarations. |
| 1347 // We have a conflict if either of the declarations is not a var. There | 1352 // We have a conflict if either of the declarations is not a var. There |
| 1348 // is similar code in runtime.cc in the Declare functions. | 1353 // is similar code in runtime.cc in the Declare functions. Also the |
| 1354 // function CheckNonConflictingScope checks for conflicting hoisting | |
| 1355 // 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
| |
| 1349 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { | 1356 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { |
| 1350 // We only have vars, consts and lets in declarations. | 1357 // We only have vars, consts and lets in declarations. |
| 1351 ASSERT(var->mode() == Variable::VAR || | 1358 ASSERT(var->mode() == Variable::VAR || |
| 1352 var->mode() == Variable::CONST || | 1359 var->mode() == Variable::CONST || |
| 1353 var->mode() == Variable::LET); | 1360 var->mode() == Variable::LET); |
| 1361 if (harmony_block_scoping_) { | |
| 1362 // In harmony mode we treat re-declarations as early errors. See | |
| 1363 // ES5 16 for a definition of early errors. | |
| 1364 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | |
| 1365 const char* elms[2] = { "Variable", *c_string }; | |
| 1366 Vector<const char*> args(elms, 2); | |
| 1367 ReportMessage("redeclaration", args); | |
| 1368 *ok = false; | |
| 1369 return NULL; | |
| 1370 } | |
| 1354 const char* type = (var->mode() == Variable::VAR) ? "var" : | 1371 const char* type = (var->mode() == Variable::VAR) ? "var" : |
| 1355 (var->mode() == Variable::CONST) ? "const" : "let"; | 1372 (var->mode() == Variable::CONST) ? "const" : "let"; |
| 1356 Handle<String> type_string = | 1373 Handle<String> type_string = |
| 1357 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | 1374 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); |
| 1358 Expression* expression = | 1375 Expression* expression = |
| 1359 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | 1376 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), |
| 1360 type_string, name); | 1377 type_string, name); |
| 1361 declaration_scope->SetIllegalRedeclaration(expression); | 1378 declaration_scope->SetIllegalRedeclaration(expression); |
| 1362 } | 1379 } |
| 1363 } | 1380 } |
| 1364 } | 1381 } |
| 1365 | 1382 |
| 1366 // We add a declaration node for every declaration. The compiler | 1383 // We add a declaration node for every declaration. The compiler |
| 1367 // will only generate code if necessary. In particular, declarations | 1384 // will only generate code if necessary. In particular, declarations |
| 1368 // for inner local variables that do not represent functions won't | 1385 // for inner local variables that do not represent functions won't |
| 1369 // result in any generated code. | 1386 // result in any generated code. |
| 1370 // | 1387 // |
| 1371 // Note that we always add an unresolved proxy even if it's not | 1388 // Note that we always add an unresolved proxy even if it's not |
| 1372 // used, simply because we don't know in this method (w/o extra | 1389 // used, simply because we don't know in this method (w/o extra |
| 1373 // parameters) if the proxy is needed or not. The proxy will be | 1390 // parameters) if the proxy is needed or not. The proxy will be |
| 1374 // bound during variable resolution time unless it was pre-bound | 1391 // bound during variable resolution time unless it was pre-bound |
| 1375 // below. | 1392 // below. |
| 1376 // | 1393 // |
| 1377 // WARNING: This will lead to multiple declaration nodes for the | 1394 // WARNING: This will lead to multiple declaration nodes for the |
| 1378 // same variable if it is declared several times. This is not a | 1395 // same variable if it is declared several times. This is not a |
| 1379 // semantic issue as long as we keep the source order, but it may be | 1396 // semantic issue as long as we keep the source order, but it may be |
| 1380 // a performance issue since it may lead to repeated | 1397 // a performance issue since it may lead to repeated |
| 1381 // Runtime::DeclareContextSlot() calls. | 1398 // Runtime::DeclareContextSlot() calls. |
| 1382 VariableProxy* proxy = declaration_scope->NewUnresolved(name, false); | 1399 VariableProxy* proxy = declaration_scope->NewUnresolved(name, false); |
| 1383 declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); | 1400 declaration_scope->AddDeclaration( |
| 1401 new(zone()) Declaration(proxy, mode, fun, top_scope_)); | |
| 1384 | 1402 |
| 1385 // For global const variables we bind the proxy to a variable. | 1403 // For global const variables we bind the proxy to a variable. |
| 1386 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { | 1404 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { |
| 1387 ASSERT(resolve); // should be set by all callers | 1405 ASSERT(resolve); // should be set by all callers |
| 1388 Variable::Kind kind = Variable::NORMAL; | 1406 Variable::Kind kind = Variable::NORMAL; |
| 1389 var = new(zone()) Variable(declaration_scope, | 1407 var = new(zone()) Variable(declaration_scope, |
| 1390 name, | 1408 name, |
| 1391 Variable::CONST, | 1409 Variable::CONST, |
| 1392 true, | 1410 true, |
| 1393 kind); | 1411 kind); |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2200 Expect(Token::RPAREN, CHECK_OK); | 2218 Expect(Token::RPAREN, CHECK_OK); |
| 2201 | 2219 |
| 2202 if (peek() == Token::LBRACE) { | 2220 if (peek() == Token::LBRACE) { |
| 2203 // Rewrite the catch body { B } to a block: | 2221 // Rewrite the catch body { B } to a block: |
| 2204 // { { B } ExitContext; }. | 2222 // { { B } ExitContext; }. |
| 2205 Target target(&this->target_stack_, &catch_collector); | 2223 Target target(&this->target_stack_, &catch_collector); |
| 2206 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | 2224 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
| 2207 if (top_scope_->is_strict_mode()) { | 2225 if (top_scope_->is_strict_mode()) { |
| 2208 catch_scope->EnableStrictMode(); | 2226 catch_scope->EnableStrictMode(); |
| 2209 } | 2227 } |
| 2210 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); | 2228 Variable::Mode mode = harmony_block_scoping_ |
| 2229 ? Variable::LET : Variable::VAR; | |
| 2230 catch_variable = catch_scope->DeclareLocal(name, mode); | |
| 2211 catch_block = new(zone()) Block(isolate(), NULL, 2, false); | 2231 catch_block = new(zone()) Block(isolate(), NULL, 2, false); |
| 2212 | 2232 |
| 2213 Scope* saved_scope = top_scope_; | 2233 Scope* saved_scope = top_scope_; |
| 2214 top_scope_ = catch_scope; | 2234 top_scope_ = catch_scope; |
| 2215 Block* catch_body = ParseBlock(NULL, CHECK_OK); | 2235 Block* catch_body = ParseBlock(NULL, CHECK_OK); |
| 2216 top_scope_ = saved_scope; | 2236 top_scope_ = saved_scope; |
| 2217 catch_block->AddStatement(catch_body); | 2237 catch_block->AddStatement(catch_body); |
| 2218 catch_block->AddStatement(new(zone()) ExitContextStatement()); | 2238 catch_block->AddStatement(new(zone()) ExitContextStatement()); |
| 2219 } else { | 2239 } else { |
| 2220 Expect(Token::LBRACE, CHECK_OK); | 2240 Expect(Token::LBRACE, CHECK_OK); |
| (...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3729 name_loc = scanner().location(); | 3749 name_loc = scanner().location(); |
| 3730 } | 3750 } |
| 3731 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 3751 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 3732 has_duplicate_parameters = true; | 3752 has_duplicate_parameters = true; |
| 3733 dupe_loc = scanner().location(); | 3753 dupe_loc = scanner().location(); |
| 3734 } | 3754 } |
| 3735 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3755 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3736 reserved_loc = scanner().location(); | 3756 reserved_loc = scanner().location(); |
| 3737 } | 3757 } |
| 3738 | 3758 |
| 3739 top_scope_->DeclareParameter(param_name); | 3759 top_scope_->DeclareParameter(param_name, |
| 3760 harmony_block_scoping_ | |
| 3761 ? Variable::LET | |
| 3762 : Variable::VAR); | |
| 3740 num_parameters++; | 3763 num_parameters++; |
| 3741 if (num_parameters > kMaxNumFunctionParameters) { | 3764 if (num_parameters > kMaxNumFunctionParameters) { |
| 3742 ReportMessageAt(scanner().location(), "too_many_parameters", | 3765 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 3743 Vector<const char*>::empty()); | 3766 Vector<const char*>::empty()); |
| 3744 *ok = false; | 3767 *ok = false; |
| 3745 return NULL; | 3768 return NULL; |
| 3746 } | 3769 } |
| 3747 done = (peek() == Token::RPAREN); | 3770 done = (peek() == Token::RPAREN); |
| 3748 if (!done) Expect(Token::COMMA, CHECK_OK); | 3771 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3749 } | 3772 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3856 if (reserved_loc.IsValid()) { | 3879 if (reserved_loc.IsValid()) { |
| 3857 ReportMessageAt(reserved_loc, "strict_reserved_word", | 3880 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3858 Vector<const char*>::empty()); | 3881 Vector<const char*>::empty()); |
| 3859 *ok = false; | 3882 *ok = false; |
| 3860 return NULL; | 3883 return NULL; |
| 3861 } | 3884 } |
| 3862 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3885 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
| 3863 } | 3886 } |
| 3864 } | 3887 } |
| 3865 | 3888 |
| 3889 if (harmony_block_scoping_) { | |
| 3890 CheckConflictingVarDeclarations(scope, CHECK_OK); | |
| 3891 } | |
| 3892 | |
| 3866 FunctionLiteral* function_literal = | 3893 FunctionLiteral* function_literal = |
| 3867 new(zone()) FunctionLiteral(isolate(), | 3894 new(zone()) FunctionLiteral(isolate(), |
| 3868 function_name, | 3895 function_name, |
| 3869 scope, | 3896 scope, |
| 3870 body, | 3897 body, |
| 3871 materialized_literal_count, | 3898 materialized_literal_count, |
| 3872 expected_property_count, | 3899 expected_property_count, |
| 3873 only_simple_this_property_assignments, | 3900 only_simple_this_property_assignments, |
| 3874 this_property_assignments, | 3901 this_property_assignments, |
| 3875 num_parameters, | 3902 num_parameters, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4062 beg_pos <= octal.beg_pos && | 4089 beg_pos <= octal.beg_pos && |
| 4063 octal.end_pos <= end_pos) { | 4090 octal.end_pos <= end_pos) { |
| 4064 ReportMessageAt(octal, "strict_octal_literal", | 4091 ReportMessageAt(octal, "strict_octal_literal", |
| 4065 Vector<const char*>::empty()); | 4092 Vector<const char*>::empty()); |
| 4066 scanner().clear_octal_position(); | 4093 scanner().clear_octal_position(); |
| 4067 *ok = false; | 4094 *ok = false; |
| 4068 } | 4095 } |
| 4069 } | 4096 } |
| 4070 | 4097 |
| 4071 | 4098 |
| 4099 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | |
| 4100 Declaration* decl = scope->CheckConflictingVarDeclarations(); | |
| 4101 if (decl != NULL) { | |
| 4102 // In harmony mode we treat conflicting variable bindinds as early | |
| 4103 // errors. See ES5 16 for a definition of early errors. | |
| 4104 Handle<String> name = decl->proxy()->name(); | |
| 4105 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | |
| 4106 const char* elms[2] = { "Variable", *c_string }; | |
| 4107 Vector<const char*> args(elms, 2); | |
| 4108 ReportMessage("redeclaration", args); | |
|
Steven
2011/08/31 21:33:00
This ReportMessage should rather be a ReportMessag
| |
| 4109 *ok = false; | |
| 4110 } | |
| 4111 } | |
| 4112 | |
| 4113 | |
| 4072 // This function reads an identifier name and determines whether or not it | 4114 // This function reads an identifier name and determines whether or not it |
| 4073 // is 'get' or 'set'. | 4115 // is 'get' or 'set'. |
| 4074 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 4116 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 4075 bool* is_set, | 4117 bool* is_set, |
| 4076 bool* ok) { | 4118 bool* ok) { |
| 4077 Handle<String> result = ParseIdentifierName(ok); | 4119 Handle<String> result = ParseIdentifierName(ok); |
| 4078 if (!*ok) return Handle<String>(); | 4120 if (!*ok) return Handle<String>(); |
| 4079 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { | 4121 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { |
| 4080 const char* token = scanner().literal_ascii_string().start(); | 4122 const char* token = scanner().literal_ascii_string().start(); |
| 4081 *is_get = strncmp(token, "get", 3) == 0; | 4123 *is_get = strncmp(token, "get", 3) == 0; |
| (...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5183 result = parser.ParseProgram(source, | 5225 result = parser.ParseProgram(source, |
| 5184 info->is_global(), | 5226 info->is_global(), |
| 5185 info->StrictMode()); | 5227 info->StrictMode()); |
| 5186 } | 5228 } |
| 5187 } | 5229 } |
| 5188 info->SetFunction(result); | 5230 info->SetFunction(result); |
| 5189 return (result != NULL); | 5231 return (result != NULL); |
| 5190 } | 5232 } |
| 5191 | 5233 |
| 5192 } } // namespace v8::internal | 5234 } } // namespace v8::internal |
| OLD | NEW |