| 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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 scanner_(isolate_->unicode_cache()), | 577 scanner_(isolate_->unicode_cache()), |
| 578 top_scope_(NULL), | 578 top_scope_(NULL), |
| 579 with_nesting_level_(0), | 579 with_nesting_level_(0), |
| 580 lexical_scope_(NULL), | 580 lexical_scope_(NULL), |
| 581 target_stack_(NULL), | 581 target_stack_(NULL), |
| 582 allow_natives_syntax_(allow_natives_syntax), | 582 allow_natives_syntax_(allow_natives_syntax), |
| 583 extension_(extension), | 583 extension_(extension), |
| 584 pre_data_(pre_data), | 584 pre_data_(pre_data), |
| 585 fni_(NULL), | 585 fni_(NULL), |
| 586 stack_overflow_(false), | 586 stack_overflow_(false), |
| 587 parenthesized_function_(false) { | 587 parenthesized_function_(false), |
| 588 harmony_block_scoping_(false) { |
| 588 AstNode::ResetIds(); | 589 AstNode::ResetIds(); |
| 589 } | 590 } |
| 590 | 591 |
| 591 | 592 |
| 592 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 593 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 593 bool in_global_context, | 594 bool in_global_context, |
| 594 StrictModeFlag strict_mode) { | 595 StrictModeFlag strict_mode) { |
| 595 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); | 596 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); |
| 596 | 597 |
| 597 HistogramTimerScope timer(isolate()->counters()->parse()); | 598 HistogramTimerScope timer(isolate()->counters()->parse()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 no_name, | 653 no_name, |
| 653 top_scope_, | 654 top_scope_, |
| 654 body, | 655 body, |
| 655 lexical_scope.materialized_literal_count(), | 656 lexical_scope.materialized_literal_count(), |
| 656 lexical_scope.expected_property_count(), | 657 lexical_scope.expected_property_count(), |
| 657 lexical_scope.only_simple_this_property_assignments(), | 658 lexical_scope.only_simple_this_property_assignments(), |
| 658 lexical_scope.this_property_assignments(), | 659 lexical_scope.this_property_assignments(), |
| 659 0, | 660 0, |
| 660 0, | 661 0, |
| 661 source->length(), | 662 source->length(), |
| 662 false, | 663 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 663 false); | 664 false); // Does not have duplicate parameters. |
| 664 } else if (stack_overflow_) { | 665 } else if (stack_overflow_) { |
| 665 isolate()->StackOverflow(); | 666 isolate()->StackOverflow(); |
| 666 } | 667 } |
| 667 } | 668 } |
| 668 | 669 |
| 669 // Make sure the target stack is empty. | 670 // Make sure the target stack is empty. |
| 670 ASSERT(target_stack_ == NULL); | 671 ASSERT(target_stack_ == NULL); |
| 671 | 672 |
| 672 // If there was a syntax error we have to get rid of the AST | 673 // If there was a syntax error we have to get rid of the AST |
| 673 // and it is not safe to do so before the scope has been deleted. | 674 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 723 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 723 if (!info->closure().is_null()) { | 724 if (!info->closure().is_null()) { |
| 724 scope = Scope::DeserializeScopeChain(info, scope); | 725 scope = Scope::DeserializeScopeChain(info, scope); |
| 725 } | 726 } |
| 726 LexicalScope lexical_scope(this, scope, isolate()); | 727 LexicalScope lexical_scope(this, scope, isolate()); |
| 727 | 728 |
| 728 if (shared_info->strict_mode()) { | 729 if (shared_info->strict_mode()) { |
| 729 top_scope_->EnableStrictMode(); | 730 top_scope_->EnableStrictMode(); |
| 730 } | 731 } |
| 731 | 732 |
| 732 FunctionLiteralType type = | 733 FunctionLiteral::Type type = shared_info->is_expression() |
| 733 shared_info->is_expression() ? EXPRESSION : DECLARATION; | 734 ? (shared_info->is_anonymous() |
| 734 Handle<String> function_name = | 735 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 735 shared_info->is_anonymous() ? Handle<String>::null() : name; | 736 : FunctionLiteral::NAMED_EXPRESSION) |
| 737 : FunctionLiteral::DECLARATION; |
| 736 bool ok = true; | 738 bool ok = true; |
| 737 result = ParseFunctionLiteral(function_name, | 739 result = ParseFunctionLiteral(name, |
| 738 false, // Strict mode name already checked. | 740 false, // Strict mode name already checked. |
| 739 RelocInfo::kNoPosition, | 741 RelocInfo::kNoPosition, |
| 740 type, | 742 type, |
| 741 &ok); | 743 &ok); |
| 742 // Make sure the results agree. | 744 // Make sure the results agree. |
| 743 ASSERT(ok == (result != NULL)); | 745 ASSERT(ok == (result != NULL)); |
| 744 } | 746 } |
| 745 | 747 |
| 746 // Make sure the target stack is empty. | 748 // Make sure the target stack is empty. |
| 747 ASSERT(target_stack_ == NULL); | 749 ASSERT(target_stack_ == NULL); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 Factory* factory = isolate()->factory(); | 803 Factory* factory = isolate()->factory(); |
| 802 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 804 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 803 for (int i = 0; i < args.length(); i++) { | 805 for (int i = 0; i < args.length(); i++) { |
| 804 elements->set(i, *args[i]); | 806 elements->set(i, *args[i]); |
| 805 } | 807 } |
| 806 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 808 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 807 Handle<Object> result = factory->NewSyntaxError(type, array); | 809 Handle<Object> result = factory->NewSyntaxError(type, array); |
| 808 isolate()->Throw(*result, &location); | 810 isolate()->Throw(*result, &location); |
| 809 } | 811 } |
| 810 | 812 |
| 813 void Parser::SetHarmonyBlockScoping(bool block_scoping) { |
| 814 scanner().SetHarmonyBlockScoping(block_scoping); |
| 815 harmony_block_scoping_ = block_scoping; |
| 816 } |
| 811 | 817 |
| 812 // Base class containing common code for the different finder classes used by | 818 // Base class containing common code for the different finder classes used by |
| 813 // the parser. | 819 // the parser. |
| 814 class ParserFinder { | 820 class ParserFinder { |
| 815 protected: | 821 protected: |
| 816 ParserFinder() {} | 822 ParserFinder() {} |
| 817 static Assignment* AsAssignment(Statement* stat) { | 823 static Assignment* AsAssignment(Statement* stat) { |
| 818 if (stat == NULL) return NULL; | 824 if (stat == NULL) return NULL; |
| 819 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); | 825 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); |
| 820 if (exp_stat == NULL) return NULL; | 826 if (exp_stat == NULL) return NULL; |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 } | 1087 } |
| 1082 | 1088 |
| 1083 Isolate* isolate_; | 1089 Isolate* isolate_; |
| 1084 bool only_simple_this_property_assignments_; | 1090 bool only_simple_this_property_assignments_; |
| 1085 ZoneStringList* names_; | 1091 ZoneStringList* names_; |
| 1086 ZoneList<int>* assigned_arguments_; | 1092 ZoneList<int>* assigned_arguments_; |
| 1087 ZoneObjectList* assigned_constants_; | 1093 ZoneObjectList* assigned_constants_; |
| 1088 }; | 1094 }; |
| 1089 | 1095 |
| 1090 | 1096 |
| 1097 Statement* Parser::ParseSourceElement(ZoneStringList* labels, |
| 1098 bool* ok) { |
| 1099 if (peek() == Token::FUNCTION) { |
| 1100 // FunctionDeclaration is only allowed in the context of SourceElements |
| 1101 // (Ecma 262 5th Edition, clause 14): |
| 1102 // SourceElement: |
| 1103 // Statement |
| 1104 // FunctionDeclaration |
| 1105 // Common language extension is to allow function declaration in place |
| 1106 // of any statement. This language extension is disabled in strict mode. |
| 1107 return ParseFunctionDeclaration(ok); |
| 1108 } else if (peek() == Token::LET) { |
| 1109 return ParseVariableStatement(kSourceElement, ok); |
| 1110 } else { |
| 1111 return ParseStatement(labels, ok); |
| 1112 } |
| 1113 } |
| 1114 |
| 1115 |
| 1091 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1116 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1092 int end_token, | 1117 int end_token, |
| 1093 bool* ok) { | 1118 bool* ok) { |
| 1094 // SourceElements :: | 1119 // SourceElements :: |
| 1095 // (Statement)* <end_token> | 1120 // (Statement)* <end_token> |
| 1096 | 1121 |
| 1097 // Allocate a target stack to use for this set of source | 1122 // Allocate a target stack to use for this set of source |
| 1098 // elements. This way, all scripts and functions get their own | 1123 // elements. This way, all scripts and functions get their own |
| 1099 // target stack thus avoiding illegal breaks and continues across | 1124 // target stack thus avoiding illegal breaks and continues across |
| 1100 // functions. | 1125 // functions. |
| 1101 TargetScope scope(&this->target_stack_); | 1126 TargetScope scope(&this->target_stack_); |
| 1102 | 1127 |
| 1103 ASSERT(processor != NULL); | 1128 ASSERT(processor != NULL); |
| 1104 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1129 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1105 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); | 1130 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); |
| 1106 bool directive_prologue = true; // Parsing directive prologue. | 1131 bool directive_prologue = true; // Parsing directive prologue. |
| 1107 | 1132 |
| 1108 while (peek() != end_token) { | 1133 while (peek() != end_token) { |
| 1109 if (directive_prologue && peek() != Token::STRING) { | 1134 if (directive_prologue && peek() != Token::STRING) { |
| 1110 directive_prologue = false; | 1135 directive_prologue = false; |
| 1111 } | 1136 } |
| 1112 | 1137 |
| 1113 Scanner::Location token_loc = scanner().peek_location(); | 1138 Scanner::Location token_loc = scanner().peek_location(); |
| 1114 | 1139 Statement* stat = ParseSourceElement(NULL, CHECK_OK); |
| 1115 Statement* stat; | |
| 1116 if (peek() == Token::FUNCTION) { | |
| 1117 // FunctionDeclaration is only allowed in the context of SourceElements | |
| 1118 // (Ecma 262 5th Edition, clause 14): | |
| 1119 // SourceElement: | |
| 1120 // Statement | |
| 1121 // FunctionDeclaration | |
| 1122 // Common language extension is to allow function declaration in place | |
| 1123 // of any statement. This language extension is disabled in strict mode. | |
| 1124 stat = ParseFunctionDeclaration(CHECK_OK); | |
| 1125 } else { | |
| 1126 stat = ParseStatement(NULL, CHECK_OK); | |
| 1127 } | |
| 1128 | |
| 1129 if (stat == NULL || stat->IsEmpty()) { | 1140 if (stat == NULL || stat->IsEmpty()) { |
| 1130 directive_prologue = false; // End of directive prologue. | 1141 directive_prologue = false; // End of directive prologue. |
| 1131 continue; | 1142 continue; |
| 1132 } | 1143 } |
| 1133 | 1144 |
| 1134 if (directive_prologue) { | 1145 if (directive_prologue) { |
| 1135 // A shot at a directive. | 1146 // A shot at a directive. |
| 1136 ExpressionStatement *e_stat; | 1147 ExpressionStatement *e_stat; |
| 1137 Literal *literal; | 1148 Literal *literal; |
| 1138 // Still processing directive prologue? | 1149 // Still processing directive prologue? |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 | 1217 |
| 1207 // Keep the source position of the statement | 1218 // Keep the source position of the statement |
| 1208 int statement_pos = scanner().peek_location().beg_pos; | 1219 int statement_pos = scanner().peek_location().beg_pos; |
| 1209 Statement* stmt = NULL; | 1220 Statement* stmt = NULL; |
| 1210 switch (peek()) { | 1221 switch (peek()) { |
| 1211 case Token::LBRACE: | 1222 case Token::LBRACE: |
| 1212 return ParseBlock(labels, ok); | 1223 return ParseBlock(labels, ok); |
| 1213 | 1224 |
| 1214 case Token::CONST: // fall through | 1225 case Token::CONST: // fall through |
| 1215 case Token::VAR: | 1226 case Token::VAR: |
| 1216 stmt = ParseVariableStatement(ok); | 1227 stmt = ParseVariableStatement(kStatement, ok); |
| 1217 break; | 1228 break; |
| 1218 | 1229 |
| 1219 case Token::SEMICOLON: | 1230 case Token::SEMICOLON: |
| 1220 Next(); | 1231 Next(); |
| 1221 return EmptyStatement(); | 1232 return EmptyStatement(); |
| 1222 | 1233 |
| 1223 case Token::IF: | 1234 case Token::IF: |
| 1224 stmt = ParseIfStatement(labels, ok); | 1235 stmt = ParseIfStatement(labels, ok); |
| 1225 break; | 1236 break; |
| 1226 | 1237 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 return stmt; | 1312 return stmt; |
| 1302 } | 1313 } |
| 1303 | 1314 |
| 1304 | 1315 |
| 1305 VariableProxy* Parser::Declare(Handle<String> name, | 1316 VariableProxy* Parser::Declare(Handle<String> name, |
| 1306 Variable::Mode mode, | 1317 Variable::Mode mode, |
| 1307 FunctionLiteral* fun, | 1318 FunctionLiteral* fun, |
| 1308 bool resolve, | 1319 bool resolve, |
| 1309 bool* ok) { | 1320 bool* ok) { |
| 1310 Variable* var = NULL; | 1321 Variable* var = NULL; |
| 1311 // If we are inside a function, a declaration of a variable | 1322 // If we are inside a function, a declaration of a var/const variable is a |
| 1312 // is a truly local variable, and the scope of the variable | 1323 // truly local variable, and the scope of the variable is always the function |
| 1313 // is always the function scope. | 1324 // scope. |
| 1314 | 1325 |
| 1315 // If a function scope exists, then we can statically declare this | 1326 // If a function scope exists, then we can statically declare this |
| 1316 // variable and also set its mode. In any case, a Declaration node | 1327 // variable and also set its mode. In any case, a Declaration node |
| 1317 // will be added to the scope so that the declaration can be added | 1328 // will be added to the scope so that the declaration can be added |
| 1318 // to the corresponding activation frame at runtime if necessary. | 1329 // to the corresponding activation frame at runtime if necessary. |
| 1319 // For instance declarations inside an eval scope need to be added | 1330 // For instance declarations inside an eval scope need to be added |
| 1320 // to the calling function context. | 1331 // to the calling function context. |
| 1321 // Similarly, strict mode eval scope does not leak variable declarations to | 1332 // Similarly, strict mode eval scope does not leak variable declarations to |
| 1322 // the caller's scope so we declare all locals, too. | 1333 // the caller's scope so we declare all locals, too. |
| 1323 Scope* declaration_scope = top_scope_->DeclarationScope(); | 1334 |
| 1335 Scope* declaration_scope = mode == Variable::LET ? top_scope_ |
| 1336 : top_scope_->DeclarationScope(); |
| 1324 if (declaration_scope->is_function_scope() || | 1337 if (declaration_scope->is_function_scope() || |
| 1325 declaration_scope->is_strict_mode_eval_scope()) { | 1338 declaration_scope->is_strict_mode_eval_scope() || |
| 1339 declaration_scope->is_block_scope()) { |
| 1326 // Declare the variable in the function scope. | 1340 // Declare the variable in the function scope. |
| 1327 var = declaration_scope->LocalLookup(name); | 1341 var = declaration_scope->LocalLookup(name); |
| 1328 if (var == NULL) { | 1342 if (var == NULL) { |
| 1329 // Declare the name. | 1343 // Declare the name. |
| 1330 var = declaration_scope->DeclareLocal(name, mode); | 1344 var = declaration_scope->DeclareLocal(name, mode); |
| 1331 } else { | 1345 } else { |
| 1332 // The name was declared before; check for conflicting | 1346 // The name was declared before; check for conflicting re-declarations. |
| 1333 // re-declarations. If the previous declaration was a const or the | 1347 // We have a conflict if either of the declarations is not a var. There |
| 1334 // current declaration is a const then we have a conflict. There is | 1348 // is similar code in runtime.cc in the Declare functions. |
| 1335 // similar code in runtime.cc in the Declare functions. | 1349 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { |
| 1336 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { | 1350 // We only have vars, consts and lets in declarations. |
| 1337 // We only have vars and consts in declarations. | |
| 1338 ASSERT(var->mode() == Variable::VAR || | 1351 ASSERT(var->mode() == Variable::VAR || |
| 1339 var->mode() == Variable::CONST); | 1352 var->mode() == Variable::CONST || |
| 1340 const char* type = (var->mode() == Variable::VAR) ? "var" : "const"; | 1353 var->mode() == Variable::LET); |
| 1354 const char* type = (var->mode() == Variable::VAR) ? "var" : |
| 1355 (var->mode() == Variable::CONST) ? "const" : "let"; |
| 1341 Handle<String> type_string = | 1356 Handle<String> type_string = |
| 1342 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | 1357 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); |
| 1343 Expression* expression = | 1358 Expression* expression = |
| 1344 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | 1359 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), |
| 1345 type_string, name); | 1360 type_string, name); |
| 1346 declaration_scope->SetIllegalRedeclaration(expression); | 1361 declaration_scope->SetIllegalRedeclaration(expression); |
| 1347 } | 1362 } |
| 1348 } | 1363 } |
| 1349 } | 1364 } |
| 1350 | 1365 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 // FunctionDeclaration :: | 1483 // FunctionDeclaration :: |
| 1469 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1484 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1470 Expect(Token::FUNCTION, CHECK_OK); | 1485 Expect(Token::FUNCTION, CHECK_OK); |
| 1471 int function_token_position = scanner().location().beg_pos; | 1486 int function_token_position = scanner().location().beg_pos; |
| 1472 bool is_strict_reserved = false; | 1487 bool is_strict_reserved = false; |
| 1473 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1488 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1474 &is_strict_reserved, CHECK_OK); | 1489 &is_strict_reserved, CHECK_OK); |
| 1475 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1490 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1476 is_strict_reserved, | 1491 is_strict_reserved, |
| 1477 function_token_position, | 1492 function_token_position, |
| 1478 DECLARATION, | 1493 FunctionLiteral::DECLARATION, |
| 1479 CHECK_OK); | 1494 CHECK_OK); |
| 1480 // Even if we're not at the top-level of the global or a function | 1495 // Even if we're not at the top-level of the global or a function |
| 1481 // scope, we treat is as such and introduce the function with it's | 1496 // scope, we treat is as such and introduce the function with it's |
| 1482 // initial value upon entering the corresponding scope. | 1497 // initial value upon entering the corresponding scope. |
| 1483 Declare(name, Variable::VAR, fun, true, CHECK_OK); | 1498 Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR; |
| 1499 Declare(name, mode, fun, true, CHECK_OK); |
| 1484 return EmptyStatement(); | 1500 return EmptyStatement(); |
| 1485 } | 1501 } |
| 1486 | 1502 |
| 1487 | 1503 |
| 1488 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1504 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1505 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); |
| 1506 |
| 1489 // Block :: | 1507 // Block :: |
| 1490 // '{' Statement* '}' | 1508 // '{' Statement* '}' |
| 1491 | 1509 |
| 1492 // Note that a Block does not introduce a new execution scope! | 1510 // Note that a Block does not introduce a new execution scope! |
| 1493 // (ECMA-262, 3rd, 12.2) | 1511 // (ECMA-262, 3rd, 12.2) |
| 1494 // | 1512 // |
| 1495 // Construct block expecting 16 statements. | 1513 // Construct block expecting 16 statements. |
| 1496 Block* result = new(zone()) Block(isolate(), labels, 16, false); | 1514 Block* result = new(zone()) Block(isolate(), labels, 16, false); |
| 1497 Target target(&this->target_stack_, result); | 1515 Target target(&this->target_stack_, result); |
| 1498 Expect(Token::LBRACE, CHECK_OK); | 1516 Expect(Token::LBRACE, CHECK_OK); |
| 1499 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1517 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1500 while (peek() != Token::RBRACE) { | 1518 while (peek() != Token::RBRACE) { |
| 1501 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1519 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1502 if (stat && !stat->IsEmpty()) { | 1520 if (stat && !stat->IsEmpty()) { |
| 1503 result->AddStatement(stat); | 1521 result->AddStatement(stat); |
| 1504 block_finder.Update(stat); | 1522 block_finder.Update(stat); |
| 1505 } | 1523 } |
| 1506 } | 1524 } |
| 1507 Expect(Token::RBRACE, CHECK_OK); | 1525 Expect(Token::RBRACE, CHECK_OK); |
| 1508 return result; | 1526 return result; |
| 1509 } | 1527 } |
| 1510 | 1528 |
| 1511 | 1529 |
| 1512 Block* Parser::ParseVariableStatement(bool* ok) { | 1530 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1531 // Construct block expecting 16 statements. |
| 1532 Block* body = new(zone()) Block(isolate(), labels, 16, false); |
| 1533 Scope* saved_scope = top_scope_; |
| 1534 Scope* block_scope = NewScope(top_scope_, |
| 1535 Scope::BLOCK_SCOPE, |
| 1536 inside_with()); |
| 1537 body->set_block_scope(block_scope); |
| 1538 block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(), |
| 1539 Variable::VAR); |
| 1540 if (top_scope_->is_strict_mode()) { |
| 1541 block_scope->EnableStrictMode(); |
| 1542 } |
| 1543 top_scope_ = block_scope; |
| 1544 |
| 1545 // Parse the statements and collect escaping labels. |
| 1546 TargetCollector collector; |
| 1547 Target target(&this->target_stack_, &collector); |
| 1548 Expect(Token::LBRACE, CHECK_OK); |
| 1549 { |
| 1550 Target target_body(&this->target_stack_, body); |
| 1551 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1552 |
| 1553 while (peek() != Token::RBRACE) { |
| 1554 Statement* stat = ParseSourceElement(NULL, CHECK_OK); |
| 1555 if (stat && !stat->IsEmpty()) { |
| 1556 body->AddStatement(stat); |
| 1557 block_finder.Update(stat); |
| 1558 } |
| 1559 } |
| 1560 } |
| 1561 Expect(Token::RBRACE, CHECK_OK); |
| 1562 |
| 1563 // Create exit block. |
| 1564 Block* exit = new(zone()) Block(isolate(), NULL, 1, false); |
| 1565 exit->AddStatement(new(zone()) ExitContextStatement()); |
| 1566 |
| 1567 // Create a try-finally statement. |
| 1568 TryFinallyStatement* try_finally = |
| 1569 new(zone()) TryFinallyStatement(body, exit); |
| 1570 try_finally->set_escaping_targets(collector.targets()); |
| 1571 top_scope_ = saved_scope; |
| 1572 |
| 1573 // Create a result block. |
| 1574 Block* result = new(zone()) Block(isolate(), NULL, 1, false); |
| 1575 result->AddStatement(try_finally); |
| 1576 return result; |
| 1577 } |
| 1578 |
| 1579 |
| 1580 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1581 bool* ok) { |
| 1513 // VariableStatement :: | 1582 // VariableStatement :: |
| 1514 // VariableDeclarations ';' | 1583 // VariableDeclarations ';' |
| 1515 | 1584 |
| 1516 Handle<String> ignore; | 1585 Handle<String> ignore; |
| 1517 Block* result = ParseVariableDeclarations(true, &ignore, CHECK_OK); | 1586 Block* result = ParseVariableDeclarations(var_context, |
| 1587 &ignore, |
| 1588 CHECK_OK); |
| 1518 ExpectSemicolon(CHECK_OK); | 1589 ExpectSemicolon(CHECK_OK); |
| 1519 return result; | 1590 return result; |
| 1520 } | 1591 } |
| 1521 | 1592 |
| 1522 | 1593 |
| 1523 bool Parser::IsEvalOrArguments(Handle<String> string) { | 1594 bool Parser::IsEvalOrArguments(Handle<String> string) { |
| 1524 return string.is_identical_to(isolate()->factory()->eval_symbol()) || | 1595 return string.is_identical_to(isolate()->factory()->eval_symbol()) || |
| 1525 string.is_identical_to(isolate()->factory()->arguments_symbol()); | 1596 string.is_identical_to(isolate()->factory()->arguments_symbol()); |
| 1526 } | 1597 } |
| 1527 | 1598 |
| 1528 | 1599 |
| 1529 // If the variable declaration declares exactly one non-const | 1600 // If the variable declaration declares exactly one non-const |
| 1530 // variable, then *var is set to that variable. In all other cases, | 1601 // variable, then *var is set to that variable. In all other cases, |
| 1531 // *var is untouched; in particular, it is the caller's responsibility | 1602 // *var is untouched; in particular, it is the caller's responsibility |
| 1532 // to initialize it properly. This mechanism is used for the parsing | 1603 // to initialize it properly. This mechanism is used for the parsing |
| 1533 // of 'for-in' loops. | 1604 // of 'for-in' loops. |
| 1534 Block* Parser::ParseVariableDeclarations(bool accept_IN, | 1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, |
| 1535 Handle<String>* out, | 1606 Handle<String>* out, |
| 1536 bool* ok) { | 1607 bool* ok) { |
| 1537 // VariableDeclarations :: | 1608 // VariableDeclarations :: |
| 1538 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1539 | 1610 |
| 1540 Variable::Mode mode = Variable::VAR; | 1611 Variable::Mode mode = Variable::VAR; |
| 1541 bool is_const = false; | 1612 bool is_const = false; |
| 1542 Scope* declaration_scope = top_scope_->DeclarationScope(); | |
| 1543 if (peek() == Token::VAR) { | 1613 if (peek() == Token::VAR) { |
| 1544 Consume(Token::VAR); | 1614 Consume(Token::VAR); |
| 1545 } else if (peek() == Token::CONST) { | 1615 } else if (peek() == Token::CONST) { |
| 1546 Consume(Token::CONST); | 1616 Consume(Token::CONST); |
| 1547 if (declaration_scope->is_strict_mode()) { | 1617 if (top_scope_->is_strict_mode()) { |
| 1548 ReportMessage("strict_const", Vector<const char*>::empty()); | 1618 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1549 *ok = false; | 1619 *ok = false; |
| 1550 return NULL; | 1620 return NULL; |
| 1551 } | 1621 } |
| 1552 mode = Variable::CONST; | 1622 mode = Variable::CONST; |
| 1553 is_const = true; | 1623 is_const = true; |
| 1624 } else if (peek() == Token::LET) { |
| 1625 Consume(Token::LET); |
| 1626 if (var_context != kSourceElement && |
| 1627 var_context != kForStatement) { |
| 1628 ASSERT(var_context == kStatement); |
| 1629 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
| 1630 *ok = false; |
| 1631 return NULL; |
| 1632 } |
| 1633 mode = Variable::LET; |
| 1554 } else { | 1634 } else { |
| 1555 UNREACHABLE(); // by current callers | 1635 UNREACHABLE(); // by current callers |
| 1556 } | 1636 } |
| 1557 | 1637 |
| 1558 // The scope of a variable/const declared anywhere inside a function | 1638 Scope* declaration_scope = mode == Variable::LET |
| 1639 ? top_scope_ : top_scope_->DeclarationScope(); |
| 1640 // The scope of a var/const declared variable anywhere inside a function |
| 1559 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 1641 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 1560 // transform a source-level variable/const declaration into a (Function) | 1642 // transform a source-level var/const declaration into a (Function) |
| 1561 // Scope declaration, and rewrite the source-level initialization into an | 1643 // Scope declaration, and rewrite the source-level initialization into an |
| 1562 // assignment statement. We use a block to collect multiple assignments. | 1644 // assignment statement. We use a block to collect multiple assignments. |
| 1563 // | 1645 // |
| 1564 // We mark the block as initializer block because we don't want the | 1646 // We mark the block as initializer block because we don't want the |
| 1565 // rewriter to add a '.result' assignment to such a block (to get compliant | 1647 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1566 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1648 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 1567 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1649 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 1568 // is inside an initializer block, it is ignored. | 1650 // is inside an initializer block, it is ignored. |
| 1569 // | 1651 // |
| 1570 // Create new block with one expected declaration. | 1652 // Create new block with one expected declaration. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 // The "variable" c initialized to x is the same as the declared | 1716 // The "variable" c initialized to x is the same as the declared |
| 1635 // one - there is no re-lookup (see the last parameter of the | 1717 // one - there is no re-lookup (see the last parameter of the |
| 1636 // Declare() call above). | 1718 // Declare() call above). |
| 1637 | 1719 |
| 1638 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1720 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
| 1639 Expression* value = NULL; | 1721 Expression* value = NULL; |
| 1640 int position = -1; | 1722 int position = -1; |
| 1641 if (peek() == Token::ASSIGN) { | 1723 if (peek() == Token::ASSIGN) { |
| 1642 Expect(Token::ASSIGN, CHECK_OK); | 1724 Expect(Token::ASSIGN, CHECK_OK); |
| 1643 position = scanner().location().beg_pos; | 1725 position = scanner().location().beg_pos; |
| 1644 value = ParseAssignmentExpression(accept_IN, CHECK_OK); | 1726 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1645 // Don't infer if it is "a = function(){...}();"-like expression. | 1727 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1646 if (fni_ != NULL && | 1728 if (fni_ != NULL && |
| 1647 value->AsCall() == NULL && | 1729 value->AsCall() == NULL && |
| 1648 value->AsCallNew() == NULL) { | 1730 value->AsCallNew() == NULL) { |
| 1649 fni_->Infer(); | 1731 fni_->Infer(); |
| 1650 } | 1732 } |
| 1651 } | 1733 } |
| 1652 | 1734 |
| 1653 // Make sure that 'const c' actually initializes 'c' to undefined | 1735 // Make sure that 'const c' actually initializes 'c' to undefined |
| 1654 // even though it seems like a stupid thing to do. | 1736 // even though it seems like a stupid thing to do. |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 ExpectSemicolon(CHECK_OK); | 2030 ExpectSemicolon(CHECK_OK); |
| 1949 return new(zone()) ReturnStatement(GetLiteralUndefined()); | 2031 return new(zone()) ReturnStatement(GetLiteralUndefined()); |
| 1950 } | 2032 } |
| 1951 | 2033 |
| 1952 Expression* expr = ParseExpression(true, CHECK_OK); | 2034 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1953 ExpectSemicolon(CHECK_OK); | 2035 ExpectSemicolon(CHECK_OK); |
| 1954 return new(zone()) ReturnStatement(expr); | 2036 return new(zone()) ReturnStatement(expr); |
| 1955 } | 2037 } |
| 1956 | 2038 |
| 1957 | 2039 |
| 1958 Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) { | |
| 1959 // Parse the statement and collect escaping labels. | |
| 1960 TargetCollector collector; | |
| 1961 Statement* stat; | |
| 1962 { Target target(&this->target_stack_, &collector); | |
| 1963 with_nesting_level_++; | |
| 1964 top_scope_->DeclarationScope()->RecordWithStatement(); | |
| 1965 stat = ParseStatement(labels, CHECK_OK); | |
| 1966 with_nesting_level_--; | |
| 1967 } | |
| 1968 // Create resulting block with two statements. | |
| 1969 // 1: Evaluate the with expression. | |
| 1970 // 2: The try-finally block evaluating the body. | |
| 1971 Block* result = new(zone()) Block(isolate(), NULL, 2, false); | |
| 1972 | |
| 1973 if (result != NULL) { | |
| 1974 result->AddStatement(new(zone()) EnterWithContextStatement(obj)); | |
| 1975 | |
| 1976 // Create body block. | |
| 1977 Block* body = new(zone()) Block(isolate(), NULL, 1, false); | |
| 1978 body->AddStatement(stat); | |
| 1979 | |
| 1980 // Create exit block. | |
| 1981 Block* exit = new(zone()) Block(isolate(), NULL, 1, false); | |
| 1982 exit->AddStatement(new(zone()) ExitContextStatement()); | |
| 1983 | |
| 1984 // Return a try-finally statement. | |
| 1985 TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit); | |
| 1986 wrapper->set_escaping_targets(collector.targets()); | |
| 1987 result->AddStatement(wrapper); | |
| 1988 } | |
| 1989 return result; | |
| 1990 } | |
| 1991 | |
| 1992 | |
| 1993 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2040 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1994 // WithStatement :: | 2041 // WithStatement :: |
| 1995 // 'with' '(' Expression ')' Statement | 2042 // 'with' '(' Expression ')' Statement |
| 1996 | 2043 |
| 1997 Expect(Token::WITH, CHECK_OK); | 2044 Expect(Token::WITH, CHECK_OK); |
| 1998 | 2045 |
| 1999 if (top_scope_->is_strict_mode()) { | 2046 if (top_scope_->is_strict_mode()) { |
| 2000 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2047 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2001 *ok = false; | 2048 *ok = false; |
| 2002 return NULL; | 2049 return NULL; |
| 2003 } | 2050 } |
| 2004 | 2051 |
| 2005 Expect(Token::LPAREN, CHECK_OK); | 2052 Expect(Token::LPAREN, CHECK_OK); |
| 2006 Expression* expr = ParseExpression(true, CHECK_OK); | 2053 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2007 Expect(Token::RPAREN, CHECK_OK); | 2054 Expect(Token::RPAREN, CHECK_OK); |
| 2008 | 2055 |
| 2009 return WithHelper(expr, labels, CHECK_OK); | 2056 ++with_nesting_level_; |
| 2057 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2058 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 2059 --with_nesting_level_; |
| 2060 return new(zone()) WithStatement(expr, stmt); |
| 2010 } | 2061 } |
| 2011 | 2062 |
| 2012 | 2063 |
| 2013 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2064 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2014 // CaseClause :: | 2065 // CaseClause :: |
| 2015 // 'case' Expression ':' Statement* | 2066 // 'case' Expression ':' Statement* |
| 2016 // 'default' ':' Statement* | 2067 // 'default' ':' Statement* |
| 2017 | 2068 |
| 2018 Expression* label = NULL; // NULL expression indicates default case | 2069 Expression* label = NULL; // NULL expression indicates default case |
| 2019 if (peek() == Token::CASE) { | 2070 if (peek() == Token::CASE) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2134 | 2185 |
| 2135 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { | 2186 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2136 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2187 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2137 *ok = false; | 2188 *ok = false; |
| 2138 return NULL; | 2189 return NULL; |
| 2139 } | 2190 } |
| 2140 | 2191 |
| 2141 Expect(Token::RPAREN, CHECK_OK); | 2192 Expect(Token::RPAREN, CHECK_OK); |
| 2142 | 2193 |
| 2143 if (peek() == Token::LBRACE) { | 2194 if (peek() == Token::LBRACE) { |
| 2144 // Rewrite the catch body B to a single statement block | 2195 // Rewrite the catch body { B } to a block: |
| 2145 // { try B finally { PopContext }}. | 2196 // { { B } ExitContext; }. |
| 2146 Block* inner_body; | 2197 Target target(&this->target_stack_, &catch_collector); |
| 2147 // We need to collect escapes from the body for both the inner | 2198 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
| 2148 // try/finally used to pop the catch context and any possible outer | 2199 if (top_scope_->is_strict_mode()) { |
| 2149 // try/finally. | 2200 catch_scope->EnableStrictMode(); |
| 2150 TargetCollector inner_collector; | 2201 } |
| 2151 { Target target(&this->target_stack_, &catch_collector); | 2202 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); |
| 2152 { Target target(&this->target_stack_, &inner_collector); | 2203 catch_block = new(zone()) Block(isolate(), NULL, 2, false); |
| 2153 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | |
| 2154 if (top_scope_->is_strict_mode()) { | |
| 2155 catch_scope->EnableStrictMode(); | |
| 2156 } | |
| 2157 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); | |
| 2158 | 2204 |
| 2159 Scope* saved_scope = top_scope_; | 2205 Scope* saved_scope = top_scope_; |
| 2160 top_scope_ = catch_scope; | 2206 top_scope_ = catch_scope; |
| 2161 inner_body = ParseBlock(NULL, CHECK_OK); | 2207 Block* catch_body = ParseBlock(NULL, CHECK_OK); |
| 2162 top_scope_ = saved_scope; | 2208 top_scope_ = saved_scope; |
| 2163 } | 2209 catch_block->AddStatement(catch_body); |
| 2164 } | 2210 catch_block->AddStatement(new(zone()) ExitContextStatement()); |
| 2165 | |
| 2166 // Create exit block. | |
| 2167 Block* inner_finally = new(zone()) Block(isolate(), NULL, 1, false); | |
| 2168 inner_finally->AddStatement(new(zone()) ExitContextStatement()); | |
| 2169 | |
| 2170 // Create a try/finally statement. | |
| 2171 TryFinallyStatement* inner_try_finally = | |
| 2172 new(zone()) TryFinallyStatement(inner_body, inner_finally); | |
| 2173 inner_try_finally->set_escaping_targets(inner_collector.targets()); | |
| 2174 | |
| 2175 catch_block = new(zone()) Block(isolate(), NULL, 1, false); | |
| 2176 catch_block->AddStatement(inner_try_finally); | |
| 2177 } else { | 2211 } else { |
| 2178 Expect(Token::LBRACE, CHECK_OK); | 2212 Expect(Token::LBRACE, CHECK_OK); |
| 2179 } | 2213 } |
| 2180 | 2214 |
| 2181 tok = peek(); | 2215 tok = peek(); |
| 2182 } | 2216 } |
| 2183 | 2217 |
| 2184 Block* finally_block = NULL; | 2218 Block* finally_block = NULL; |
| 2185 if (tok == Token::FINALLY || catch_block == NULL) { | 2219 if (tok == Token::FINALLY || catch_block == NULL) { |
| 2186 Consume(Token::FINALLY); | 2220 Consume(Token::FINALLY); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2316 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2283 | 2317 |
| 2284 Statement* init = NULL; | 2318 Statement* init = NULL; |
| 2285 | 2319 |
| 2286 Expect(Token::FOR, CHECK_OK); | 2320 Expect(Token::FOR, CHECK_OK); |
| 2287 Expect(Token::LPAREN, CHECK_OK); | 2321 Expect(Token::LPAREN, CHECK_OK); |
| 2288 if (peek() != Token::SEMICOLON) { | 2322 if (peek() != Token::SEMICOLON) { |
| 2289 if (peek() == Token::VAR || peek() == Token::CONST) { | 2323 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2290 Handle<String> name; | 2324 Handle<String> name; |
| 2291 Block* variable_statement = | 2325 Block* variable_statement = |
| 2292 ParseVariableDeclarations(false, &name, CHECK_OK); | 2326 ParseVariableDeclarations(kForStatement, &name, CHECK_OK); |
| 2293 | 2327 |
| 2294 if (peek() == Token::IN && !name.is_null()) { | 2328 if (peek() == Token::IN && !name.is_null()) { |
| 2295 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); | 2329 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); |
| 2296 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); | 2330 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
| 2297 Target target(&this->target_stack_, loop); | 2331 Target target(&this->target_stack_, loop); |
| 2298 | 2332 |
| 2299 Expect(Token::IN, CHECK_OK); | 2333 Expect(Token::IN, CHECK_OK); |
| 2300 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2334 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2301 Expect(Token::RPAREN, CHECK_OK); | 2335 Expect(Token::RPAREN, CHECK_OK); |
| 2302 | 2336 |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2839 Expression* result = NULL; | 2873 Expression* result = NULL; |
| 2840 if (peek() == Token::FUNCTION) { | 2874 if (peek() == Token::FUNCTION) { |
| 2841 Expect(Token::FUNCTION, CHECK_OK); | 2875 Expect(Token::FUNCTION, CHECK_OK); |
| 2842 int function_token_position = scanner().location().beg_pos; | 2876 int function_token_position = scanner().location().beg_pos; |
| 2843 Handle<String> name; | 2877 Handle<String> name; |
| 2844 bool is_strict_reserved_name = false; | 2878 bool is_strict_reserved_name = false; |
| 2845 if (peek_any_identifier()) { | 2879 if (peek_any_identifier()) { |
| 2846 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2880 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 2847 CHECK_OK); | 2881 CHECK_OK); |
| 2848 } | 2882 } |
| 2883 FunctionLiteral::Type type = name.is_null() |
| 2884 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 2885 : FunctionLiteral::NAMED_EXPRESSION; |
| 2849 result = ParseFunctionLiteral(name, | 2886 result = ParseFunctionLiteral(name, |
| 2850 is_strict_reserved_name, | 2887 is_strict_reserved_name, |
| 2851 function_token_position, | 2888 function_token_position, |
| 2852 EXPRESSION, | 2889 type, |
| 2853 CHECK_OK); | 2890 CHECK_OK); |
| 2854 } else { | 2891 } else { |
| 2855 result = ParsePrimaryExpression(CHECK_OK); | 2892 result = ParsePrimaryExpression(CHECK_OK); |
| 2856 } | 2893 } |
| 2857 | 2894 |
| 2858 while (true) { | 2895 while (true) { |
| 2859 switch (peek()) { | 2896 switch (peek()) { |
| 2860 case Token::LBRACK: { | 2897 case Token::LBRACK: { |
| 2861 Consume(Token::LBRACK); | 2898 Consume(Token::LBRACK); |
| 2862 int pos = scanner().location().beg_pos; | 2899 int pos = scanner().location().beg_pos; |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3412 Handle<String> name; | 3449 Handle<String> name; |
| 3413 if (is_keyword) { | 3450 if (is_keyword) { |
| 3414 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); | 3451 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); |
| 3415 } else { | 3452 } else { |
| 3416 name = GetSymbol(CHECK_OK); | 3453 name = GetSymbol(CHECK_OK); |
| 3417 } | 3454 } |
| 3418 FunctionLiteral* value = | 3455 FunctionLiteral* value = |
| 3419 ParseFunctionLiteral(name, | 3456 ParseFunctionLiteral(name, |
| 3420 false, // reserved words are allowed here | 3457 false, // reserved words are allowed here |
| 3421 RelocInfo::kNoPosition, | 3458 RelocInfo::kNoPosition, |
| 3422 EXPRESSION, | 3459 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3423 CHECK_OK); | 3460 CHECK_OK); |
| 3424 // Allow any number of parameters for compatiabilty with JSC. | 3461 // Allow any number of parameters for compatiabilty with JSC. |
| 3425 // Specification only allows zero parameters for get and one for set. | 3462 // Specification only allows zero parameters for get and one for set. |
| 3426 ObjectLiteral::Property* property = | 3463 ObjectLiteral::Property* property = |
| 3427 new(zone()) ObjectLiteral::Property(is_getter, value); | 3464 new(zone()) ObjectLiteral::Property(is_getter, value); |
| 3428 return property; | 3465 return property; |
| 3429 } else { | 3466 } else { |
| 3430 ReportUnexpectedToken(next); | 3467 ReportUnexpectedToken(next); |
| 3431 *ok = false; | 3468 *ok = false; |
| 3432 return NULL; | 3469 return NULL; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3622 if (!done) Expect(Token::COMMA, CHECK_OK); | 3659 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3623 } | 3660 } |
| 3624 Expect(Token::RPAREN, CHECK_OK); | 3661 Expect(Token::RPAREN, CHECK_OK); |
| 3625 return result; | 3662 return result; |
| 3626 } | 3663 } |
| 3627 | 3664 |
| 3628 | 3665 |
| 3629 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, | 3666 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
| 3630 bool name_is_strict_reserved, | 3667 bool name_is_strict_reserved, |
| 3631 int function_token_position, | 3668 int function_token_position, |
| 3632 FunctionLiteralType type, | 3669 FunctionLiteral::Type type, |
| 3633 bool* ok) { | 3670 bool* ok) { |
| 3634 // Function :: | 3671 // Function :: |
| 3635 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3672 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3636 | 3673 |
| 3637 // Anonymous functions were passed either the empty symbol or a null | 3674 // Anonymous functions were passed either the empty symbol or a null |
| 3638 // handle as the function name. Remember if we were passed a non-empty | 3675 // handle as the function name. Remember if we were passed a non-empty |
| 3639 // handle to decide whether to invoke function name inference. | 3676 // handle to decide whether to invoke function name inference. |
| 3640 bool should_infer_name = function_name.is_null(); | 3677 bool should_infer_name = function_name.is_null(); |
| 3641 | 3678 |
| 3642 // We want a non-null handle as the function name. | 3679 // We want a non-null handle as the function name. |
| 3643 if (should_infer_name) { | 3680 if (should_infer_name) { |
| 3644 function_name = isolate()->factory()->empty_symbol(); | 3681 function_name = isolate()->factory()->empty_symbol(); |
| 3645 } | 3682 } |
| 3646 | 3683 |
| 3647 int num_parameters = 0; | 3684 int num_parameters = 0; |
| 3648 // Function declarations are hoisted. | 3685 // Function declarations are function scoped in normal mode, so they are |
| 3649 Scope* scope = (type == DECLARATION) | 3686 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3687 // are not hoisted. |
| 3688 Scope* scope = (type == FunctionLiteral::DECLARATION && |
| 3689 !harmony_block_scoping_) |
| 3650 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) | 3690 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) |
| 3651 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3691 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3692 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
| 3653 int materialized_literal_count; | 3693 int materialized_literal_count; |
| 3654 int expected_property_count; | 3694 int expected_property_count; |
| 3655 int start_pos; | 3695 int start_pos; |
| 3656 int end_pos; | 3696 int end_pos; |
| 3657 bool only_simple_this_property_assignments; | 3697 bool only_simple_this_property_assignments; |
| 3658 Handle<FixedArray> this_property_assignments; | 3698 Handle<FixedArray> this_property_assignments; |
| 3659 bool has_duplicate_parameters = false; | 3699 bool has_duplicate_parameters = false; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3702 Expect(Token::RPAREN, CHECK_OK); | 3742 Expect(Token::RPAREN, CHECK_OK); |
| 3703 | 3743 |
| 3704 Expect(Token::LBRACE, CHECK_OK); | 3744 Expect(Token::LBRACE, CHECK_OK); |
| 3705 | 3745 |
| 3706 // If we have a named function expression, we add a local variable | 3746 // If we have a named function expression, we add a local variable |
| 3707 // declaration to the body of the function with the name of the | 3747 // declaration to the body of the function with the name of the |
| 3708 // function and let it refer to the function itself (closure). | 3748 // function and let it refer to the function itself (closure). |
| 3709 // NOTE: We create a proxy and resolve it here so that in the | 3749 // NOTE: We create a proxy and resolve it here so that in the |
| 3710 // future we can change the AST to only refer to VariableProxies | 3750 // future we can change the AST to only refer to VariableProxies |
| 3711 // instead of Variables and Proxis as is the case now. | 3751 // instead of Variables and Proxis as is the case now. |
| 3712 if (type == EXPRESSION && function_name->length() > 0) { | 3752 if (type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3713 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); | 3753 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); |
| 3714 VariableProxy* fproxy = | 3754 VariableProxy* fproxy = |
| 3715 top_scope_->NewUnresolved(function_name, inside_with()); | 3755 top_scope_->NewUnresolved(function_name, inside_with()); |
| 3716 fproxy->BindTo(fvar); | 3756 fproxy->BindTo(fvar); |
| 3717 body->Add(new(zone()) ExpressionStatement( | 3757 body->Add(new(zone()) ExpressionStatement( |
| 3718 new(zone()) Assignment(isolate(), | 3758 new(zone()) Assignment(isolate(), |
| 3719 Token::INIT_CONST, | 3759 Token::INIT_CONST, |
| 3720 fproxy, | 3760 fproxy, |
| 3721 new(zone()) ThisFunction(isolate()), | 3761 new(zone()) ThisFunction(isolate()), |
| 3722 RelocInfo::kNoPosition))); | 3762 RelocInfo::kNoPosition))); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3820 function_name, | 3860 function_name, |
| 3821 scope, | 3861 scope, |
| 3822 body, | 3862 body, |
| 3823 materialized_literal_count, | 3863 materialized_literal_count, |
| 3824 expected_property_count, | 3864 expected_property_count, |
| 3825 only_simple_this_property_assignments, | 3865 only_simple_this_property_assignments, |
| 3826 this_property_assignments, | 3866 this_property_assignments, |
| 3827 num_parameters, | 3867 num_parameters, |
| 3828 start_pos, | 3868 start_pos, |
| 3829 end_pos, | 3869 end_pos, |
| 3830 type == EXPRESSION, | 3870 type, |
| 3831 has_duplicate_parameters); | 3871 has_duplicate_parameters); |
| 3832 function_literal->set_function_token_position(function_token_position); | 3872 function_literal->set_function_token_position(function_token_position); |
| 3833 | 3873 |
| 3834 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3874 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3835 return function_literal; | 3875 return function_literal; |
| 3836 } | 3876 } |
| 3837 | 3877 |
| 3838 | 3878 |
| 3839 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3879 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3840 // CallRuntime :: | 3880 // CallRuntime :: |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3941 Literal* Parser::GetLiteralTheHole() { | 3981 Literal* Parser::GetLiteralTheHole() { |
| 3942 return NewLiteral(isolate()->factory()->the_hole_value()); | 3982 return NewLiteral(isolate()->factory()->the_hole_value()); |
| 3943 } | 3983 } |
| 3944 | 3984 |
| 3945 | 3985 |
| 3946 Literal* Parser::GetLiteralNumber(double value) { | 3986 Literal* Parser::GetLiteralNumber(double value) { |
| 3947 return NewNumberLiteral(value); | 3987 return NewNumberLiteral(value); |
| 3948 } | 3988 } |
| 3949 | 3989 |
| 3950 | 3990 |
| 3951 // Parses and identifier that is valid for the current scope, in particular it | 3991 // Parses an identifier that is valid for the current scope, in particular it |
| 3952 // fails on strict mode future reserved keywords in a strict scope. | 3992 // fails on strict mode future reserved keywords in a strict scope. |
| 3953 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3993 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3954 if (top_scope_->is_strict_mode()) { | 3994 if (top_scope_->is_strict_mode()) { |
| 3955 Expect(Token::IDENTIFIER, ok); | 3995 Expect(Token::IDENTIFIER, ok); |
| 3956 } else if (!Check(Token::IDENTIFIER)) { | 3996 } else if (!Check(Token::IDENTIFIER)) { |
| 3957 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); | 3997 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); |
| 3958 } | 3998 } |
| 3959 if (!*ok) return Handle<String>(); | 3999 if (!*ok) return Handle<String>(); |
| 3960 return GetSymbol(ok); | 4000 return GetSymbol(ok); |
| 3961 } | 4001 } |
| (...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5022 data++; | 5062 data++; |
| 5023 } | 5063 } |
| 5024 *source = data; | 5064 *source = data; |
| 5025 return result; | 5065 return result; |
| 5026 } | 5066 } |
| 5027 | 5067 |
| 5028 | 5068 |
| 5029 // Create a Scanner for the preparser to use as input, and preparse the source. | 5069 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5030 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, | 5070 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
| 5031 bool allow_lazy, | 5071 bool allow_lazy, |
| 5032 ParserRecorder* recorder) { | 5072 ParserRecorder* recorder, |
| 5073 bool harmony_block_scoping) { |
| 5033 Isolate* isolate = Isolate::Current(); | 5074 Isolate* isolate = Isolate::Current(); |
| 5034 JavaScriptScanner scanner(isolate->unicode_cache()); | 5075 JavaScriptScanner scanner(isolate->unicode_cache()); |
| 5076 scanner.SetHarmonyBlockScoping(harmony_block_scoping); |
| 5035 scanner.Initialize(source); | 5077 scanner.Initialize(source); |
| 5036 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5078 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5037 if (!preparser::PreParser::PreParseProgram(&scanner, | 5079 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 5038 recorder, | 5080 recorder, |
| 5039 allow_lazy, | 5081 allow_lazy, |
| 5040 stack_limit)) { | 5082 stack_limit)) { |
| 5041 isolate->StackOverflow(); | 5083 isolate->StackOverflow(); |
| 5042 return NULL; | 5084 return NULL; |
| 5043 } | 5085 } |
| 5044 | 5086 |
| 5045 // Extract the accumulated data from the recorder as a single | 5087 // Extract the accumulated data from the recorder as a single |
| 5046 // contiguous vector that we are responsible for disposing. | 5088 // contiguous vector that we are responsible for disposing. |
| 5047 Vector<unsigned> store = recorder->ExtractData(); | 5089 Vector<unsigned> store = recorder->ExtractData(); |
| 5048 return new ScriptDataImpl(store); | 5090 return new ScriptDataImpl(store); |
| 5049 } | 5091 } |
| 5050 | 5092 |
| 5051 | 5093 |
| 5052 // Preparse, but only collect data that is immediately useful, | 5094 // Preparse, but only collect data that is immediately useful, |
| 5053 // even if the preparser data is only used once. | 5095 // even if the preparser data is only used once. |
| 5054 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, | 5096 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
| 5055 v8::Extension* extension) { | 5097 v8::Extension* extension, |
| 5098 bool harmony_block_scoping) { |
| 5056 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5099 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 5057 if (!allow_lazy) { | 5100 if (!allow_lazy) { |
| 5058 // Partial preparsing is only about lazily compiled functions. | 5101 // Partial preparsing is only about lazily compiled functions. |
| 5059 // If we don't allow lazy compilation, the log data will be empty. | 5102 // If we don't allow lazy compilation, the log data will be empty. |
| 5060 return NULL; | 5103 return NULL; |
| 5061 } | 5104 } |
| 5062 PartialParserRecorder recorder; | 5105 PartialParserRecorder recorder; |
| 5063 return DoPreParse(source, allow_lazy, &recorder); | 5106 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping); |
| 5064 } | 5107 } |
| 5065 | 5108 |
| 5066 | 5109 |
| 5067 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, | 5110 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
| 5068 v8::Extension* extension) { | 5111 v8::Extension* extension, |
| 5112 bool harmony_block_scoping) { |
| 5069 Handle<Script> no_script; | 5113 Handle<Script> no_script; |
| 5070 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5114 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 5071 CompleteParserRecorder recorder; | 5115 CompleteParserRecorder recorder; |
| 5072 return DoPreParse(source, allow_lazy, &recorder); | 5116 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping); |
| 5073 } | 5117 } |
| 5074 | 5118 |
| 5075 | 5119 |
| 5076 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5120 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5077 bool multiline, | 5121 bool multiline, |
| 5078 RegExpCompileData* result) { | 5122 RegExpCompileData* result) { |
| 5079 ASSERT(result != NULL); | 5123 ASSERT(result != NULL); |
| 5080 RegExpParser parser(input, &result->error, multiline); | 5124 RegExpParser parser(input, &result->error, multiline); |
| 5081 RegExpTree* tree = parser.ParsePattern(); | 5125 RegExpTree* tree = parser.ParsePattern(); |
| 5082 if (parser.failed()) { | 5126 if (parser.failed()) { |
| 5083 ASSERT(tree == NULL); | 5127 ASSERT(tree == NULL); |
| 5084 ASSERT(!result->error.is_null()); | 5128 ASSERT(!result->error.is_null()); |
| 5085 } else { | 5129 } else { |
| 5086 ASSERT(tree != NULL); | 5130 ASSERT(tree != NULL); |
| 5087 ASSERT(result->error.is_null()); | 5131 ASSERT(result->error.is_null()); |
| 5088 result->tree = tree; | 5132 result->tree = tree; |
| 5089 int capture_count = parser.captures_started(); | 5133 int capture_count = parser.captures_started(); |
| 5090 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5134 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 5091 result->contains_anchor = parser.contains_anchor(); | 5135 result->contains_anchor = parser.contains_anchor(); |
| 5092 result->capture_count = capture_count; | 5136 result->capture_count = capture_count; |
| 5093 } | 5137 } |
| 5094 return !parser.failed(); | 5138 return !parser.failed(); |
| 5095 } | 5139 } |
| 5096 | 5140 |
| 5097 | 5141 |
| 5098 bool ParserApi::Parse(CompilationInfo* info) { | 5142 bool ParserApi::Parse(CompilationInfo* info) { |
| 5099 ASSERT(info->function() == NULL); | 5143 ASSERT(info->function() == NULL); |
| 5100 FunctionLiteral* result = NULL; | 5144 FunctionLiteral* result = NULL; |
| 5101 Handle<Script> script = info->script(); | 5145 Handle<Script> script = info->script(); |
| 5146 bool harmony_block_scoping = !info->is_native() && |
| 5147 FLAG_harmony_block_scoping; |
| 5102 if (info->is_lazy()) { | 5148 if (info->is_lazy()) { |
| 5103 Parser parser(script, true, NULL, NULL); | 5149 Parser parser(script, true, NULL, NULL); |
| 5150 parser.SetHarmonyBlockScoping(harmony_block_scoping); |
| 5104 result = parser.ParseLazy(info); | 5151 result = parser.ParseLazy(info); |
| 5105 } else { | 5152 } else { |
| 5106 // Whether we allow %identifier(..) syntax. | 5153 // Whether we allow %identifier(..) syntax. |
| 5107 bool allow_natives_syntax = | 5154 bool allow_natives_syntax = |
| 5108 info->allows_natives_syntax() || FLAG_allow_natives_syntax; | 5155 info->allows_natives_syntax() || FLAG_allow_natives_syntax; |
| 5109 ScriptDataImpl* pre_data = info->pre_parse_data(); | 5156 ScriptDataImpl* pre_data = info->pre_parse_data(); |
| 5110 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); | 5157 Parser parser(script, |
| 5158 allow_natives_syntax, |
| 5159 info->extension(), |
| 5160 pre_data); |
| 5161 parser.SetHarmonyBlockScoping(harmony_block_scoping); |
| 5111 if (pre_data != NULL && pre_data->has_error()) { | 5162 if (pre_data != NULL && pre_data->has_error()) { |
| 5112 Scanner::Location loc = pre_data->MessageLocation(); | 5163 Scanner::Location loc = pre_data->MessageLocation(); |
| 5113 const char* message = pre_data->BuildMessage(); | 5164 const char* message = pre_data->BuildMessage(); |
| 5114 Vector<const char*> args = pre_data->BuildArgs(); | 5165 Vector<const char*> args = pre_data->BuildArgs(); |
| 5115 parser.ReportMessageAt(loc, message, args); | 5166 parser.ReportMessageAt(loc, message, args); |
| 5116 DeleteArray(message); | 5167 DeleteArray(message); |
| 5117 for (int i = 0; i < args.length(); i++) { | 5168 for (int i = 0; i < args.length(); i++) { |
| 5118 DeleteArray(args[i]); | 5169 DeleteArray(args[i]); |
| 5119 } | 5170 } |
| 5120 DeleteArray(args.start()); | 5171 DeleteArray(args.start()); |
| 5121 ASSERT(info->isolate()->has_pending_exception()); | 5172 ASSERT(info->isolate()->has_pending_exception()); |
| 5122 } else { | 5173 } else { |
| 5123 Handle<String> source = Handle<String>(String::cast(script->source())); | 5174 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5124 result = parser.ParseProgram(source, | 5175 result = parser.ParseProgram(source, |
| 5125 info->is_global(), | 5176 info->is_global(), |
| 5126 info->StrictMode()); | 5177 info->StrictMode()); |
| 5127 } | 5178 } |
| 5128 } | 5179 } |
| 5129 | |
| 5130 info->SetFunction(result); | 5180 info->SetFunction(result); |
| 5131 return (result != NULL); | 5181 return (result != NULL); |
| 5132 } | 5182 } |
| 5133 | 5183 |
| 5134 } } // namespace v8::internal | 5184 } } // namespace v8::internal |
| OLD | NEW |