OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 | 647 |
648 // Make sure the target stack is empty. | 648 // Make sure the target stack is empty. |
649 ASSERT(target_stack_ == NULL); | 649 ASSERT(target_stack_ == NULL); |
650 | 650 |
651 // If there was a syntax error we have to get rid of the AST | 651 // If there was a syntax error we have to get rid of the AST |
652 // and it is not safe to do so before the scope has been deleted. | 652 // and it is not safe to do so before the scope has been deleted. |
653 if (result == NULL) zone_scope->DeleteOnExit(); | 653 if (result == NULL) zone_scope->DeleteOnExit(); |
654 return result; | 654 return result; |
655 } | 655 } |
656 | 656 |
657 | |
657 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { | 658 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { |
658 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); | 659 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); |
659 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); | 660 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); |
660 Handle<String> source(String::cast(script_->source())); | 661 Handle<String> source(String::cast(script_->source())); |
661 isolate()->counters()->total_parse_size()->Increment(source->length()); | 662 isolate()->counters()->total_parse_size()->Increment(source->length()); |
662 | 663 |
663 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 664 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
664 // Initialize parser state. | 665 // Initialize parser state. |
665 source->TryFlatten(); | 666 source->TryFlatten(); |
666 if (source->IsExternalTwoByteString()) { | 667 if (source->IsExternalTwoByteString()) { |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1080 } | 1081 } |
1081 | 1082 |
1082 Isolate* isolate_; | 1083 Isolate* isolate_; |
1083 bool only_simple_this_property_assignments_; | 1084 bool only_simple_this_property_assignments_; |
1084 ZoneStringList names_; | 1085 ZoneStringList names_; |
1085 ZoneList<int> assigned_arguments_; | 1086 ZoneList<int> assigned_arguments_; |
1086 ZoneObjectList assigned_constants_; | 1087 ZoneObjectList assigned_constants_; |
1087 }; | 1088 }; |
1088 | 1089 |
1089 | 1090 |
1090 Statement* Parser::ParseSourceElement(ZoneStringList* labels, | |
1091 bool* ok) { | |
1092 // (Ecma 262 5th Edition, clause 14): | |
1093 // SourceElement: | |
1094 // Statement | |
1095 // FunctionDeclaration | |
1096 // | |
1097 // In harmony mode we allow additionally the following productions | |
1098 // SourceElement: | |
1099 // LetDeclaration | |
1100 // ConstDeclaration | |
1101 | |
1102 if (peek() == Token::FUNCTION) { | |
1103 return ParseFunctionDeclaration(ok); | |
1104 } else if (peek() == Token::LET || peek() == Token::CONST) { | |
1105 return ParseVariableStatement(kSourceElement, ok); | |
1106 } | |
1107 return ParseStatement(labels, ok); | |
1108 } | |
1109 | |
1110 | |
1111 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1091 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
1112 int end_token, | 1092 int end_token, |
1113 bool* ok) { | 1093 bool* ok) { |
1114 // SourceElements :: | 1094 // SourceElements :: |
1115 // (SourceElement)* <end_token> | 1095 // (ModuleElement)* <end_token> |
1116 | 1096 |
1117 // Allocate a target stack to use for this set of source | 1097 // Allocate a target stack to use for this set of source |
1118 // elements. This way, all scripts and functions get their own | 1098 // elements. This way, all scripts and functions get their own |
1119 // target stack thus avoiding illegal breaks and continues across | 1099 // target stack thus avoiding illegal breaks and continues across |
1120 // functions. | 1100 // functions. |
1121 TargetScope scope(&this->target_stack_); | 1101 TargetScope scope(&this->target_stack_); |
1122 | 1102 |
1123 ASSERT(processor != NULL); | 1103 ASSERT(processor != NULL); |
1124 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1104 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
1125 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate()); | 1105 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate()); |
1126 bool directive_prologue = true; // Parsing directive prologue. | 1106 bool directive_prologue = true; // Parsing directive prologue. |
1127 | 1107 |
1128 while (peek() != end_token) { | 1108 while (peek() != end_token) { |
1129 if (directive_prologue && peek() != Token::STRING) { | 1109 if (directive_prologue && peek() != Token::STRING) { |
1130 directive_prologue = false; | 1110 directive_prologue = false; |
1131 } | 1111 } |
1132 | 1112 |
1133 Scanner::Location token_loc = scanner().peek_location(); | 1113 Scanner::Location token_loc = scanner().peek_location(); |
1134 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1114 Statement* stat = ParseModuleElement(NULL, CHECK_OK); |
1135 if (stat == NULL || stat->IsEmpty()) { | 1115 if (stat == NULL || stat->IsEmpty()) { |
1136 directive_prologue = false; // End of directive prologue. | 1116 directive_prologue = false; // End of directive prologue. |
1137 continue; | 1117 continue; |
1138 } | 1118 } |
1139 | 1119 |
1140 if (directive_prologue) { | 1120 if (directive_prologue) { |
1141 // A shot at a directive. | 1121 // A shot at a directive. |
1142 ExpressionStatement* e_stat; | 1122 ExpressionStatement* e_stat; |
1143 Literal* literal; | 1123 Literal* literal; |
1144 // Still processing directive prologue? | 1124 // Still processing directive prologue? |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1180 if (only_simple_this_property_assignments) { | 1160 if (only_simple_this_property_assignments) { |
1181 current_function_state_->SetThisPropertyAssignmentInfo( | 1161 current_function_state_->SetThisPropertyAssignmentInfo( |
1182 only_simple_this_property_assignments, | 1162 only_simple_this_property_assignments, |
1183 this_property_assignment_finder.GetThisPropertyAssignments()); | 1163 this_property_assignment_finder.GetThisPropertyAssignments()); |
1184 } | 1164 } |
1185 } | 1165 } |
1186 return 0; | 1166 return 0; |
1187 } | 1167 } |
1188 | 1168 |
1189 | 1169 |
1170 Statement* Parser::ParseModuleElement(ZoneStringList* labels, | |
1171 bool* ok) { | |
1172 // (Ecma 262 5th Edition, clause 14): | |
1173 // SourceElement: | |
1174 // Statement | |
1175 // FunctionDeclaration | |
1176 // | |
1177 // In harmony mode we allow additionally the following productions | |
1178 // ModuleElement: | |
1179 // LetDeclaration | |
1180 // ConstDeclaration | |
1181 // ModuleDeclaration | |
1182 // ImportDeclaration | |
1183 // ExportDeclaration | |
1184 | |
1185 switch (peek()) { | |
1186 case Token::FUNCTION: | |
1187 return ParseFunctionDeclaration(ok); | |
1188 case Token::LET: | |
1189 case Token::CONST: | |
1190 return ParseVariableStatement(kModuleElement, ok); | |
1191 case Token::MODULE: | |
1192 return ParseModuleDeclaration(ok); | |
1193 case Token::IMPORT: | |
1194 return ParseImportDeclaration(ok); | |
1195 case Token::EXPORT: | |
1196 return ParseExportDeclaration(ok); | |
1197 default: | |
1198 return ParseStatement(labels, ok); | |
1199 } | |
1200 } | |
1201 | |
1202 | |
1203 Block* Parser::ParseModuleDeclaration(bool* ok) { | |
1204 // ModuleDeclaration: | |
1205 // 'module' Identifier Module | |
1206 | |
1207 // Create new block with one expected declaration. | |
1208 Block* block = factory()->NewBlock(NULL, 1, true); | |
1209 Expect(Token::MODULE, CHECK_OK); | |
1210 Handle<String> name = ParseIdentifier(CHECK_OK); | |
1211 // top_scope_->AddDeclaration( | |
1212 // factory()->NewModuleDeclaration(proxy, module, top_scope_)); | |
1213 VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK); | |
1214 Module* module = ParseModule(ok); | |
1215 // TODO(rossberg): Add initialization statement to block. | |
1216 USE(proxy); | |
1217 USE(module); | |
1218 return block; | |
1219 } | |
1220 | |
1221 | |
1222 Module* Parser::ParseModule(bool* ok) { | |
1223 // Module: | |
1224 // '{' ModuleElement '}' | |
1225 // '=' ModulePath | |
1226 // 'at' String | |
1227 | |
1228 switch (peek()) { | |
1229 case Token::LBRACE: | |
1230 return ParseModuleLiteral(ok); | |
1231 | |
1232 case Token::ASSIGN: | |
1233 Expect(Token::ASSIGN, CHECK_OK); | |
1234 return ParseModulePath(ok); | |
1235 | |
1236 default: | |
1237 return ParseModuleUrl(ok); | |
1238 } | |
1239 } | |
1240 | |
1241 | |
1242 Module* Parser::ParseModuleLiteral(bool* ok) { | |
1243 // Module: | |
1244 // '{' ModuleElement '}' | |
1245 | |
1246 // Construct block expecting 16 statements. | |
1247 Block* body = factory()->NewBlock(NULL, 16, false); | |
1248 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | |
1249 | |
1250 Expect(Token::LBRACE, CHECK_OK); | |
1251 scope->set_start_position(scanner().location().beg_pos); | |
1252 scope->SetLanguageMode(EXTENDED_MODE); | |
1253 | |
1254 { | |
1255 BlockState block_state(this, scope); | |
1256 TargetCollector collector; | |
1257 Target target(&this->target_stack_, &collector); | |
1258 Target target_body(&this->target_stack_, body); | |
1259 InitializationBlockFinder block_finder(top_scope_, target_stack_); | |
1260 | |
1261 while (peek() != Token::RBRACE) { | |
1262 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | |
1263 if (stat && !stat->IsEmpty()) { | |
1264 body->AddStatement(stat); | |
1265 block_finder.Update(stat); | |
1266 } | |
1267 } | |
1268 } | |
1269 | |
1270 Expect(Token::RBRACE, CHECK_OK); | |
1271 scope->set_end_position(scanner().location().end_pos); | |
1272 body->set_block_scope(scope); | |
1273 return factory()->NewModuleLiteral(body); | |
1274 } | |
1275 | |
1276 | |
1277 Module* Parser::ParseModulePath(bool* ok) { | |
1278 // ModulePath: | |
1279 // Identifier | |
1280 // ModulePath '.' Identifier | |
1281 | |
1282 Module* result = ParseModuleVariable(CHECK_OK); | |
1283 | |
1284 while (Check(Token::PERIOD)) { | |
1285 Handle<String> name = ParseIdentifierName(CHECK_OK); | |
1286 result = factory()->NewModulePath(result, name); | |
1287 } | |
1288 | |
1289 return result; | |
1290 } | |
1291 | |
1292 | |
1293 Module* Parser::ParseModuleVariable(bool* ok) { | |
1294 // ModulePath: | |
1295 // Identifier | |
1296 | |
1297 Handle<String> name = ParseIdentifier(CHECK_OK); | |
1298 VariableProxy* proxy = top_scope_->NewUnresolved( | |
1299 factory(), name, scanner().location().beg_pos); | |
1300 return factory()->NewModuleVariable(proxy); | |
1301 } | |
1302 | |
1303 | |
1304 Module* Parser::ParseModuleUrl(bool* ok) { | |
1305 // Module: | |
1306 // 'at' String | |
1307 | |
1308 Expect(Token::IDENTIFIER, CHECK_OK); | |
1309 Handle<String> symbol = GetSymbol(CHECK_OK); | |
1310 if (!symbol->IsEqualTo(CStrVector("at"))) { | |
1311 *ok = false; | |
1312 ReportUnexpectedToken(scanner().current_token()); | |
1313 return NULL; | |
1314 } | |
1315 Expect(Token::STRING, CHECK_OK); | |
1316 symbol = GetSymbol(CHECK_OK); | |
Lasse Reichstein Nielsen
2012/02/21 13:46:02
Great! :)
| |
1317 | |
1318 return factory()->NewModuleUrl(symbol); | |
1319 } | |
1320 | |
1321 | |
1322 Block* Parser::ParseImportDeclaration(bool* ok) { | |
1323 // TODO(rossberg) | |
1324 return NULL; | |
1325 } | |
1326 | |
1327 | |
1328 Block* Parser::ParseExportDeclaration(bool* ok) { | |
1329 // TODO(rossberg) | |
1330 return NULL; | |
1331 } | |
1332 | |
1333 | |
1334 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | |
1335 bool* ok) { | |
1336 // (Ecma 262 5th Edition, clause 14): | |
1337 // SourceElement: | |
1338 // Statement | |
1339 // FunctionDeclaration | |
1340 // | |
1341 // In harmony mode we allow additionally the following productions | |
1342 // BlockElement (aka SourceElement): | |
1343 // LetDeclaration | |
1344 // ConstDeclaration | |
1345 | |
1346 switch (peek()) { | |
1347 case Token::FUNCTION: | |
1348 return ParseFunctionDeclaration(ok); | |
1349 case Token::LET: | |
1350 case Token::CONST: | |
1351 return ParseVariableStatement(kModuleElement, ok); | |
1352 default: | |
1353 return ParseStatement(labels, ok); | |
1354 } | |
1355 } | |
1356 | |
1357 | |
1190 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1358 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
1191 // Statement :: | 1359 // Statement :: |
1192 // Block | 1360 // Block |
1193 // VariableStatement | 1361 // VariableStatement |
1194 // EmptyStatement | 1362 // EmptyStatement |
1195 // ExpressionStatement | 1363 // ExpressionStatement |
1196 // IfStatement | 1364 // IfStatement |
1197 // IterationStatement | 1365 // IterationStatement |
1198 // ContinueStatement | 1366 // ContinueStatement |
1199 // BreakStatement | 1367 // BreakStatement |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1337 // will be added to the scope so that the declaration can be added | 1505 // will be added to the scope so that the declaration can be added |
1338 // to the corresponding activation frame at runtime if necessary. | 1506 // to the corresponding activation frame at runtime if necessary. |
1339 // For instance declarations inside an eval scope need to be added | 1507 // For instance declarations inside an eval scope need to be added |
1340 // to the calling function context. | 1508 // to the calling function context. |
1341 // Similarly, strict mode eval scope does not leak variable declarations to | 1509 // Similarly, strict mode eval scope does not leak variable declarations to |
1342 // the caller's scope so we declare all locals, too. | 1510 // the caller's scope so we declare all locals, too. |
1343 // Also for block scoped let/const bindings the variable can be | 1511 // Also for block scoped let/const bindings the variable can be |
1344 // statically declared. | 1512 // statically declared. |
1345 if (declaration_scope->is_function_scope() || | 1513 if (declaration_scope->is_function_scope() || |
1346 declaration_scope->is_strict_or_extended_eval_scope() || | 1514 declaration_scope->is_strict_or_extended_eval_scope() || |
1347 declaration_scope->is_block_scope()) { | 1515 declaration_scope->is_block_scope() || |
1516 declaration_scope->is_module_scope()) { | |
1348 // Declare the variable in the function scope. | 1517 // Declare the variable in the function scope. |
1349 var = declaration_scope->LocalLookup(name); | 1518 var = declaration_scope->LocalLookup(name); |
1350 if (var == NULL) { | 1519 if (var == NULL) { |
1351 // Declare the name. | 1520 // Declare the name. |
1352 var = declaration_scope->DeclareLocal(name, mode, init_flag); | 1521 var = declaration_scope->DeclareLocal(name, mode, init_flag); |
1353 } else { | 1522 } else { |
1354 // The name was declared in this scope before; check for conflicting | 1523 // The name was declared in this scope before; check for conflicting |
1355 // re-declarations. We have a conflict if either of the declarations is | 1524 // re-declarations. We have a conflict if either of the declarations is |
1356 // not a var. There is similar code in runtime.cc in the Declare | 1525 // not a var. There is similar code in runtime.cc in the Declare |
1357 // functions. The function CheckNonConflictingScope checks for conflicting | 1526 // functions. The function CheckNonConflictingScope checks for conflicting |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1567 result->AddStatement(stat); | 1736 result->AddStatement(stat); |
1568 block_finder.Update(stat); | 1737 block_finder.Update(stat); |
1569 } | 1738 } |
1570 } | 1739 } |
1571 Expect(Token::RBRACE, CHECK_OK); | 1740 Expect(Token::RBRACE, CHECK_OK); |
1572 return result; | 1741 return result; |
1573 } | 1742 } |
1574 | 1743 |
1575 | 1744 |
1576 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1745 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
1577 // The harmony mode uses source elements instead of statements. | 1746 // The harmony mode uses block elements instead of statements. |
1578 // | 1747 // |
1579 // Block :: | 1748 // Block :: |
1580 // '{' SourceElement* '}' | 1749 // '{' BlockElement* '}' |
1581 | 1750 |
1582 // Construct block expecting 16 statements. | 1751 // Construct block expecting 16 statements. |
1583 Block* body = factory()->NewBlock(labels, 16, false); | 1752 Block* body = factory()->NewBlock(labels, 16, false); |
1584 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1753 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
1585 | 1754 |
1586 // Parse the statements and collect escaping labels. | 1755 // Parse the statements and collect escaping labels. |
1587 Expect(Token::LBRACE, CHECK_OK); | 1756 Expect(Token::LBRACE, CHECK_OK); |
1588 block_scope->set_start_position(scanner().location().beg_pos); | 1757 block_scope->set_start_position(scanner().location().beg_pos); |
1589 { BlockState block_state(this, block_scope); | 1758 { BlockState block_state(this, block_scope); |
1590 TargetCollector collector; | 1759 TargetCollector collector; |
1591 Target target(&this->target_stack_, &collector); | 1760 Target target(&this->target_stack_, &collector); |
1592 Target target_body(&this->target_stack_, body); | 1761 Target target_body(&this->target_stack_, body); |
1593 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1762 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
1594 | 1763 |
1595 while (peek() != Token::RBRACE) { | 1764 while (peek() != Token::RBRACE) { |
1596 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1765 Statement* stat = ParseBlockElement(NULL, CHECK_OK); |
1597 if (stat && !stat->IsEmpty()) { | 1766 if (stat && !stat->IsEmpty()) { |
1598 body->AddStatement(stat); | 1767 body->AddStatement(stat); |
1599 block_finder.Update(stat); | 1768 block_finder.Update(stat); |
1600 } | 1769 } |
1601 } | 1770 } |
1602 } | 1771 } |
1603 Expect(Token::RBRACE, CHECK_OK); | 1772 Expect(Token::RBRACE, CHECK_OK); |
1604 block_scope->set_end_position(scanner().location().end_pos); | 1773 block_scope->set_end_position(scanner().location().end_pos); |
1605 block_scope = block_scope->FinalizeBlockScope(); | 1774 block_scope = block_scope->FinalizeBlockScope(); |
1606 body->set_block_scope(block_scope); | 1775 body->set_block_scope(block_scope); |
1607 return body; | 1776 return body; |
1608 } | 1777 } |
1609 | 1778 |
1610 | 1779 |
1611 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1780 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
1612 bool* ok) { | 1781 bool* ok) { |
1613 // VariableStatement :: | 1782 // VariableStatement :: |
1614 // VariableDeclarations ';' | 1783 // VariableDeclarations ';' |
1615 | 1784 |
1616 Handle<String> ignore; | 1785 Handle<String> ignore; |
1617 Block* result = ParseVariableDeclarations(var_context, | 1786 Block* result = |
1618 NULL, | 1787 ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK); |
1619 &ignore, | |
1620 CHECK_OK); | |
1621 ExpectSemicolon(CHECK_OK); | 1788 ExpectSemicolon(CHECK_OK); |
1622 return result; | 1789 return result; |
1623 } | 1790 } |
1624 | 1791 |
1625 | 1792 |
1626 bool Parser::IsEvalOrArguments(Handle<String> string) { | 1793 bool Parser::IsEvalOrArguments(Handle<String> string) { |
1627 return string.is_identical_to(isolate()->factory()->eval_symbol()) || | 1794 return string.is_identical_to(isolate()->factory()->eval_symbol()) || |
1628 string.is_identical_to(isolate()->factory()->arguments_symbol()); | 1795 string.is_identical_to(isolate()->factory()->arguments_symbol()); |
1629 } | 1796 } |
1630 | 1797 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1677 switch (top_scope_->language_mode()) { | 1844 switch (top_scope_->language_mode()) { |
1678 case CLASSIC_MODE: | 1845 case CLASSIC_MODE: |
1679 mode = CONST; | 1846 mode = CONST; |
1680 init_op = Token::INIT_CONST; | 1847 init_op = Token::INIT_CONST; |
1681 break; | 1848 break; |
1682 case STRICT_MODE: | 1849 case STRICT_MODE: |
1683 ReportMessage("strict_const", Vector<const char*>::empty()); | 1850 ReportMessage("strict_const", Vector<const char*>::empty()); |
1684 *ok = false; | 1851 *ok = false; |
1685 return NULL; | 1852 return NULL; |
1686 case EXTENDED_MODE: | 1853 case EXTENDED_MODE: |
1687 if (var_context != kSourceElement && | 1854 if (var_context == kStatement) { |
1688 var_context != kForStatement) { | |
1689 // In extended mode 'const' declarations are only allowed in source | 1855 // In extended mode 'const' declarations are only allowed in source |
1690 // element positions. | 1856 // element positions. |
1691 ReportMessage("unprotected_const", Vector<const char*>::empty()); | 1857 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
1692 *ok = false; | 1858 *ok = false; |
1693 return NULL; | 1859 return NULL; |
1694 } | 1860 } |
1695 mode = CONST_HARMONY; | 1861 mode = CONST_HARMONY; |
1696 init_op = Token::INIT_CONST_HARMONY; | 1862 init_op = Token::INIT_CONST_HARMONY; |
1697 } | 1863 } |
1698 is_const = true; | 1864 is_const = true; |
1699 needs_init = true; | 1865 needs_init = true; |
1700 } else if (peek() == Token::LET) { | 1866 } else if (peek() == Token::LET) { |
1701 // ES6 Draft Rev4 section 12.2.1: | 1867 // ES6 Draft Rev4 section 12.2.1: |
1702 // | 1868 // |
1703 // LetDeclaration : let LetBindingList ; | 1869 // LetDeclaration : let LetBindingList ; |
1704 // | 1870 // |
1705 // * It is a Syntax Error if the code that matches this production is not | 1871 // * It is a Syntax Error if the code that matches this production is not |
1706 // contained in extended code. | 1872 // contained in extended code. |
1707 if (!is_extended_mode()) { | 1873 if (!is_extended_mode()) { |
1708 ReportMessage("illegal_let", Vector<const char*>::empty()); | 1874 ReportMessage("illegal_let", Vector<const char*>::empty()); |
1709 *ok = false; | 1875 *ok = false; |
1710 return NULL; | 1876 return NULL; |
1711 } | 1877 } |
1712 Consume(Token::LET); | 1878 Consume(Token::LET); |
1713 if (var_context != kSourceElement && | 1879 if (var_context == kStatement) { |
1714 var_context != kForStatement) { | |
1715 // Let declarations are only allowed in source element positions. | 1880 // Let declarations are only allowed in source element positions. |
1716 ASSERT(var_context == kStatement); | |
1717 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1881 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
1718 *ok = false; | 1882 *ok = false; |
1719 return NULL; | 1883 return NULL; |
1720 } | 1884 } |
1721 mode = LET; | 1885 mode = LET; |
1722 needs_init = true; | 1886 needs_init = true; |
1723 init_op = Token::INIT_LET; | 1887 init_op = Token::INIT_LET; |
1724 } else { | 1888 } else { |
1725 UNREACHABLE(); // by current callers | 1889 UNREACHABLE(); // by current callers |
1726 } | 1890 } |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2446 ASSERT(for_scope == NULL); | 2610 ASSERT(for_scope == NULL); |
2447 // Parsed for-in loop w/ variable/const declaration. | 2611 // Parsed for-in loop w/ variable/const declaration. |
2448 return result; | 2612 return result; |
2449 } else { | 2613 } else { |
2450 init = variable_statement; | 2614 init = variable_statement; |
2451 } | 2615 } |
2452 } else if (peek() == Token::LET) { | 2616 } else if (peek() == Token::LET) { |
2453 Handle<String> name; | 2617 Handle<String> name; |
2454 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2618 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2455 Block* variable_statement = | 2619 Block* variable_statement = |
2456 ParseVariableDeclarations(kForStatement, | 2620 ParseVariableDeclarations(kForStatement, &decl_props, &name, CHECK_OK); |
2457 &decl_props, | |
2458 &name, | |
2459 CHECK_OK); | |
2460 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2621 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
2461 if (peek() == Token::IN && accept_IN) { | 2622 if (peek() == Token::IN && accept_IN) { |
2462 // Rewrite a for-in statement of the form | 2623 // Rewrite a for-in statement of the form |
2463 // | 2624 // |
2464 // for (let x in e) b | 2625 // for (let x in e) b |
2465 // | 2626 // |
2466 // into | 2627 // into |
2467 // | 2628 // |
2468 // <let x' be a temporary variable> | 2629 // <let x' be a temporary variable> |
2469 // for (x' in e) { | 2630 // for (x' in e) { |
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5619 ASSERT(info->isolate()->has_pending_exception()); | 5780 ASSERT(info->isolate()->has_pending_exception()); |
5620 } else { | 5781 } else { |
5621 result = parser.ParseProgram(info); | 5782 result = parser.ParseProgram(info); |
5622 } | 5783 } |
5623 } | 5784 } |
5624 info->SetFunction(result); | 5785 info->SetFunction(result); |
5625 return (result != NULL); | 5786 return (result != NULL); |
5626 } | 5787 } |
5627 | 5788 |
5628 } } // namespace v8::internal | 5789 } } // namespace v8::internal |
OLD | NEW |