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

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: 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 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 } 1086 }
1087 1087
1088 Isolate* isolate_; 1088 Isolate* isolate_;
1089 bool only_simple_this_property_assignments_; 1089 bool only_simple_this_property_assignments_;
1090 ZoneStringList* names_; 1090 ZoneStringList* names_;
1091 ZoneList<int>* assigned_arguments_; 1091 ZoneList<int>* assigned_arguments_;
1092 ZoneObjectList* assigned_constants_; 1092 ZoneObjectList* assigned_constants_;
1093 }; 1093 };
1094 1094
1095 1095
1096 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1097 bool* ok) {
1098 if (peek() == Token::FUNCTION) {
1099 // FunctionDeclaration is only allowed in the context of SourceElements
1100 // (Ecma 262 5th Edition, clause 14):
1101 // SourceElement:
1102 // Statement
1103 // FunctionDeclaration
1104 // Common language extension is to allow function declaration in place
1105 // of any statement. This language extension is disabled in strict mode.
1106 return ParseFunctionDeclaration(ok);
1107 } else if (peek() == Token::LET && harmony_block_scoping_) {
1108 return ParseVariableStatement(true, ok);
Lasse Reichstein 2011/08/12 08:08:33 Please use an enum with meaningful names for the f
Steven 2011/08/16 09:05:32 Done. See the VariableDeclarationContext enum. Als
1109 } else {
1110 return ParseStatement(labels, ok);
1111 }
1112 }
1113
1114
1096 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1115 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1097 int end_token, 1116 int end_token,
1098 bool* ok) { 1117 bool* ok) {
1099 // SourceElements :: 1118 // SourceElements ::
1100 // (Statement)* <end_token> 1119 // (Statement)* <end_token>
1101 1120
1102 // Allocate a target stack to use for this set of source 1121 // Allocate a target stack to use for this set of source
1103 // elements. This way, all scripts and functions get their own 1122 // elements. This way, all scripts and functions get their own
1104 // target stack thus avoiding illegal breaks and continues across 1123 // target stack thus avoiding illegal breaks and continues across
1105 // functions. 1124 // functions.
1106 TargetScope scope(&this->target_stack_); 1125 TargetScope scope(&this->target_stack_);
1107 1126
1108 ASSERT(processor != NULL); 1127 ASSERT(processor != NULL);
1109 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1128 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1110 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); 1129 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
1111 bool directive_prologue = true; // Parsing directive prologue. 1130 bool directive_prologue = true; // Parsing directive prologue.
1112 1131
1113 while (peek() != end_token) { 1132 while (peek() != end_token) {
1114 if (directive_prologue && peek() != Token::STRING) { 1133 if (directive_prologue && peek() != Token::STRING) {
1115 directive_prologue = false; 1134 directive_prologue = false;
1116 } 1135 }
1117 1136
1118 Scanner::Location token_loc = scanner().peek_location(); 1137 Scanner::Location token_loc = scanner().peek_location();
1119 1138 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()) { 1139 if (stat == NULL || stat->IsEmpty()) {
1135 directive_prologue = false; // End of directive prologue. 1140 directive_prologue = false; // End of directive prologue.
1136 continue; 1141 continue;
1137 } 1142 }
1138 1143
1139 if (directive_prologue) { 1144 if (directive_prologue) {
1140 // A shot at a directive. 1145 // A shot at a directive.
1141 ExpressionStatement *e_stat; 1146 ExpressionStatement *e_stat;
1142 Literal *literal; 1147 Literal *literal;
1143 // Still processing directive prologue? 1148 // Still processing directive prologue?
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 1216
1212 // Keep the source position of the statement 1217 // Keep the source position of the statement
1213 int statement_pos = scanner().peek_location().beg_pos; 1218 int statement_pos = scanner().peek_location().beg_pos;
1214 Statement* stmt = NULL; 1219 Statement* stmt = NULL;
1215 switch (peek()) { 1220 switch (peek()) {
1216 case Token::LBRACE: 1221 case Token::LBRACE:
1217 return ParseBlock(labels, ok); 1222 return ParseBlock(labels, ok);
1218 1223
1219 case Token::CONST: // fall through 1224 case Token::CONST: // fall through
1220 case Token::VAR: 1225 case Token::VAR:
1221 stmt = ParseVariableStatement(ok); 1226 stmt = ParseVariableStatement(false, ok);
1222 break; 1227 break;
1223 1228
1224 case Token::SEMICOLON: 1229 case Token::SEMICOLON:
1225 Next(); 1230 Next();
1226 return EmptyStatement(); 1231 return EmptyStatement();
1227 1232
1228 case Token::IF: 1233 case Token::IF:
1229 stmt = ParseIfStatement(labels, ok); 1234 stmt = ParseIfStatement(labels, ok);
1230 break; 1235 break;
1231 1236
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 // is always the function scope. 1323 // is always the function scope.
1319 1324
1320 // If a function scope exists, then we can statically declare this 1325 // If a function scope exists, then we can statically declare this
1321 // variable and also set its mode. In any case, a Declaration node 1326 // 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 1327 // will be added to the scope so that the declaration can be added
1323 // to the corresponding activation frame at runtime if necessary. 1328 // to the corresponding activation frame at runtime if necessary.
1324 // For instance declarations inside an eval scope need to be added 1329 // For instance declarations inside an eval scope need to be added
1325 // to the calling function context. 1330 // to the calling function context.
1326 // Similarly, strict mode eval scope does not leak variable declarations to 1331 // Similarly, strict mode eval scope does not leak variable declarations to
1327 // the caller's scope so we declare all locals, too. 1332 // the caller's scope so we declare all locals, too.
1328 Scope* declaration_scope = top_scope_->DeclarationScope(); 1333
1334 Scope* declaration_scope = mode == Variable::LET ? top_scope_
1335 : top_scope_->DeclarationScope();
1329 if (declaration_scope->is_function_scope() || 1336 if (declaration_scope->is_function_scope() ||
1330 declaration_scope->is_strict_mode_eval_scope()) { 1337 declaration_scope->is_strict_mode_eval_scope() ||
1338 declaration_scope->is_block_scope()) {
1331 // Declare the variable in the function scope. 1339 // Declare the variable in the function scope.
1332 var = declaration_scope->LocalLookup(name); 1340 var = declaration_scope->LocalLookup(name);
1333 if (var == NULL) { 1341 if (var == NULL) {
1334 // Declare the name. 1342 // Declare the name.
1335 var = declaration_scope->DeclareLocal(name, mode); 1343 var = declaration_scope->DeclareLocal(name, mode);
1336 } else { 1344 } else {
1337 // The name was declared before; check for conflicting 1345 // The name was declared before; check for conflicting re-declarations.
1338 // re-declarations. If the previous declaration was a const or the 1346 // 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 1347 // is similar code in runtime.cc in the Declare functions.
1340 // similar code in runtime.cc in the Declare functions. 1348 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
1341 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { 1349 // We only have vars, consts and lets in declarations.
1342 // We only have vars and consts in declarations.
1343 ASSERT(var->mode() == Variable::VAR || 1350 ASSERT(var->mode() == Variable::VAR ||
1344 var->mode() == Variable::CONST); 1351 var->mode() == Variable::CONST ||
1345 const char* type = (var->mode() == Variable::VAR) ? "var" : "const"; 1352 var->mode() == Variable::LET);
1353 const char* type = (var->mode() == Variable::VAR) ? "var" :
1354 (var->mode() == Variable::CONST) ? "const" : "let";
1346 Handle<String> type_string = 1355 Handle<String> type_string =
1347 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1356 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1348 Expression* expression = 1357 Expression* expression =
1349 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1358 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1350 type_string, name); 1359 type_string, name);
1351 declaration_scope->SetIllegalRedeclaration(expression); 1360 declaration_scope->SetIllegalRedeclaration(expression);
1352 } 1361 }
1353 } 1362 }
1354 } 1363 }
1355 1364
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 Handle<String> name = ParseIdentifierOrStrictReservedWord( 1487 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1479 &is_strict_reserved, CHECK_OK); 1488 &is_strict_reserved, CHECK_OK);
1480 FunctionLiteral* fun = ParseFunctionLiteral(name, 1489 FunctionLiteral* fun = ParseFunctionLiteral(name,
1481 is_strict_reserved, 1490 is_strict_reserved,
1482 function_token_position, 1491 function_token_position,
1483 FunctionLiteral::DECLARATION, 1492 FunctionLiteral::DECLARATION,
1484 CHECK_OK); 1493 CHECK_OK);
1485 // Even if we're not at the top-level of the global or a function 1494 // 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 1495 // scope, we treat is as such and introduce the function with it's
1487 // initial value upon entering the corresponding scope. 1496 // initial value upon entering the corresponding scope.
1488 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1497 Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR;
1498 Declare(name, mode, fun, true, CHECK_OK);
1489 return EmptyStatement(); 1499 return EmptyStatement();
1490 } 1500 }
1491 1501
1492 1502
1493 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 1503 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1494 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); 1504 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok);
1495 1505
1496 // Block :: 1506 // Block ::
1497 // '{' Statement* '}' 1507 // '{' Statement* '}'
1498 1508
(...skipping 16 matching lines...) Expand all
1515 return result; 1525 return result;
1516 } 1526 }
1517 1527
1518 1528
1519 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1529 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1520 // Construct block expecting 16 statements. 1530 // Construct block expecting 16 statements.
1521 Block* body = new(zone()) Block(isolate(), labels, 16, false); 1531 Block* body = new(zone()) Block(isolate(), labels, 16, false);
1522 Scope* saved_scope = top_scope_; 1532 Scope* saved_scope = top_scope_;
1523 Scope* block_scope = NewScope(top_scope_, 1533 Scope* block_scope = NewScope(top_scope_,
1524 Scope::BLOCK_SCOPE, 1534 Scope::BLOCK_SCOPE,
1525 inside_with()); 1535 inside_with());
Lasse Reichstein 2011/08/12 08:08:33 What baseline is this patch based on? I don't see
Steven 2011/08/16 09:05:32 It is based on a CL that was still in review. It's
1526 body->set_block_scope(block_scope); 1536 body->set_block_scope(block_scope);
1527 block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(), 1537 block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(),
1528 Variable::VAR); 1538 Variable::VAR);
1529 if (top_scope_->is_strict_mode()) { 1539 if (top_scope_->is_strict_mode()) {
1530 block_scope->EnableStrictMode(); 1540 block_scope->EnableStrictMode();
1531 } 1541 }
1532 top_scope_ = block_scope; 1542 top_scope_ = block_scope;
1533 1543
1534 // Parse the statements and collect escaping labels. 1544 // Parse the statements and collect escaping labels.
1535 TargetCollector collector; 1545 TargetCollector collector;
1536 Target target(&this->target_stack_, &collector); 1546 Target target(&this->target_stack_, &collector);
1537 Expect(Token::LBRACE, CHECK_OK); 1547 Expect(Token::LBRACE, CHECK_OK);
1538 { 1548 {
1539 Target target_body(&this->target_stack_, body); 1549 Target target_body(&this->target_stack_, body);
1540 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1550 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1541 1551
1542 while (peek() != Token::RBRACE) { 1552 while (peek() != Token::RBRACE) {
1543 Statement* stat = ParseStatement(NULL, CHECK_OK); 1553 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
Lasse Reichstein 2011/08/12 08:08:33 Will this enable function declarations inside bloc
Steven 2011/08/16 09:05:32 The proposal allows local function declarations in
1544 if (stat && !stat->IsEmpty()) { 1554 if (stat && !stat->IsEmpty()) {
1545 body->AddStatement(stat); 1555 body->AddStatement(stat);
1546 block_finder.Update(stat); 1556 block_finder.Update(stat);
1547 } 1557 }
1548 } 1558 }
1549 } 1559 }
1550 Expect(Token::RBRACE, CHECK_OK); 1560 Expect(Token::RBRACE, CHECK_OK);
1551 1561
1552 // Create exit block. 1562 // Create exit block.
1553 Block* exit = new(zone()) Block(isolate(), NULL, 1, false); 1563 Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
1554 exit->AddStatement(new(zone()) ExitContextStatement()); 1564 exit->AddStatement(new(zone()) ExitContextStatement());
1555 1565
1556 // Create a try-finally statement. 1566 // Create a try-finally statement.
1557 TryFinallyStatement* try_finally = 1567 TryFinallyStatement* try_finally =
1558 new(zone()) TryFinallyStatement(body, exit); 1568 new(zone()) TryFinallyStatement(body, exit);
1559 try_finally->set_escaping_targets(collector.targets()); 1569 try_finally->set_escaping_targets(collector.targets());
1560 top_scope_ = saved_scope; 1570 top_scope_ = saved_scope;
1561 1571
1562 // Create a result block. 1572 // Create a result block.
1563 Block* result = new(zone()) Block(isolate(), NULL, 1, false); 1573 Block* result = new(zone()) Block(isolate(), NULL, 1, false);
1564 result->AddStatement(try_finally); 1574 result->AddStatement(try_finally);
1565 return result; 1575 return result;
1566 } 1576 }
1567 1577
1568 1578
1569 Block* Parser::ParseVariableStatement(bool* ok) { 1579 Block* Parser::ParseVariableStatement(bool accept_LET, bool* ok) {
1570 // VariableStatement :: 1580 // VariableStatement ::
1571 // VariableDeclarations ';' 1581 // VariableDeclarations ';'
1572 1582
1573 Handle<String> ignore; 1583 Handle<String> ignore;
1574 Block* result = ParseVariableDeclarations(true, &ignore, CHECK_OK); 1584 Block* result = ParseVariableDeclarations(accept_LET, true,
1585 &ignore, CHECK_OK);
1575 ExpectSemicolon(CHECK_OK); 1586 ExpectSemicolon(CHECK_OK);
1576 return result; 1587 return result;
1577 } 1588 }
1578 1589
1579 1590
1580 bool Parser::IsEvalOrArguments(Handle<String> string) { 1591 bool Parser::IsEvalOrArguments(Handle<String> string) {
1581 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1592 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1582 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1593 string.is_identical_to(isolate()->factory()->arguments_symbol());
1583 } 1594 }
1584 1595
1585 1596
1586 // If the variable declaration declares exactly one non-const 1597 // If the variable declaration declares exactly one non-const
1587 // variable, then *var is set to that variable. In all other cases, 1598 // variable, then *var is set to that variable. In all other cases,
1588 // *var is untouched; in particular, it is the caller's responsibility 1599 // *var is untouched; in particular, it is the caller's responsibility
1589 // to initialize it properly. This mechanism is used for the parsing 1600 // to initialize it properly. This mechanism is used for the parsing
1590 // of 'for-in' loops. 1601 // of 'for-in' loops.
1591 Block* Parser::ParseVariableDeclarations(bool accept_IN, 1602 Block* Parser::ParseVariableDeclarations(bool accept_LET,
1603 bool accept_IN,
1592 Handle<String>* out, 1604 Handle<String>* out,
1593 bool* ok) { 1605 bool* ok) {
1594 // VariableDeclarations :: 1606 // VariableDeclarations ::
1595 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1607 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
1596 1608
1597 Variable::Mode mode = Variable::VAR; 1609 Variable::Mode mode = Variable::VAR;
1598 bool is_const = false; 1610 bool is_const = false;
1599 Scope* declaration_scope = top_scope_->DeclarationScope(); 1611 Scope* declaration_scope = top_scope_->DeclarationScope();
1600 if (peek() == Token::VAR) { 1612 if (peek() == Token::VAR) {
1601 Consume(Token::VAR); 1613 Consume(Token::VAR);
1602 } else if (peek() == Token::CONST) { 1614 } else if (peek() == Token::CONST) {
1603 Consume(Token::CONST); 1615 Consume(Token::CONST);
1604 if (declaration_scope->is_strict_mode()) { 1616 if (declaration_scope->is_strict_mode()) {
1605 ReportMessage("strict_const", Vector<const char*>::empty()); 1617 ReportMessage("strict_const", Vector<const char*>::empty());
1606 *ok = false; 1618 *ok = false;
1607 return NULL; 1619 return NULL;
1608 } 1620 }
1609 mode = Variable::CONST; 1621 mode = Variable::CONST;
1610 is_const = true; 1622 is_const = true;
1623 } else if (peek() == Token::LET) {
1624 Consume(Token::LET);
1625 if (!accept_LET) {
1626 ReportMessage("unprotected_let", Vector<const char*>::empty());
1627 *ok = false;
1628 return NULL;
1629 }
1630 mode = Variable::LET;
1611 } else { 1631 } else {
1612 UNREACHABLE(); // by current callers 1632 UNREACHABLE(); // by current callers
1613 } 1633 }
1614 1634
1615 // The scope of a variable/const declared anywhere inside a function 1635 // The scope of a variable/const declared anywhere inside a function
1616 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1636 // 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) 1637 // transform a source-level variable/const declaration into a (Function)
1618 // Scope declaration, and rewrite the source-level initialization into an 1638 // Scope declaration, and rewrite the source-level initialization into an
1619 // assignment statement. We use a block to collect multiple assignments. 1639 // assignment statement. We use a block to collect multiple assignments.
1620 // 1640 //
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2359 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2340 2360
2341 Statement* init = NULL; 2361 Statement* init = NULL;
2342 2362
2343 Expect(Token::FOR, CHECK_OK); 2363 Expect(Token::FOR, CHECK_OK);
2344 Expect(Token::LPAREN, CHECK_OK); 2364 Expect(Token::LPAREN, CHECK_OK);
2345 if (peek() != Token::SEMICOLON) { 2365 if (peek() != Token::SEMICOLON) {
2346 if (peek() == Token::VAR || peek() == Token::CONST) { 2366 if (peek() == Token::VAR || peek() == Token::CONST) {
2347 Handle<String> name; 2367 Handle<String> name;
2348 Block* variable_statement = 2368 Block* variable_statement =
2349 ParseVariableDeclarations(false, &name, CHECK_OK); 2369 ParseVariableDeclarations(true, false, &name, CHECK_OK);
2350 2370
2351 if (peek() == Token::IN && !name.is_null()) { 2371 if (peek() == Token::IN && !name.is_null()) {
2352 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); 2372 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
2353 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); 2373 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
2354 Target target(&this->target_stack_, loop); 2374 Target target(&this->target_stack_, loop);
2355 2375
2356 Expect(Token::IN, CHECK_OK); 2376 Expect(Token::IN, CHECK_OK);
2357 Expression* enumerable = ParseExpression(true, CHECK_OK); 2377 Expression* enumerable = ParseExpression(true, CHECK_OK);
2358 Expect(Token::RPAREN, CHECK_OK); 2378 Expect(Token::RPAREN, CHECK_OK);
2359 2379
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 Vector<const char*>::empty()); 3006 Vector<const char*>::empty());
2987 case Token::STRING: 3007 case Token::STRING:
2988 return ReportMessage("unexpected_token_string", 3008 return ReportMessage("unexpected_token_string",
2989 Vector<const char*>::empty()); 3009 Vector<const char*>::empty());
2990 case Token::IDENTIFIER: 3010 case Token::IDENTIFIER:
2991 return ReportMessage("unexpected_token_identifier", 3011 return ReportMessage("unexpected_token_identifier",
2992 Vector<const char*>::empty()); 3012 Vector<const char*>::empty());
2993 case Token::FUTURE_RESERVED_WORD: 3013 case Token::FUTURE_RESERVED_WORD:
2994 return ReportMessage("unexpected_reserved", 3014 return ReportMessage("unexpected_reserved",
2995 Vector<const char*>::empty()); 3015 Vector<const char*>::empty());
3016 case Token::LET:
3017 if (harmony_block_scoping_) {
3018 const char* name = Token::String(token);
3019 ASSERT(name != NULL);
3020 return ReportMessage("unexpected_token",
3021 Vector<const char*>(&name, 1));
3022 }
3023 // FALLTHROUGH
2996 case Token::FUTURE_STRICT_RESERVED_WORD: 3024 case Token::FUTURE_STRICT_RESERVED_WORD:
2997 return ReportMessage(top_scope_->is_strict_mode() ? 3025 return ReportMessage(top_scope_->is_strict_mode() ?
2998 "unexpected_strict_reserved" : 3026 "unexpected_strict_reserved" :
2999 "unexpected_token_identifier", 3027 "unexpected_token_identifier",
3000 Vector<const char*>::empty()); 3028 Vector<const char*>::empty());
3001 default: 3029 default:
3002 const char* name = Token::String(token); 3030 const char* name = Token::String(token);
3003 ASSERT(name != NULL); 3031 ASSERT(name != NULL);
3004 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 3032 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
3005 } 3033 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 result = new(zone()) Literal( 3076 result = new(zone()) Literal(
3049 isolate(), isolate()->factory()->true_value()); 3077 isolate(), isolate()->factory()->true_value());
3050 break; 3078 break;
3051 3079
3052 case Token::FALSE_LITERAL: 3080 case Token::FALSE_LITERAL:
3053 Consume(Token::FALSE_LITERAL); 3081 Consume(Token::FALSE_LITERAL);
3054 result = new(zone()) Literal( 3082 result = new(zone()) Literal(
3055 isolate(), isolate()->factory()->false_value()); 3083 isolate(), isolate()->factory()->false_value());
3056 break; 3084 break;
3057 3085
3086 case Token::LET:
3087 if (harmony_block_scoping_) {
3088 Token::Value tok = Next();
3089 ReportUnexpectedToken(tok);
3090 *ok = false;
3091 return NULL;
3092 }
3093 // FALLTHROUGH
3058 case Token::IDENTIFIER: 3094 case Token::IDENTIFIER:
3059 case Token::FUTURE_STRICT_RESERVED_WORD: { 3095 case Token::FUTURE_STRICT_RESERVED_WORD: {
3060 Handle<String> name = ParseIdentifier(CHECK_OK); 3096 Handle<String> name = ParseIdentifier(CHECK_OK);
3061 if (fni_ != NULL) fni_->PushVariableName(name); 3097 if (fni_ != NULL) fni_->PushVariableName(name);
3062 result = top_scope_->NewUnresolved(name, 3098 result = top_scope_->NewUnresolved(name,
3063 inside_with(), 3099 inside_with(),
3064 scanner().location().beg_pos); 3100 scanner().location().beg_pos);
3065 break; 3101 break;
3066 } 3102 }
3067 3103
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 3548
3513 while (peek() != Token::RBRACE) { 3549 while (peek() != Token::RBRACE) {
3514 if (fni_ != NULL) fni_->Enter(); 3550 if (fni_ != NULL) fni_->Enter();
3515 3551
3516 Literal* key = NULL; 3552 Literal* key = NULL;
3517 Token::Value next = peek(); 3553 Token::Value next = peek();
3518 3554
3519 // Location of the property name token 3555 // Location of the property name token
3520 Scanner::Location loc = scanner().peek_location(); 3556 Scanner::Location loc = scanner().peek_location();
3521 3557
3558 if (harmony_block_scoping_ && next == Token::LET) {
3559 // Go into FUTURE_STRICT_RESERVED_WORD case where
3560 // ParseIdentifierNameOrGetOrSet will handle the LET
3561 // token like a FUTURE_STRICT_RESERVED_WORD.
3562 next = Token::FUTURE_STRICT_RESERVED_WORD;
Lasse Reichstein 2011/08/12 08:08:33 Why not just add a case for Token::LET next to Tok
Steven 2011/08/16 09:05:32 Now obsolete, since the scanner now produces the c
3563 }
3522 switch (next) { 3564 switch (next) {
3523 case Token::FUTURE_RESERVED_WORD: 3565 case Token::FUTURE_RESERVED_WORD:
3524 case Token::FUTURE_STRICT_RESERVED_WORD: 3566 case Token::FUTURE_STRICT_RESERVED_WORD:
3525 case Token::IDENTIFIER: { 3567 case Token::IDENTIFIER: {
3526 bool is_getter = false; 3568 bool is_getter = false;
3527 bool is_setter = false; 3569 bool is_setter = false;
3528 Handle<String> id = 3570 Handle<String> id =
3529 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3571 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3530 if (fni_ != NULL) fni_->PushLiteralName(id); 3572 if (fni_ != NULL) fni_->PushLiteralName(id);
3531 3573
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3699 // handle to decide whether to invoke function name inference. 3741 // handle to decide whether to invoke function name inference.
3700 bool should_infer_name = function_name.is_null(); 3742 bool should_infer_name = function_name.is_null();
3701 3743
3702 // We want a non-null handle as the function name. 3744 // We want a non-null handle as the function name.
3703 if (should_infer_name) { 3745 if (should_infer_name) {
3704 function_name = isolate()->factory()->empty_symbol(); 3746 function_name = isolate()->factory()->empty_symbol();
3705 } 3747 }
3706 3748
3707 int num_parameters = 0; 3749 int num_parameters = 0;
3708 // Function declarations are hoisted. 3750 // Function declarations are hoisted.
3709 Scope* scope = (type == FunctionLiteral::DECLARATION) 3751 Scope* scope = (type == FunctionLiteral::DECLARATION &&
3752 !harmony_block_scoping_)
Lasse Reichstein 2011/08/12 08:08:33 If harmony_block_scoping_ is set, function declara
Steven 2011/08/16 09:05:32 Yes, function declarations are then also expected
3710 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) 3753 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
3711 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3754 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3712 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); 3755 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
3713 int materialized_literal_count; 3756 int materialized_literal_count;
3714 int expected_property_count; 3757 int expected_property_count;
3715 int start_pos; 3758 int start_pos;
3716 int end_pos; 3759 int end_pos;
3717 bool only_simple_this_property_assignments; 3760 bool only_simple_this_property_assignments;
3718 Handle<FixedArray> this_property_assignments; 3761 Handle<FixedArray> this_property_assignments;
3719 bool has_duplicate_parameters = false; 3762 bool has_duplicate_parameters = false;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
3939 3982
3940 // We have a valid intrinsics call or a call to a builtin. 3983 // We have a valid intrinsics call or a call to a builtin.
3941 return new(zone()) CallRuntime(isolate(), name, function, args); 3984 return new(zone()) CallRuntime(isolate(), name, function, args);
3942 } 3985 }
3943 3986
3944 3987
3945 bool Parser::peek_any_identifier() { 3988 bool Parser::peek_any_identifier() {
3946 Token::Value next = peek(); 3989 Token::Value next = peek();
3947 return next == Token::IDENTIFIER || 3990 return next == Token::IDENTIFIER ||
3948 next == Token::FUTURE_RESERVED_WORD || 3991 next == Token::FUTURE_RESERVED_WORD ||
3949 next == Token::FUTURE_STRICT_RESERVED_WORD; 3992 next == Token::FUTURE_STRICT_RESERVED_WORD ||
3993 (next == Token::LET && !harmony_block_scoping_);
3950 } 3994 }
3951 3995
3952 3996
3953 void Parser::Consume(Token::Value token) { 3997 void Parser::Consume(Token::Value token) {
3954 Token::Value next = Next(); 3998 Token::Value next = Next();
3955 USE(next); 3999 USE(next);
3956 USE(token); 4000 USE(token);
3957 ASSERT(next == token); 4001 ASSERT(next == token);
3958 } 4002 }
3959 4003
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 Literal* Parser::GetLiteralTheHole() { 4045 Literal* Parser::GetLiteralTheHole() {
4002 return NewLiteral(isolate()->factory()->the_hole_value()); 4046 return NewLiteral(isolate()->factory()->the_hole_value());
4003 } 4047 }
4004 4048
4005 4049
4006 Literal* Parser::GetLiteralNumber(double value) { 4050 Literal* Parser::GetLiteralNumber(double value) {
4007 return NewNumberLiteral(value); 4051 return NewNumberLiteral(value);
4008 } 4052 }
4009 4053
4010 4054
4011 // Parses and identifier that is valid for the current scope, in particular it 4055 // Parses and identifier that is valid for the current scope, in particular it
Lasse Reichstein 2011/08/12 08:08:33 "and"->"an" while you are here :)
Steven 2011/08/16 09:05:32 Done.
4012 // fails on strict mode future reserved keywords in a strict scope. 4056 // fails on strict mode future reserved keywords in a strict scope.
4013 Handle<String> Parser::ParseIdentifier(bool* ok) { 4057 Handle<String> Parser::ParseIdentifier(bool* ok) {
4014 if (top_scope_->is_strict_mode()) { 4058 if (top_scope_->is_strict_mode()) {
4015 Expect(Token::IDENTIFIER, ok); 4059 Expect(Token::IDENTIFIER, ok);
4016 } else if (!Check(Token::IDENTIFIER)) { 4060 } else if (!Check(Token::IDENTIFIER)) {
4017 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 4061 if (harmony_block_scoping_) {
4062 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4063 } else if (!Check(Token::FUTURE_STRICT_RESERVED_WORD)) {
4064 Expect(Token::LET, ok);
4065 }
4018 } 4066 }
4019 if (!*ok) return Handle<String>(); 4067 if (!*ok) return Handle<String>();
4020 return GetSymbol(ok); 4068 return GetSymbol(ok);
4021 } 4069 }
4022 4070
4023 4071
4024 // Parses and identifier or a strict mode future reserved word, and indicate 4072 // Parses and identifier or a strict mode future reserved word, and indicate
4025 // whether it is strict mode future reserved. 4073 // whether it is strict mode future reserved.
4026 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( 4074 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4027 bool* is_strict_reserved, bool* ok) { 4075 bool* is_strict_reserved, bool* ok) {
4028 *is_strict_reserved = false; 4076 *is_strict_reserved = false;
4029 if (!Check(Token::IDENTIFIER)) { 4077 if (!Check(Token::IDENTIFIER)) {
4030 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 4078 if (harmony_block_scoping_) {
4079 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4080 } else if (!Check(Token::FUTURE_STRICT_RESERVED_WORD)) {
4081 Expect(Token::LET, ok);
4082 }
4031 *is_strict_reserved = true; 4083 *is_strict_reserved = true;
4032 } 4084 }
4033 if (!*ok) return Handle<String>(); 4085 if (!*ok) return Handle<String>();
4034 return GetSymbol(ok); 4086 return GetSymbol(ok);
4035 } 4087 }
4036 4088
4037 4089
4038 Handle<String> Parser::ParseIdentifierName(bool* ok) { 4090 Handle<String> Parser::ParseIdentifierName(bool* ok) {
4039 Token::Value next = Next(); 4091 Token::Value next = Next();
4040 if (next != Token::IDENTIFIER && 4092 if (next != Token::IDENTIFIER &&
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5188 result = parser.ParseProgram(source, 5240 result = parser.ParseProgram(source,
5189 info->is_global(), 5241 info->is_global(),
5190 info->StrictMode()); 5242 info->StrictMode());
5191 } 5243 }
5192 } 5244 }
5193 info->SetFunction(result); 5245 info->SetFunction(result);
5194 return (result != NULL); 5246 return (result != NULL);
5195 } 5247 }
5196 5248
5197 } } // namespace v8::internal 5249 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698