| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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()); |
| 5076 scanner.SetHarmonyBlockScoping(harmony_block_scoping); |
| 5047 scanner.Initialize(source); | 5077 scanner.Initialize(source); |
| 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 |
| OLD | NEW |