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 (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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |