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...) 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...) 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...) 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 (peek() == Token::PERIOD) { | |
1285 Consume(Token::PERIOD); | |
Lasse Reichstein Nielsen
2012/02/20 09:55:48
Can be shortened to
while (Check(Token::PERIOD))
rossberg
2012/02/20 12:30:04
Done.
| |
1286 Handle<String> name = ParseIdentifierName(CHECK_OK); | |
1287 result = factory()->NewModulePath(result, name); | |
1288 } | |
1289 | |
1290 return result; | |
1291 } | |
1292 | |
1293 | |
1294 Module* Parser::ParseModuleVariable(bool* ok) { | |
1295 // ModulePath: | |
1296 // Identifier | |
1297 | |
1298 Handle<String> name = ParseIdentifier(CHECK_OK); | |
1299 VariableProxy* proxy = top_scope_->NewUnresolved( | |
1300 factory(), name, scanner().location().beg_pos); | |
1301 return factory()->NewModuleVariable(proxy); | |
1302 } | |
1303 | |
1304 | |
1305 Module* Parser::ParseModuleUrl(bool* ok) { | |
1306 // Module: | |
1307 // 'at' String | |
1308 | |
1309 Token::Value token = Next(); | |
1310 Handle<String> symbol = GetSymbol(ok); | |
Lasse Reichstein Nielsen
2012/02/20 09:55:48
Should this continue after an error?
I.e., shouldn
rossberg
2012/02/20 12:30:04
Right, I don't know what I was thinking. Much simp
| |
1311 | |
1312 if (*ok && token == Token::IDENTIFIER && | |
1313 symbol->IsEqualTo(CStrVector("at"))) { | |
1314 token = Next(); | |
1315 symbol = GetSymbol(ok); | |
1316 } else { | |
1317 *ok = false; | |
1318 } | |
1319 | |
1320 if (!*ok || token != Token::STRING) { | |
1321 *ok = false; | |
1322 ReportUnexpectedToken(token); | |
1323 return NULL; | |
1324 } | |
1325 | |
1326 return factory()->NewModuleUrl(symbol); | |
1327 } | |
1328 | |
1329 | |
1330 Block* Parser::ParseImportDeclaration(bool* ok) { | |
1331 // TODO(rossberg) | |
1332 return NULL; | |
1333 } | |
1334 | |
1335 | |
1336 Block* Parser::ParseExportDeclaration(bool* ok) { | |
1337 // TODO(rossberg) | |
1338 return NULL; | |
1339 } | |
1340 | |
1341 | |
1342 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | |
1343 bool* ok) { | |
1344 // (Ecma 262 5th Edition, clause 14): | |
1345 // SourceElement: | |
1346 // Statement | |
1347 // FunctionDeclaration | |
1348 // | |
1349 // In harmony mode we allow additionally the following productions | |
1350 // BlockElement (aka SourceElement): | |
1351 // LetDeclaration | |
1352 // ConstDeclaration | |
1353 | |
1354 switch (peek()) { | |
1355 case Token::FUNCTION: | |
1356 return ParseFunctionDeclaration(ok); | |
1357 case Token::LET: | |
1358 case Token::CONST: | |
1359 return ParseVariableStatement(kModuleElement, ok); | |
1360 default: | |
1361 return ParseStatement(labels, ok); | |
1362 } | |
1363 } | |
1364 | |
1365 | |
1190 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1366 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
1191 // Statement :: | 1367 // Statement :: |
1192 // Block | 1368 // Block |
1193 // VariableStatement | 1369 // VariableStatement |
1194 // EmptyStatement | 1370 // EmptyStatement |
1195 // ExpressionStatement | 1371 // ExpressionStatement |
1196 // IfStatement | 1372 // IfStatement |
1197 // IterationStatement | 1373 // IterationStatement |
1198 // ContinueStatement | 1374 // ContinueStatement |
1199 // BreakStatement | 1375 // BreakStatement |
(...skipping 137 matching lines...) Loading... | |
1337 // will be added to the scope so that the declaration can be added | 1513 // will be added to the scope so that the declaration can be added |
1338 // to the corresponding activation frame at runtime if necessary. | 1514 // to the corresponding activation frame at runtime if necessary. |
1339 // For instance declarations inside an eval scope need to be added | 1515 // For instance declarations inside an eval scope need to be added |
1340 // to the calling function context. | 1516 // to the calling function context. |
1341 // Similarly, strict mode eval scope does not leak variable declarations to | 1517 // Similarly, strict mode eval scope does not leak variable declarations to |
1342 // the caller's scope so we declare all locals, too. | 1518 // the caller's scope so we declare all locals, too. |
1343 // Also for block scoped let/const bindings the variable can be | 1519 // Also for block scoped let/const bindings the variable can be |
1344 // statically declared. | 1520 // statically declared. |
1345 if (declaration_scope->is_function_scope() || | 1521 if (declaration_scope->is_function_scope() || |
1346 declaration_scope->is_strict_or_extended_eval_scope() || | 1522 declaration_scope->is_strict_or_extended_eval_scope() || |
1347 declaration_scope->is_block_scope()) { | 1523 declaration_scope->is_block_scope() || |
1524 declaration_scope->is_module_scope()) { | |
1348 // Declare the variable in the function scope. | 1525 // Declare the variable in the function scope. |
1349 var = declaration_scope->LocalLookup(name); | 1526 var = declaration_scope->LocalLookup(name); |
1350 if (var == NULL) { | 1527 if (var == NULL) { |
1351 // Declare the name. | 1528 // Declare the name. |
1352 var = declaration_scope->DeclareLocal(name, mode, init_flag); | 1529 var = declaration_scope->DeclareLocal(name, mode, init_flag); |
1353 } else { | 1530 } else { |
1354 // The name was declared in this scope before; check for conflicting | 1531 // The name was declared in this scope before; check for conflicting |
1355 // re-declarations. We have a conflict if either of the declarations is | 1532 // 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 | 1533 // not a var. There is similar code in runtime.cc in the Declare |
1357 // functions. The function CheckNonConflictingScope checks for conflicting | 1534 // functions. The function CheckNonConflictingScope checks for conflicting |
(...skipping 209 matching lines...) Loading... | |
1567 result->AddStatement(stat); | 1744 result->AddStatement(stat); |
1568 block_finder.Update(stat); | 1745 block_finder.Update(stat); |
1569 } | 1746 } |
1570 } | 1747 } |
1571 Expect(Token::RBRACE, CHECK_OK); | 1748 Expect(Token::RBRACE, CHECK_OK); |
1572 return result; | 1749 return result; |
1573 } | 1750 } |
1574 | 1751 |
1575 | 1752 |
1576 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1753 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
1577 // The harmony mode uses source elements instead of statements. | 1754 // The harmony mode uses block elements instead of statements. |
1578 // | 1755 // |
1579 // Block :: | 1756 // Block :: |
1580 // '{' SourceElement* '}' | 1757 // '{' BlockElement* '}' |
1581 | 1758 |
1582 // Construct block expecting 16 statements. | 1759 // Construct block expecting 16 statements. |
1583 Block* body = factory()->NewBlock(labels, 16, false); | 1760 Block* body = factory()->NewBlock(labels, 16, false); |
1584 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1761 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
1585 | 1762 |
1586 // Parse the statements and collect escaping labels. | 1763 // Parse the statements and collect escaping labels. |
1587 Expect(Token::LBRACE, CHECK_OK); | 1764 Expect(Token::LBRACE, CHECK_OK); |
1588 block_scope->set_start_position(scanner().location().beg_pos); | 1765 block_scope->set_start_position(scanner().location().beg_pos); |
1589 { BlockState block_state(this, block_scope); | 1766 { BlockState block_state(this, block_scope); |
1590 TargetCollector collector; | 1767 TargetCollector collector; |
1591 Target target(&this->target_stack_, &collector); | 1768 Target target(&this->target_stack_, &collector); |
1592 Target target_body(&this->target_stack_, body); | 1769 Target target_body(&this->target_stack_, body); |
1593 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1770 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
1594 | 1771 |
1595 while (peek() != Token::RBRACE) { | 1772 while (peek() != Token::RBRACE) { |
1596 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1773 Statement* stat = ParseBlockElement(NULL, CHECK_OK); |
1597 if (stat && !stat->IsEmpty()) { | 1774 if (stat && !stat->IsEmpty()) { |
1598 body->AddStatement(stat); | 1775 body->AddStatement(stat); |
1599 block_finder.Update(stat); | 1776 block_finder.Update(stat); |
1600 } | 1777 } |
1601 } | 1778 } |
1602 } | 1779 } |
1603 Expect(Token::RBRACE, CHECK_OK); | 1780 Expect(Token::RBRACE, CHECK_OK); |
1604 block_scope->set_end_position(scanner().location().end_pos); | 1781 block_scope->set_end_position(scanner().location().end_pos); |
1605 block_scope = block_scope->FinalizeBlockScope(); | 1782 block_scope = block_scope->FinalizeBlockScope(); |
1606 body->set_block_scope(block_scope); | 1783 body->set_block_scope(block_scope); |
1607 return body; | 1784 return body; |
1608 } | 1785 } |
1609 | 1786 |
1610 | 1787 |
1611 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1788 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
1612 bool* ok) { | 1789 bool* ok) { |
1613 // VariableStatement :: | 1790 // VariableStatement :: |
1614 // VariableDeclarations ';' | 1791 // VariableDeclarations ';' |
1615 | 1792 |
1616 Handle<String> ignore; | 1793 Handle<String> ignore; |
1617 Block* result = ParseVariableDeclarations(var_context, | 1794 Block* result = |
1618 NULL, | 1795 ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK); |
1619 &ignore, | |
1620 CHECK_OK); | |
1621 ExpectSemicolon(CHECK_OK); | 1796 ExpectSemicolon(CHECK_OK); |
1622 return result; | 1797 return result; |
1623 } | 1798 } |
1624 | 1799 |
1625 | 1800 |
1626 bool Parser::IsEvalOrArguments(Handle<String> string) { | 1801 bool Parser::IsEvalOrArguments(Handle<String> string) { |
1627 return string.is_identical_to(isolate()->factory()->eval_symbol()) || | 1802 return string.is_identical_to(isolate()->factory()->eval_symbol()) || |
1628 string.is_identical_to(isolate()->factory()->arguments_symbol()); | 1803 string.is_identical_to(isolate()->factory()->arguments_symbol()); |
1629 } | 1804 } |
1630 | 1805 |
(...skipping 46 matching lines...) Loading... | |
1677 switch (top_scope_->language_mode()) { | 1852 switch (top_scope_->language_mode()) { |
1678 case CLASSIC_MODE: | 1853 case CLASSIC_MODE: |
1679 mode = CONST; | 1854 mode = CONST; |
1680 init_op = Token::INIT_CONST; | 1855 init_op = Token::INIT_CONST; |
1681 break; | 1856 break; |
1682 case STRICT_MODE: | 1857 case STRICT_MODE: |
1683 ReportMessage("strict_const", Vector<const char*>::empty()); | 1858 ReportMessage("strict_const", Vector<const char*>::empty()); |
1684 *ok = false; | 1859 *ok = false; |
1685 return NULL; | 1860 return NULL; |
1686 case EXTENDED_MODE: | 1861 case EXTENDED_MODE: |
1687 if (var_context != kSourceElement && | 1862 if (var_context == kStatement) { |
1688 var_context != kForStatement) { | |
1689 // In extended mode 'const' declarations are only allowed in source | 1863 // In extended mode 'const' declarations are only allowed in source |
1690 // element positions. | 1864 // element positions. |
1691 ReportMessage("unprotected_const", Vector<const char*>::empty()); | 1865 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
1692 *ok = false; | 1866 *ok = false; |
1693 return NULL; | 1867 return NULL; |
1694 } | 1868 } |
1695 mode = CONST_HARMONY; | 1869 mode = CONST_HARMONY; |
1696 init_op = Token::INIT_CONST_HARMONY; | 1870 init_op = Token::INIT_CONST_HARMONY; |
1697 } | 1871 } |
1698 is_const = true; | 1872 is_const = true; |
1699 needs_init = true; | 1873 needs_init = true; |
1700 } else if (peek() == Token::LET) { | 1874 } else if (peek() == Token::LET) { |
1701 // ES6 Draft Rev4 section 12.2.1: | 1875 // ES6 Draft Rev4 section 12.2.1: |
1702 // | 1876 // |
1703 // LetDeclaration : let LetBindingList ; | 1877 // LetDeclaration : let LetBindingList ; |
1704 // | 1878 // |
1705 // * It is a Syntax Error if the code that matches this production is not | 1879 // * It is a Syntax Error if the code that matches this production is not |
1706 // contained in extended code. | 1880 // contained in extended code. |
1707 if (!is_extended_mode()) { | 1881 if (!is_extended_mode()) { |
1708 ReportMessage("illegal_let", Vector<const char*>::empty()); | 1882 ReportMessage("illegal_let", Vector<const char*>::empty()); |
1709 *ok = false; | 1883 *ok = false; |
1710 return NULL; | 1884 return NULL; |
1711 } | 1885 } |
1712 Consume(Token::LET); | 1886 Consume(Token::LET); |
1713 if (var_context != kSourceElement && | 1887 if (var_context == kStatement) { |
1714 var_context != kForStatement) { | |
1715 // Let declarations are only allowed in source element positions. | 1888 // Let declarations are only allowed in source element positions. |
1716 ASSERT(var_context == kStatement); | |
1717 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1889 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
1718 *ok = false; | 1890 *ok = false; |
1719 return NULL; | 1891 return NULL; |
1720 } | 1892 } |
1721 mode = LET; | 1893 mode = LET; |
1722 needs_init = true; | 1894 needs_init = true; |
1723 init_op = Token::INIT_LET; | 1895 init_op = Token::INIT_LET; |
1724 } else { | 1896 } else { |
1725 UNREACHABLE(); // by current callers | 1897 UNREACHABLE(); // by current callers |
1726 } | 1898 } |
(...skipping 719 matching lines...) Loading... | |
2446 ASSERT(for_scope == NULL); | 2618 ASSERT(for_scope == NULL); |
2447 // Parsed for-in loop w/ variable/const declaration. | 2619 // Parsed for-in loop w/ variable/const declaration. |
2448 return result; | 2620 return result; |
2449 } else { | 2621 } else { |
2450 init = variable_statement; | 2622 init = variable_statement; |
2451 } | 2623 } |
2452 } else if (peek() == Token::LET) { | 2624 } else if (peek() == Token::LET) { |
2453 Handle<String> name; | 2625 Handle<String> name; |
2454 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2626 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2455 Block* variable_statement = | 2627 Block* variable_statement = |
2456 ParseVariableDeclarations(kForStatement, | 2628 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; | 2629 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
2461 if (peek() == Token::IN && accept_IN) { | 2630 if (peek() == Token::IN && accept_IN) { |
2462 // Rewrite a for-in statement of the form | 2631 // Rewrite a for-in statement of the form |
2463 // | 2632 // |
2464 // for (let x in e) b | 2633 // for (let x in e) b |
2465 // | 2634 // |
2466 // into | 2635 // into |
2467 // | 2636 // |
2468 // <let x' be a temporary variable> | 2637 // <let x' be a temporary variable> |
2469 // for (x' in e) { | 2638 // for (x' in e) { |
(...skipping 3149 matching lines...) Loading... | |
5619 ASSERT(info->isolate()->has_pending_exception()); | 5788 ASSERT(info->isolate()->has_pending_exception()); |
5620 } else { | 5789 } else { |
5621 result = parser.ParseProgram(info); | 5790 result = parser.ParseProgram(info); |
5622 } | 5791 } |
5623 } | 5792 } |
5624 info->SetFunction(result); | 5793 info->SetFunction(result); |
5625 return (result != NULL); | 5794 return (result != NULL); |
5626 } | 5795 } |
5627 | 5796 |
5628 } } // namespace v8::internal | 5797 } } // namespace v8::internal |
OLD | NEW |