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 |