Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: src/parser.cc

Issue 7616009: Parse harmony let declarations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Updated tests. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 804 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
805 for (int i = 0; i < args.length(); i++) { 805 for (int i = 0; i < args.length(); i++) {
806 elements->set(i, *args[i]); 806 elements->set(i, *args[i]);
807 } 807 }
808 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 808 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
809 Handle<Object> result = factory->NewSyntaxError(type, array); 809 Handle<Object> result = factory->NewSyntaxError(type, array);
810 isolate()->Throw(*result, &location); 810 isolate()->Throw(*result, &location);
811 } 811 }
812 812
813 void Parser::SetHarmonyBlockScoping(bool block_scoping) { 813 void Parser::SetHarmonyBlockScoping(bool block_scoping) {
814 scanner().SetHarmonyBlockScoping(block_scoping);
814 harmony_block_scoping_ = block_scoping; 815 harmony_block_scoping_ = block_scoping;
815 } 816 }
816 817
817 // Base class containing common code for the different finder classes used by 818 // Base class containing common code for the different finder classes used by
818 // the parser. 819 // the parser.
819 class ParserFinder { 820 class ParserFinder {
820 protected: 821 protected:
821 ParserFinder() {} 822 ParserFinder() {}
822 static Assignment* AsAssignment(Statement* stat) { 823 static Assignment* AsAssignment(Statement* stat) {
823 if (stat == NULL) return NULL; 824 if (stat == NULL) return NULL;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 } 1087 }
1087 1088
1088 Isolate* isolate_; 1089 Isolate* isolate_;
1089 bool only_simple_this_property_assignments_; 1090 bool only_simple_this_property_assignments_;
1090 ZoneStringList* names_; 1091 ZoneStringList* names_;
1091 ZoneList<int>* assigned_arguments_; 1092 ZoneList<int>* assigned_arguments_;
1092 ZoneObjectList* assigned_constants_; 1093 ZoneObjectList* assigned_constants_;
1093 }; 1094 };
1094 1095
1095 1096
1097 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1098 bool* ok) {
1099 if (peek() == Token::FUNCTION) {
1100 // FunctionDeclaration is only allowed in the context of SourceElements
1101 // (Ecma 262 5th Edition, clause 14):
1102 // SourceElement:
1103 // Statement
1104 // FunctionDeclaration
1105 // Common language extension is to allow function declaration in place
1106 // of any statement. This language extension is disabled in strict mode.
1107 return ParseFunctionDeclaration(ok);
1108 } else if (peek() == Token::LET) {
1109 return ParseVariableStatement(kSourceElement, ok);
1110 } else {
1111 return ParseStatement(labels, ok);
1112 }
1113 }
1114
1115
1096 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1116 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1097 int end_token, 1117 int end_token,
1098 bool* ok) { 1118 bool* ok) {
1099 // SourceElements :: 1119 // SourceElements ::
1100 // (Statement)* <end_token> 1120 // (Statement)* <end_token>
1101 1121
1102 // Allocate a target stack to use for this set of source 1122 // Allocate a target stack to use for this set of source
1103 // elements. This way, all scripts and functions get their own 1123 // elements. This way, all scripts and functions get their own
1104 // target stack thus avoiding illegal breaks and continues across 1124 // target stack thus avoiding illegal breaks and continues across
1105 // functions. 1125 // functions.
1106 TargetScope scope(&this->target_stack_); 1126 TargetScope scope(&this->target_stack_);
1107 1127
1108 ASSERT(processor != NULL); 1128 ASSERT(processor != NULL);
1109 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1129 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1110 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); 1130 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
1111 bool directive_prologue = true; // Parsing directive prologue. 1131 bool directive_prologue = true; // Parsing directive prologue.
1112 1132
1113 while (peek() != end_token) { 1133 while (peek() != end_token) {
1114 if (directive_prologue && peek() != Token::STRING) { 1134 if (directive_prologue && peek() != Token::STRING) {
1115 directive_prologue = false; 1135 directive_prologue = false;
1116 } 1136 }
1117 1137
1118 Scanner::Location token_loc = scanner().peek_location(); 1138 Scanner::Location token_loc = scanner().peek_location();
1119 1139 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1120 Statement* stat;
1121 if (peek() == Token::FUNCTION) {
1122 // FunctionDeclaration is only allowed in the context of SourceElements
1123 // (Ecma 262 5th Edition, clause 14):
1124 // SourceElement:
1125 // Statement
1126 // FunctionDeclaration
1127 // Common language extension is to allow function declaration in place
1128 // of any statement. This language extension is disabled in strict mode.
1129 stat = ParseFunctionDeclaration(CHECK_OK);
1130 } else {
1131 stat = ParseStatement(NULL, CHECK_OK);
1132 }
1133
1134 if (stat == NULL || stat->IsEmpty()) { 1140 if (stat == NULL || stat->IsEmpty()) {
1135 directive_prologue = false; // End of directive prologue. 1141 directive_prologue = false; // End of directive prologue.
1136 continue; 1142 continue;
1137 } 1143 }
1138 1144
1139 if (directive_prologue) { 1145 if (directive_prologue) {
1140 // A shot at a directive. 1146 // A shot at a directive.
1141 ExpressionStatement *e_stat; 1147 ExpressionStatement *e_stat;
1142 Literal *literal; 1148 Literal *literal;
1143 // Still processing directive prologue? 1149 // Still processing directive prologue?
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 1217
1212 // Keep the source position of the statement 1218 // Keep the source position of the statement
1213 int statement_pos = scanner().peek_location().beg_pos; 1219 int statement_pos = scanner().peek_location().beg_pos;
1214 Statement* stmt = NULL; 1220 Statement* stmt = NULL;
1215 switch (peek()) { 1221 switch (peek()) {
1216 case Token::LBRACE: 1222 case Token::LBRACE:
1217 return ParseBlock(labels, ok); 1223 return ParseBlock(labels, ok);
1218 1224
1219 case Token::CONST: // fall through 1225 case Token::CONST: // fall through
1220 case Token::VAR: 1226 case Token::VAR:
1221 stmt = ParseVariableStatement(ok); 1227 stmt = ParseVariableStatement(kStatement, ok);
1222 break; 1228 break;
1223 1229
1224 case Token::SEMICOLON: 1230 case Token::SEMICOLON:
1225 Next(); 1231 Next();
1226 return EmptyStatement(); 1232 return EmptyStatement();
1227 1233
1228 case Token::IF: 1234 case Token::IF:
1229 stmt = ParseIfStatement(labels, ok); 1235 stmt = ParseIfStatement(labels, ok);
1230 break; 1236 break;
1231 1237
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 return stmt; 1312 return stmt;
1307 } 1313 }
1308 1314
1309 1315
1310 VariableProxy* Parser::Declare(Handle<String> name, 1316 VariableProxy* Parser::Declare(Handle<String> name,
1311 Variable::Mode mode, 1317 Variable::Mode mode,
1312 FunctionLiteral* fun, 1318 FunctionLiteral* fun,
1313 bool resolve, 1319 bool resolve,
1314 bool* ok) { 1320 bool* ok) {
1315 Variable* var = NULL; 1321 Variable* var = NULL;
1316 // If we are inside a function, a declaration of a variable 1322 // If we are inside a function, a declaration of a var/const variable is a
1317 // is a truly local variable, and the scope of the variable 1323 // truly local variable, and the scope of the variable is always the function
1318 // is always the function scope. 1324 // scope.
1319 1325
1320 // If a function scope exists, then we can statically declare this 1326 // If a function scope exists, then we can statically declare this
1321 // variable and also set its mode. In any case, a Declaration node 1327 // variable and also set its mode. In any case, a Declaration node
1322 // will be added to the scope so that the declaration can be added 1328 // will be added to the scope so that the declaration can be added
1323 // to the corresponding activation frame at runtime if necessary. 1329 // to the corresponding activation frame at runtime if necessary.
1324 // For instance declarations inside an eval scope need to be added 1330 // For instance declarations inside an eval scope need to be added
1325 // to the calling function context. 1331 // to the calling function context.
1326 // Similarly, strict mode eval scope does not leak variable declarations to 1332 // Similarly, strict mode eval scope does not leak variable declarations to
1327 // the caller's scope so we declare all locals, too. 1333 // the caller's scope so we declare all locals, too.
1328 Scope* declaration_scope = top_scope_->DeclarationScope(); 1334
1335 Scope* declaration_scope = mode == Variable::LET ? top_scope_
1336 : top_scope_->DeclarationScope();
1329 if (declaration_scope->is_function_scope() || 1337 if (declaration_scope->is_function_scope() ||
1330 declaration_scope->is_strict_mode_eval_scope()) { 1338 declaration_scope->is_strict_mode_eval_scope() ||
1339 declaration_scope->is_block_scope()) {
1331 // Declare the variable in the function scope. 1340 // Declare the variable in the function scope.
1332 var = declaration_scope->LocalLookup(name); 1341 var = declaration_scope->LocalLookup(name);
1333 if (var == NULL) { 1342 if (var == NULL) {
1334 // Declare the name. 1343 // Declare the name.
1335 var = declaration_scope->DeclareLocal(name, mode); 1344 var = declaration_scope->DeclareLocal(name, mode);
1336 } else { 1345 } else {
1337 // The name was declared before; check for conflicting 1346 // The name was declared before; check for conflicting re-declarations.
1338 // re-declarations. If the previous declaration was a const or the 1347 // We have a conflict if either of the declarations is not a var. There
1339 // current declaration is a const then we have a conflict. There is 1348 // is similar code in runtime.cc in the Declare functions.
1340 // similar code in runtime.cc in the Declare functions. 1349 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
1341 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { 1350 // We only have vars, consts and lets in declarations.
1342 // We only have vars and consts in declarations.
1343 ASSERT(var->mode() == Variable::VAR || 1351 ASSERT(var->mode() == Variable::VAR ||
1344 var->mode() == Variable::CONST); 1352 var->mode() == Variable::CONST ||
1345 const char* type = (var->mode() == Variable::VAR) ? "var" : "const"; 1353 var->mode() == Variable::LET);
1354 const char* type = (var->mode() == Variable::VAR) ? "var" :
1355 (var->mode() == Variable::CONST) ? "const" : "let";
1346 Handle<String> type_string = 1356 Handle<String> type_string =
1347 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1357 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1348 Expression* expression = 1358 Expression* expression =
1349 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1359 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1350 type_string, name); 1360 type_string, name);
1351 declaration_scope->SetIllegalRedeclaration(expression); 1361 declaration_scope->SetIllegalRedeclaration(expression);
1352 } 1362 }
1353 } 1363 }
1354 } 1364 }
1355 1365
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 Handle<String> name = ParseIdentifierOrStrictReservedWord( 1488 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1479 &is_strict_reserved, CHECK_OK); 1489 &is_strict_reserved, CHECK_OK);
1480 FunctionLiteral* fun = ParseFunctionLiteral(name, 1490 FunctionLiteral* fun = ParseFunctionLiteral(name,
1481 is_strict_reserved, 1491 is_strict_reserved,
1482 function_token_position, 1492 function_token_position,
1483 FunctionLiteral::DECLARATION, 1493 FunctionLiteral::DECLARATION,
1484 CHECK_OK); 1494 CHECK_OK);
1485 // Even if we're not at the top-level of the global or a function 1495 // Even if we're not at the top-level of the global or a function
1486 // scope, we treat is as such and introduce the function with it's 1496 // scope, we treat is as such and introduce the function with it's
1487 // initial value upon entering the corresponding scope. 1497 // initial value upon entering the corresponding scope.
1488 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1498 Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR;
1499 Declare(name, mode, fun, true, CHECK_OK);
1489 return EmptyStatement(); 1500 return EmptyStatement();
1490 } 1501 }
1491 1502
1492 1503
1493 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 1504 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1494 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); 1505 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok);
1495 1506
1496 // Block :: 1507 // Block ::
1497 // '{' Statement* '}' 1508 // '{' Statement* '}'
1498 1509
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 1544
1534 // Parse the statements and collect escaping labels. 1545 // Parse the statements and collect escaping labels.
1535 TargetCollector collector; 1546 TargetCollector collector;
1536 Target target(&this->target_stack_, &collector); 1547 Target target(&this->target_stack_, &collector);
1537 Expect(Token::LBRACE, CHECK_OK); 1548 Expect(Token::LBRACE, CHECK_OK);
1538 { 1549 {
1539 Target target_body(&this->target_stack_, body); 1550 Target target_body(&this->target_stack_, body);
1540 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1551 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1541 1552
1542 while (peek() != Token::RBRACE) { 1553 while (peek() != Token::RBRACE) {
1543 Statement* stat = ParseStatement(NULL, CHECK_OK); 1554 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1544 if (stat && !stat->IsEmpty()) { 1555 if (stat && !stat->IsEmpty()) {
1545 body->AddStatement(stat); 1556 body->AddStatement(stat);
1546 block_finder.Update(stat); 1557 block_finder.Update(stat);
1547 } 1558 }
1548 } 1559 }
1549 } 1560 }
1550 Expect(Token::RBRACE, CHECK_OK); 1561 Expect(Token::RBRACE, CHECK_OK);
1551 1562
1552 // Create exit block. 1563 // Create exit block.
1553 Block* exit = new(zone()) Block(isolate(), NULL, 1, false); 1564 Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
1554 exit->AddStatement(new(zone()) ExitContextStatement()); 1565 exit->AddStatement(new(zone()) ExitContextStatement());
1555 1566
1556 // Create a try-finally statement. 1567 // Create a try-finally statement.
1557 TryFinallyStatement* try_finally = 1568 TryFinallyStatement* try_finally =
1558 new(zone()) TryFinallyStatement(body, exit); 1569 new(zone()) TryFinallyStatement(body, exit);
1559 try_finally->set_escaping_targets(collector.targets()); 1570 try_finally->set_escaping_targets(collector.targets());
1560 top_scope_ = saved_scope; 1571 top_scope_ = saved_scope;
1561 1572
1562 // Create a result block. 1573 // Create a result block.
1563 Block* result = new(zone()) Block(isolate(), NULL, 1, false); 1574 Block* result = new(zone()) Block(isolate(), NULL, 1, false);
1564 result->AddStatement(try_finally); 1575 result->AddStatement(try_finally);
1565 return result; 1576 return result;
1566 } 1577 }
1567 1578
1568 1579
1569 Block* Parser::ParseVariableStatement(bool* ok) { 1580 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1581 bool* ok) {
1570 // VariableStatement :: 1582 // VariableStatement ::
1571 // VariableDeclarations ';' 1583 // VariableDeclarations ';'
1572 1584
1573 Handle<String> ignore; 1585 Handle<String> ignore;
1574 Block* result = ParseVariableDeclarations(true, &ignore, CHECK_OK); 1586 Block* result = ParseVariableDeclarations(var_context,
1587 &ignore,
1588 CHECK_OK);
1575 ExpectSemicolon(CHECK_OK); 1589 ExpectSemicolon(CHECK_OK);
1576 return result; 1590 return result;
1577 } 1591 }
1578 1592
1579 1593
1580 bool Parser::IsEvalOrArguments(Handle<String> string) { 1594 bool Parser::IsEvalOrArguments(Handle<String> string) {
1581 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1595 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1582 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1596 string.is_identical_to(isolate()->factory()->arguments_symbol());
1583 } 1597 }
1584 1598
1585 1599
1586 // If the variable declaration declares exactly one non-const 1600 // If the variable declaration declares exactly one non-const
1587 // variable, then *var is set to that variable. In all other cases, 1601 // variable, then *var is set to that variable. In all other cases,
1588 // *var is untouched; in particular, it is the caller's responsibility 1602 // *var is untouched; in particular, it is the caller's responsibility
1589 // to initialize it properly. This mechanism is used for the parsing 1603 // to initialize it properly. This mechanism is used for the parsing
1590 // of 'for-in' loops. 1604 // of 'for-in' loops.
1591 Block* Parser::ParseVariableDeclarations(bool accept_IN, 1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
1592 Handle<String>* out, 1606 Handle<String>* out,
1593 bool* ok) { 1607 bool* ok) {
1594 // VariableDeclarations :: 1608 // VariableDeclarations ::
1595 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1596 1610
1597 Variable::Mode mode = Variable::VAR; 1611 Variable::Mode mode = Variable::VAR;
1598 bool is_const = false; 1612 bool is_const = false;
1599 Scope* declaration_scope = top_scope_->DeclarationScope();
1600 if (peek() == Token::VAR) { 1613 if (peek() == Token::VAR) {
1601 Consume(Token::VAR); 1614 Consume(Token::VAR);
1602 } else if (peek() == Token::CONST) { 1615 } else if (peek() == Token::CONST) {
1603 Consume(Token::CONST); 1616 Consume(Token::CONST);
1604 if (declaration_scope->is_strict_mode()) { 1617 if (top_scope_->is_strict_mode()) {
1605 ReportMessage("strict_const", Vector<const char*>::empty()); 1618 ReportMessage("strict_const", Vector<const char*>::empty());
1606 *ok = false; 1619 *ok = false;
1607 return NULL; 1620 return NULL;
1608 } 1621 }
1609 mode = Variable::CONST; 1622 mode = Variable::CONST;
1610 is_const = true; 1623 is_const = true;
1624 } else if (peek() == Token::LET) {
1625 Consume(Token::LET);
1626 if (var_context != kSourceElement &&
1627 var_context != kForStatement) {
1628 ASSERT(var_context == kStatement);
1629 ReportMessage("unprotected_let", Vector<const char*>::empty());
1630 *ok = false;
1631 return NULL;
1632 }
1633 mode = Variable::LET;
1611 } else { 1634 } else {
1612 UNREACHABLE(); // by current callers 1635 UNREACHABLE(); // by current callers
1613 } 1636 }
1614 1637
1615 // The scope of a variable/const declared anywhere inside a function 1638 Scope* declaration_scope = mode == Variable::LET
1639 ? top_scope_ : top_scope_->DeclarationScope();
1640 // The scope of a var/const declared variable anywhere inside a function
1616 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1641 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1617 // transform a source-level variable/const declaration into a (Function) 1642 // transform a source-level var/const declaration into a (Function)
1618 // Scope declaration, and rewrite the source-level initialization into an 1643 // Scope declaration, and rewrite the source-level initialization into an
1619 // assignment statement. We use a block to collect multiple assignments. 1644 // assignment statement. We use a block to collect multiple assignments.
1620 // 1645 //
1621 // We mark the block as initializer block because we don't want the 1646 // We mark the block as initializer block because we don't want the
1622 // rewriter to add a '.result' assignment to such a block (to get compliant 1647 // rewriter to add a '.result' assignment to such a block (to get compliant
1623 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1648 // behavior for code such as print(eval('var x = 7')), and for cosmetic
1624 // reasons when pretty-printing. Also, unless an assignment (initialization) 1649 // reasons when pretty-printing. Also, unless an assignment (initialization)
1625 // is inside an initializer block, it is ignored. 1650 // is inside an initializer block, it is ignored.
1626 // 1651 //
1627 // Create new block with one expected declaration. 1652 // Create new block with one expected declaration.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 // The "variable" c initialized to x is the same as the declared 1716 // The "variable" c initialized to x is the same as the declared
1692 // one - there is no re-lookup (see the last parameter of the 1717 // one - there is no re-lookup (see the last parameter of the
1693 // Declare() call above). 1718 // Declare() call above).
1694 1719
1695 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 1720 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
1696 Expression* value = NULL; 1721 Expression* value = NULL;
1697 int position = -1; 1722 int position = -1;
1698 if (peek() == Token::ASSIGN) { 1723 if (peek() == Token::ASSIGN) {
1699 Expect(Token::ASSIGN, CHECK_OK); 1724 Expect(Token::ASSIGN, CHECK_OK);
1700 position = scanner().location().beg_pos; 1725 position = scanner().location().beg_pos;
1701 value = ParseAssignmentExpression(accept_IN, CHECK_OK); 1726 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1702 // Don't infer if it is "a = function(){...}();"-like expression. 1727 // Don't infer if it is "a = function(){...}();"-like expression.
1703 if (fni_ != NULL && 1728 if (fni_ != NULL &&
1704 value->AsCall() == NULL && 1729 value->AsCall() == NULL &&
1705 value->AsCallNew() == NULL) { 1730 value->AsCallNew() == NULL) {
1706 fni_->Infer(); 1731 fni_->Infer();
1707 } 1732 }
1708 } 1733 }
1709 1734
1710 // Make sure that 'const c' actually initializes 'c' to undefined 1735 // Make sure that 'const c' actually initializes 'c' to undefined
1711 // even though it seems like a stupid thing to do. 1736 // even though it seems like a stupid thing to do.
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2316 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2292 2317
2293 Statement* init = NULL; 2318 Statement* init = NULL;
2294 2319
2295 Expect(Token::FOR, CHECK_OK); 2320 Expect(Token::FOR, CHECK_OK);
2296 Expect(Token::LPAREN, CHECK_OK); 2321 Expect(Token::LPAREN, CHECK_OK);
2297 if (peek() != Token::SEMICOLON) { 2322 if (peek() != Token::SEMICOLON) {
2298 if (peek() == Token::VAR || peek() == Token::CONST) { 2323 if (peek() == Token::VAR || peek() == Token::CONST) {
2299 Handle<String> name; 2324 Handle<String> name;
2300 Block* variable_statement = 2325 Block* variable_statement =
2301 ParseVariableDeclarations(false, &name, CHECK_OK); 2326 ParseVariableDeclarations(kForStatement, &name, CHECK_OK);
2302 2327
2303 if (peek() == Token::IN && !name.is_null()) { 2328 if (peek() == Token::IN && !name.is_null()) {
2304 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); 2329 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
2305 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); 2330 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
2306 Target target(&this->target_stack_, loop); 2331 Target target(&this->target_stack_, loop);
2307 2332
2308 Expect(Token::IN, CHECK_OK); 2333 Expect(Token::IN, CHECK_OK);
2309 Expression* enumerable = ParseExpression(true, CHECK_OK); 2334 Expression* enumerable = ParseExpression(true, CHECK_OK);
2310 Expect(Token::RPAREN, CHECK_OK); 2335 Expect(Token::RPAREN, CHECK_OK);
2311 2336
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after
3650 // handle as the function name. Remember if we were passed a non-empty 3675 // handle as the function name. Remember if we were passed a non-empty
3651 // handle to decide whether to invoke function name inference. 3676 // handle to decide whether to invoke function name inference.
3652 bool should_infer_name = function_name.is_null(); 3677 bool should_infer_name = function_name.is_null();
3653 3678
3654 // We want a non-null handle as the function name. 3679 // We want a non-null handle as the function name.
3655 if (should_infer_name) { 3680 if (should_infer_name) {
3656 function_name = isolate()->factory()->empty_symbol(); 3681 function_name = isolate()->factory()->empty_symbol();
3657 } 3682 }
3658 3683
3659 int num_parameters = 0; 3684 int num_parameters = 0;
3660 // Function declarations are hoisted. 3685 // Function declarations are function scoped in normal mode, so they are
3661 Scope* scope = (type == FunctionLiteral::DECLARATION) 3686 // hoisted. In harmony block scoping mode they are block scoped, so they
3687 // are not hoisted.
3688 Scope* scope = (type == FunctionLiteral::DECLARATION &&
3689 !harmony_block_scoping_)
3662 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) 3690 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
3663 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3691 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3664 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); 3692 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
3665 int materialized_literal_count; 3693 int materialized_literal_count;
3666 int expected_property_count; 3694 int expected_property_count;
3667 int start_pos; 3695 int start_pos;
3668 int end_pos; 3696 int end_pos;
3669 bool only_simple_this_property_assignments; 3697 bool only_simple_this_property_assignments;
3670 Handle<FixedArray> this_property_assignments; 3698 Handle<FixedArray> this_property_assignments;
3671 bool has_duplicate_parameters = false; 3699 bool has_duplicate_parameters = false;
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3953 Literal* Parser::GetLiteralTheHole() { 3981 Literal* Parser::GetLiteralTheHole() {
3954 return NewLiteral(isolate()->factory()->the_hole_value()); 3982 return NewLiteral(isolate()->factory()->the_hole_value());
3955 } 3983 }
3956 3984
3957 3985
3958 Literal* Parser::GetLiteralNumber(double value) { 3986 Literal* Parser::GetLiteralNumber(double value) {
3959 return NewNumberLiteral(value); 3987 return NewNumberLiteral(value);
3960 } 3988 }
3961 3989
3962 3990
3963 // Parses and identifier that is valid for the current scope, in particular it 3991 // Parses an identifier that is valid for the current scope, in particular it
3964 // fails on strict mode future reserved keywords in a strict scope. 3992 // fails on strict mode future reserved keywords in a strict scope.
3965 Handle<String> Parser::ParseIdentifier(bool* ok) { 3993 Handle<String> Parser::ParseIdentifier(bool* ok) {
3966 if (top_scope_->is_strict_mode()) { 3994 if (top_scope_->is_strict_mode()) {
3967 Expect(Token::IDENTIFIER, ok); 3995 Expect(Token::IDENTIFIER, ok);
3968 } else if (!Check(Token::IDENTIFIER)) { 3996 } else if (!Check(Token::IDENTIFIER)) {
3969 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 3997 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
3970 } 3998 }
3971 if (!*ok) return Handle<String>(); 3999 if (!*ok) return Handle<String>();
3972 return GetSymbol(ok); 4000 return GetSymbol(ok);
3973 } 4001 }
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after
5034 data++; 5062 data++;
5035 } 5063 }
5036 *source = data; 5064 *source = data;
5037 return result; 5065 return result;
5038 } 5066 }
5039 5067
5040 5068
5041 // Create a Scanner for the preparser to use as input, and preparse the source. 5069 // Create a Scanner for the preparser to use as input, and preparse the source.
5042 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5070 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
5043 bool allow_lazy, 5071 bool allow_lazy,
5044 ParserRecorder* recorder) { 5072 ParserRecorder* recorder,
5073 bool harmony_block_scoping) {
5045 Isolate* isolate = Isolate::Current(); 5074 Isolate* isolate = Isolate::Current();
5046 JavaScriptScanner scanner(isolate->unicode_cache()); 5075 JavaScriptScanner scanner(isolate->unicode_cache());
5047 scanner.Initialize(source); 5076 scanner.Initialize(source);
5077 scanner.SetHarmonyBlockScoping(harmony_block_scoping);
5048 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5078 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5049 if (!preparser::PreParser::PreParseProgram(&scanner, 5079 if (!preparser::PreParser::PreParseProgram(&scanner,
5050 recorder, 5080 recorder,
5051 allow_lazy, 5081 allow_lazy,
5052 stack_limit)) { 5082 stack_limit)) {
5053 isolate->StackOverflow(); 5083 isolate->StackOverflow();
5054 return NULL; 5084 return NULL;
5055 } 5085 }
5056 5086
5057 // Extract the accumulated data from the recorder as a single 5087 // Extract the accumulated data from the recorder as a single
5058 // contiguous vector that we are responsible for disposing. 5088 // contiguous vector that we are responsible for disposing.
5059 Vector<unsigned> store = recorder->ExtractData(); 5089 Vector<unsigned> store = recorder->ExtractData();
5060 return new ScriptDataImpl(store); 5090 return new ScriptDataImpl(store);
5061 } 5091 }
5062 5092
5063 5093
5064 // Preparse, but only collect data that is immediately useful, 5094 // Preparse, but only collect data that is immediately useful,
5065 // even if the preparser data is only used once. 5095 // even if the preparser data is only used once.
5066 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, 5096 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
5067 v8::Extension* extension) { 5097 v8::Extension* extension,
5098 bool harmony_block_scoping) {
5068 bool allow_lazy = FLAG_lazy && (extension == NULL); 5099 bool allow_lazy = FLAG_lazy && (extension == NULL);
5069 if (!allow_lazy) { 5100 if (!allow_lazy) {
5070 // Partial preparsing is only about lazily compiled functions. 5101 // Partial preparsing is only about lazily compiled functions.
5071 // If we don't allow lazy compilation, the log data will be empty. 5102 // If we don't allow lazy compilation, the log data will be empty.
5072 return NULL; 5103 return NULL;
5073 } 5104 }
5074 PartialParserRecorder recorder; 5105 PartialParserRecorder recorder;
5075 return DoPreParse(source, allow_lazy, &recorder); 5106 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
5076 } 5107 }
5077 5108
5078 5109
5079 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, 5110 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
5080 v8::Extension* extension) { 5111 v8::Extension* extension,
5112 bool harmony_block_scoping) {
5081 Handle<Script> no_script; 5113 Handle<Script> no_script;
5082 bool allow_lazy = FLAG_lazy && (extension == NULL); 5114 bool allow_lazy = FLAG_lazy && (extension == NULL);
5083 CompleteParserRecorder recorder; 5115 CompleteParserRecorder recorder;
5084 return DoPreParse(source, allow_lazy, &recorder); 5116 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
5085 } 5117 }
5086 5118
5087 5119
5088 bool RegExpParser::ParseRegExp(FlatStringReader* input, 5120 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5089 bool multiline, 5121 bool multiline,
5090 RegExpCompileData* result) { 5122 RegExpCompileData* result) {
5091 ASSERT(result != NULL); 5123 ASSERT(result != NULL);
5092 RegExpParser parser(input, &result->error, multiline); 5124 RegExpParser parser(input, &result->error, multiline);
5093 RegExpTree* tree = parser.ParsePattern(); 5125 RegExpTree* tree = parser.ParsePattern();
5094 if (parser.failed()) { 5126 if (parser.failed()) {
5095 ASSERT(tree == NULL); 5127 ASSERT(tree == NULL);
5096 ASSERT(!result->error.is_null()); 5128 ASSERT(!result->error.is_null());
5097 } else { 5129 } else {
5098 ASSERT(tree != NULL); 5130 ASSERT(tree != NULL);
5099 ASSERT(result->error.is_null()); 5131 ASSERT(result->error.is_null());
5100 result->tree = tree; 5132 result->tree = tree;
5101 int capture_count = parser.captures_started(); 5133 int capture_count = parser.captures_started();
5102 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5134 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5103 result->contains_anchor = parser.contains_anchor(); 5135 result->contains_anchor = parser.contains_anchor();
5104 result->capture_count = capture_count; 5136 result->capture_count = capture_count;
5105 } 5137 }
5106 return !parser.failed(); 5138 return !parser.failed();
5107 } 5139 }
5108 5140
5109 5141
5110 bool ParserApi::Parse(CompilationInfo* info) { 5142 bool ParserApi::Parse(CompilationInfo* info) {
5111 ASSERT(info->function() == NULL); 5143 ASSERT(info->function() == NULL);
5112 FunctionLiteral* result = NULL; 5144 FunctionLiteral* result = NULL;
5113 Handle<Script> script = info->script(); 5145 Handle<Script> script = info->script();
5146 bool harmony_block_scoping = !info->is_native() &&
5147 FLAG_harmony_block_scoping;
5114 if (info->is_lazy()) { 5148 if (info->is_lazy()) {
5115 Parser parser(script, true, NULL, NULL); 5149 Parser parser(script, true, NULL, NULL);
5116 parser.SetHarmonyBlockScoping(!info->is_native() && 5150 parser.SetHarmonyBlockScoping(harmony_block_scoping);
5117 FLAG_harmony_block_scoping);
5118 result = parser.ParseLazy(info); 5151 result = parser.ParseLazy(info);
5119 } else { 5152 } else {
5120 // Whether we allow %identifier(..) syntax. 5153 // Whether we allow %identifier(..) syntax.
5121 bool allow_natives_syntax = 5154 bool allow_natives_syntax =
5122 info->allows_natives_syntax() || FLAG_allow_natives_syntax; 5155 info->allows_natives_syntax() || FLAG_allow_natives_syntax;
5123 ScriptDataImpl* pre_data = info->pre_parse_data(); 5156 ScriptDataImpl* pre_data = info->pre_parse_data();
5124 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); 5157 Parser parser(script,
5125 parser.SetHarmonyBlockScoping(!info->is_native() && 5158 allow_natives_syntax,
5126 FLAG_harmony_block_scoping); 5159 info->extension(),
5160 pre_data);
5161 parser.SetHarmonyBlockScoping(harmony_block_scoping);
5127 if (pre_data != NULL && pre_data->has_error()) { 5162 if (pre_data != NULL && pre_data->has_error()) {
5128 Scanner::Location loc = pre_data->MessageLocation(); 5163 Scanner::Location loc = pre_data->MessageLocation();
5129 const char* message = pre_data->BuildMessage(); 5164 const char* message = pre_data->BuildMessage();
5130 Vector<const char*> args = pre_data->BuildArgs(); 5165 Vector<const char*> args = pre_data->BuildArgs();
5131 parser.ReportMessageAt(loc, message, args); 5166 parser.ReportMessageAt(loc, message, args);
5132 DeleteArray(message); 5167 DeleteArray(message);
5133 for (int i = 0; i < args.length(); i++) { 5168 for (int i = 0; i < args.length(); i++) {
5134 DeleteArray(args[i]); 5169 DeleteArray(args[i]);
5135 } 5170 }
5136 DeleteArray(args.start()); 5171 DeleteArray(args.start());
5137 ASSERT(info->isolate()->has_pending_exception()); 5172 ASSERT(info->isolate()->has_pending_exception());
5138 } else { 5173 } else {
5139 Handle<String> source = Handle<String>(String::cast(script->source())); 5174 Handle<String> source = Handle<String>(String::cast(script->source()));
5140 result = parser.ParseProgram(source, 5175 result = parser.ParseProgram(source,
5141 info->is_global(), 5176 info->is_global(),
5142 info->StrictMode()); 5177 info->StrictMode());
5143 } 5178 }
5144 } 5179 }
5145 info->SetFunction(result); 5180 info->SetFunction(result);
5146 return (result != NULL); 5181 return (result != NULL);
5147 } 5182 }
5148 5183
5149 } } // namespace v8::internal 5184 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | test/mjsunit/harmony/block-let-declaration.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698