Chromium Code Reviews| 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 |