| 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 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "ast-inl.h" | 31 #include "ast-inl.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "char-predicates-inl.h" |
| 33 #include "codegen.h" | 34 #include "codegen.h" |
| 34 #include "compiler.h" | 35 #include "compiler.h" |
| 35 #include "func-name-inferrer.h" | 36 #include "func-name-inferrer.h" |
| 36 #include "messages.h" | 37 #include "messages.h" |
| 37 #include "parser.h" | 38 #include "parser.h" |
| 38 #include "platform.h" | 39 #include "platform.h" |
| 39 #include "preparser.h" | 40 #include "preparser.h" |
| 40 #include "runtime.h" | 41 #include "runtime.h" |
| 41 #include "scopeinfo.h" | 42 #include "scopeinfo.h" |
| 42 #include "string-stream.h" | 43 #include "string-stream.h" |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 only_simple_this_property_assignments_(false), | 526 only_simple_this_property_assignments_(false), |
| 526 this_property_assignments_(isolate->factory()->empty_fixed_array()), | 527 this_property_assignments_(isolate->factory()->empty_fixed_array()), |
| 527 parser_(parser), | 528 parser_(parser), |
| 528 lexical_scope_parent_(parser->lexical_scope_), | 529 lexical_scope_parent_(parser->lexical_scope_), |
| 529 previous_scope_(parser->top_scope_), | 530 previous_scope_(parser->top_scope_), |
| 530 previous_with_nesting_level_(parser->with_nesting_level_), | 531 previous_with_nesting_level_(parser->with_nesting_level_), |
| 531 previous_ast_node_id_(isolate->ast_node_id()) { | 532 previous_ast_node_id_(isolate->ast_node_id()) { |
| 532 parser->top_scope_ = scope; | 533 parser->top_scope_ = scope; |
| 533 parser->lexical_scope_ = this; | 534 parser->lexical_scope_ = this; |
| 534 parser->with_nesting_level_ = 0; | 535 parser->with_nesting_level_ = 0; |
| 535 isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1); | 536 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
| 536 } | 537 } |
| 537 | 538 |
| 538 | 539 |
| 539 LexicalScope::~LexicalScope() { | 540 LexicalScope::~LexicalScope() { |
| 540 parser_->top_scope_ = previous_scope_; | 541 parser_->top_scope_ = previous_scope_; |
| 541 parser_->lexical_scope_ = lexical_scope_parent_; | 542 parser_->lexical_scope_ = lexical_scope_parent_; |
| 542 parser_->with_nesting_level_ = previous_with_nesting_level_; | 543 parser_->with_nesting_level_ = previous_with_nesting_level_; |
| 543 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); | 544 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); |
| 544 } | 545 } |
| 545 | 546 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 if (strict_mode == kStrictMode) { | 641 if (strict_mode == kStrictMode) { |
| 641 top_scope_->EnableStrictMode(); | 642 top_scope_->EnableStrictMode(); |
| 642 } | 643 } |
| 643 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 644 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 644 bool ok = true; | 645 bool ok = true; |
| 645 int beg_loc = scanner().location().beg_pos; | 646 int beg_loc = scanner().location().beg_pos; |
| 646 ParseSourceElements(body, Token::EOS, &ok); | 647 ParseSourceElements(body, Token::EOS, &ok); |
| 647 if (ok && top_scope_->is_strict_mode()) { | 648 if (ok && top_scope_->is_strict_mode()) { |
| 648 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 649 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 649 } | 650 } |
| 651 |
| 652 if (ok && harmony_block_scoping_) { |
| 653 CheckConflictingVarDeclarations(scope, &ok); |
| 654 } |
| 655 |
| 650 if (ok) { | 656 if (ok) { |
| 651 result = new(zone()) FunctionLiteral( | 657 result = new(zone()) FunctionLiteral( |
| 652 isolate(), | 658 isolate(), |
| 653 no_name, | 659 no_name, |
| 654 top_scope_, | 660 top_scope_, |
| 655 body, | 661 body, |
| 656 lexical_scope.materialized_literal_count(), | 662 lexical_scope.materialized_literal_count(), |
| 657 lexical_scope.expected_property_count(), | 663 lexical_scope.expected_property_count(), |
| 658 lexical_scope.only_simple_this_property_assignments(), | 664 lexical_scope.only_simple_this_property_assignments(), |
| 659 lexical_scope.this_property_assignments(), | 665 lexical_scope.this_property_assignments(), |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 : top_scope_->DeclarationScope(); | 1342 : top_scope_->DeclarationScope(); |
| 1337 if (declaration_scope->is_function_scope() || | 1343 if (declaration_scope->is_function_scope() || |
| 1338 declaration_scope->is_strict_mode_eval_scope() || | 1344 declaration_scope->is_strict_mode_eval_scope() || |
| 1339 declaration_scope->is_block_scope()) { | 1345 declaration_scope->is_block_scope()) { |
| 1340 // Declare the variable in the function scope. | 1346 // Declare the variable in the function scope. |
| 1341 var = declaration_scope->LocalLookup(name); | 1347 var = declaration_scope->LocalLookup(name); |
| 1342 if (var == NULL) { | 1348 if (var == NULL) { |
| 1343 // Declare the name. | 1349 // Declare the name. |
| 1344 var = declaration_scope->DeclareLocal(name, mode); | 1350 var = declaration_scope->DeclareLocal(name, mode); |
| 1345 } else { | 1351 } else { |
| 1346 // The name was declared before; check for conflicting re-declarations. | 1352 // The name was declared in this scope before; check for conflicting |
| 1347 // We have a conflict if either of the declarations is not a var. There | 1353 // re-declarations. We have a conflict if either of the declarations is |
| 1348 // is similar code in runtime.cc in the Declare functions. | 1354 // not a var. There is similar code in runtime.cc in the Declare |
| 1355 // functions. The function CheckNonConflictingScope checks for conflicting |
| 1356 // var and let bindings from different scopes whereas this is a check for |
| 1357 // conflicting declarations within the same scope. This check also covers |
| 1358 // |
| 1359 // function () { let x; { var x; } } |
| 1360 // |
| 1361 // because the var declaration is hoisted to the function scope where 'x' |
| 1362 // is already bound. |
| 1349 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { | 1363 if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) { |
| 1350 // We only have vars, consts and lets in declarations. | 1364 // We only have vars, consts and lets in declarations. |
| 1351 ASSERT(var->mode() == Variable::VAR || | 1365 ASSERT(var->mode() == Variable::VAR || |
| 1352 var->mode() == Variable::CONST || | 1366 var->mode() == Variable::CONST || |
| 1353 var->mode() == Variable::LET); | 1367 var->mode() == Variable::LET); |
| 1368 if (harmony_block_scoping_) { |
| 1369 // In harmony mode we treat re-declarations as early errors. See |
| 1370 // ES5 16 for a definition of early errors. |
| 1371 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1372 const char* elms[2] = { "Variable", *c_string }; |
| 1373 Vector<const char*> args(elms, 2); |
| 1374 ReportMessage("redeclaration", args); |
| 1375 *ok = false; |
| 1376 return NULL; |
| 1377 } |
| 1354 const char* type = (var->mode() == Variable::VAR) ? "var" : | 1378 const char* type = (var->mode() == Variable::VAR) ? "var" : |
| 1355 (var->mode() == Variable::CONST) ? "const" : "let"; | 1379 (var->mode() == Variable::CONST) ? "const" : "let"; |
| 1356 Handle<String> type_string = | 1380 Handle<String> type_string = |
| 1357 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | 1381 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); |
| 1358 Expression* expression = | 1382 Expression* expression = |
| 1359 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | 1383 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), |
| 1360 type_string, name); | 1384 type_string, name); |
| 1361 declaration_scope->SetIllegalRedeclaration(expression); | 1385 declaration_scope->SetIllegalRedeclaration(expression); |
| 1362 } | 1386 } |
| 1363 } | 1387 } |
| 1364 } | 1388 } |
| 1365 | 1389 |
| 1366 // We add a declaration node for every declaration. The compiler | 1390 // We add a declaration node for every declaration. The compiler |
| 1367 // will only generate code if necessary. In particular, declarations | 1391 // will only generate code if necessary. In particular, declarations |
| 1368 // for inner local variables that do not represent functions won't | 1392 // for inner local variables that do not represent functions won't |
| 1369 // result in any generated code. | 1393 // result in any generated code. |
| 1370 // | 1394 // |
| 1371 // Note that we always add an unresolved proxy even if it's not | 1395 // Note that we always add an unresolved proxy even if it's not |
| 1372 // used, simply because we don't know in this method (w/o extra | 1396 // used, simply because we don't know in this method (w/o extra |
| 1373 // parameters) if the proxy is needed or not. The proxy will be | 1397 // parameters) if the proxy is needed or not. The proxy will be |
| 1374 // bound during variable resolution time unless it was pre-bound | 1398 // bound during variable resolution time unless it was pre-bound |
| 1375 // below. | 1399 // below. |
| 1376 // | 1400 // |
| 1377 // WARNING: This will lead to multiple declaration nodes for the | 1401 // WARNING: This will lead to multiple declaration nodes for the |
| 1378 // same variable if it is declared several times. This is not a | 1402 // same variable if it is declared several times. This is not a |
| 1379 // semantic issue as long as we keep the source order, but it may be | 1403 // semantic issue as long as we keep the source order, but it may be |
| 1380 // a performance issue since it may lead to repeated | 1404 // a performance issue since it may lead to repeated |
| 1381 // Runtime::DeclareContextSlot() calls. | 1405 // Runtime::DeclareContextSlot() calls. |
| 1382 VariableProxy* proxy = declaration_scope->NewUnresolved(name, false); | 1406 VariableProxy* proxy = declaration_scope->NewUnresolved( |
| 1383 declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); | 1407 name, false, scanner().location().beg_pos); |
| 1408 declaration_scope->AddDeclaration( |
| 1409 new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
| 1384 | 1410 |
| 1385 // For global const variables we bind the proxy to a variable. | 1411 // For global const variables we bind the proxy to a variable. |
| 1386 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { | 1412 if (mode == Variable::CONST && declaration_scope->is_global_scope()) { |
| 1387 ASSERT(resolve); // should be set by all callers | 1413 ASSERT(resolve); // should be set by all callers |
| 1388 Variable::Kind kind = Variable::NORMAL; | 1414 Variable::Kind kind = Variable::NORMAL; |
| 1389 var = new(zone()) Variable(declaration_scope, | 1415 var = new(zone()) Variable(declaration_scope, |
| 1390 name, | 1416 name, |
| 1391 Variable::CONST, | 1417 Variable::CONST, |
| 1392 true, | 1418 true, |
| 1393 kind); | 1419 kind); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 } | 1553 } |
| 1528 | 1554 |
| 1529 | 1555 |
| 1530 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1556 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1531 // Construct block expecting 16 statements. | 1557 // Construct block expecting 16 statements. |
| 1532 Block* body = new(zone()) Block(isolate(), labels, 16, false); | 1558 Block* body = new(zone()) Block(isolate(), labels, 16, false); |
| 1533 Scope* saved_scope = top_scope_; | 1559 Scope* saved_scope = top_scope_; |
| 1534 Scope* block_scope = NewScope(top_scope_, | 1560 Scope* block_scope = NewScope(top_scope_, |
| 1535 Scope::BLOCK_SCOPE, | 1561 Scope::BLOCK_SCOPE, |
| 1536 inside_with()); | 1562 inside_with()); |
| 1537 body->set_block_scope(block_scope); | |
| 1538 block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(), | |
| 1539 Variable::VAR); | |
| 1540 if (top_scope_->is_strict_mode()) { | 1563 if (top_scope_->is_strict_mode()) { |
| 1541 block_scope->EnableStrictMode(); | 1564 block_scope->EnableStrictMode(); |
| 1542 } | 1565 } |
| 1543 top_scope_ = block_scope; | 1566 top_scope_ = block_scope; |
| 1544 | 1567 |
| 1545 // Parse the statements and collect escaping labels. | 1568 // Parse the statements and collect escaping labels. |
| 1546 TargetCollector collector; | 1569 TargetCollector collector; |
| 1547 Target target(&this->target_stack_, &collector); | 1570 Target target(&this->target_stack_, &collector); |
| 1548 Expect(Token::LBRACE, CHECK_OK); | 1571 Expect(Token::LBRACE, CHECK_OK); |
| 1549 { | 1572 { |
| 1550 Target target_body(&this->target_stack_, body); | 1573 Target target_body(&this->target_stack_, body); |
| 1551 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1574 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1552 | 1575 |
| 1553 while (peek() != Token::RBRACE) { | 1576 while (peek() != Token::RBRACE) { |
| 1554 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1577 Statement* stat = ParseSourceElement(NULL, CHECK_OK); |
| 1555 if (stat && !stat->IsEmpty()) { | 1578 if (stat && !stat->IsEmpty()) { |
| 1556 body->AddStatement(stat); | 1579 body->AddStatement(stat); |
| 1557 block_finder.Update(stat); | 1580 block_finder.Update(stat); |
| 1558 } | 1581 } |
| 1559 } | 1582 } |
| 1560 } | 1583 } |
| 1561 Expect(Token::RBRACE, CHECK_OK); | 1584 Expect(Token::RBRACE, CHECK_OK); |
| 1562 | |
| 1563 // Create exit block. | |
| 1564 Block* exit = new(zone()) Block(isolate(), NULL, 1, false); | |
| 1565 exit->AddStatement(new(zone()) ExitContextStatement()); | |
| 1566 | |
| 1567 // Create a try-finally statement. | |
| 1568 TryFinallyStatement* try_finally = | |
| 1569 new(zone()) TryFinallyStatement(body, exit); | |
| 1570 try_finally->set_escaping_targets(collector.targets()); | |
| 1571 top_scope_ = saved_scope; | 1585 top_scope_ = saved_scope; |
| 1572 | 1586 |
| 1573 // Create a result block. | 1587 block_scope = block_scope->FinalizeBlockScope(); |
| 1574 Block* result = new(zone()) Block(isolate(), NULL, 1, false); | 1588 body->set_block_scope(block_scope); |
| 1575 result->AddStatement(try_finally); | 1589 return body; |
| 1576 return result; | |
| 1577 } | 1590 } |
| 1578 | 1591 |
| 1579 | 1592 |
| 1580 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1593 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1581 bool* ok) { | 1594 bool* ok) { |
| 1582 // VariableStatement :: | 1595 // VariableStatement :: |
| 1583 // VariableDeclarations ';' | 1596 // VariableDeclarations ';' |
| 1584 | 1597 |
| 1585 Handle<String> ignore; | 1598 Handle<String> ignore; |
| 1586 Block* result = ParseVariableDeclarations(var_context, | 1599 Block* result = ParseVariableDeclarations(var_context, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1602 // *var is untouched; in particular, it is the caller's responsibility | 1615 // *var is untouched; in particular, it is the caller's responsibility |
| 1603 // to initialize it properly. This mechanism is used for the parsing | 1616 // to initialize it properly. This mechanism is used for the parsing |
| 1604 // of 'for-in' loops. | 1617 // of 'for-in' loops. |
| 1605 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, | 1618 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, |
| 1606 Handle<String>* out, | 1619 Handle<String>* out, |
| 1607 bool* ok) { | 1620 bool* ok) { |
| 1608 // VariableDeclarations :: | 1621 // VariableDeclarations :: |
| 1609 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1622 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1610 | 1623 |
| 1611 Variable::Mode mode = Variable::VAR; | 1624 Variable::Mode mode = Variable::VAR; |
| 1625 // True if the binding needs initialization. 'let' and 'const' declared |
| 1626 // bindings are created uninitialized by their declaration nodes and |
| 1627 // need initialization. 'var' declared bindings are always initialized |
| 1628 // immediately by their declaration nodes. |
| 1629 bool needs_init = false; |
| 1612 bool is_const = false; | 1630 bool is_const = false; |
| 1631 Token::Value init_op = Token::INIT_VAR; |
| 1613 if (peek() == Token::VAR) { | 1632 if (peek() == Token::VAR) { |
| 1614 Consume(Token::VAR); | 1633 Consume(Token::VAR); |
| 1615 } else if (peek() == Token::CONST) { | 1634 } else if (peek() == Token::CONST) { |
| 1616 Consume(Token::CONST); | 1635 Consume(Token::CONST); |
| 1617 if (top_scope_->is_strict_mode()) { | 1636 if (top_scope_->is_strict_mode()) { |
| 1618 ReportMessage("strict_const", Vector<const char*>::empty()); | 1637 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1619 *ok = false; | 1638 *ok = false; |
| 1620 return NULL; | 1639 return NULL; |
| 1621 } | 1640 } |
| 1622 mode = Variable::CONST; | 1641 mode = Variable::CONST; |
| 1623 is_const = true; | 1642 is_const = true; |
| 1643 needs_init = true; |
| 1644 init_op = Token::INIT_CONST; |
| 1624 } else if (peek() == Token::LET) { | 1645 } else if (peek() == Token::LET) { |
| 1625 Consume(Token::LET); | 1646 Consume(Token::LET); |
| 1626 if (var_context != kSourceElement && | 1647 if (var_context != kSourceElement && |
| 1627 var_context != kForStatement) { | 1648 var_context != kForStatement) { |
| 1628 ASSERT(var_context == kStatement); | 1649 ASSERT(var_context == kStatement); |
| 1629 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1650 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
| 1630 *ok = false; | 1651 *ok = false; |
| 1631 return NULL; | 1652 return NULL; |
| 1632 } | 1653 } |
| 1633 mode = Variable::LET; | 1654 mode = Variable::LET; |
| 1655 needs_init = true; |
| 1656 init_op = Token::INIT_LET; |
| 1634 } else { | 1657 } else { |
| 1635 UNREACHABLE(); // by current callers | 1658 UNREACHABLE(); // by current callers |
| 1636 } | 1659 } |
| 1637 | 1660 |
| 1638 Scope* declaration_scope = mode == Variable::LET | 1661 Scope* declaration_scope = mode == Variable::LET |
| 1639 ? top_scope_ : top_scope_->DeclarationScope(); | 1662 ? top_scope_ : top_scope_->DeclarationScope(); |
| 1640 // The scope of a var/const declared variable anywhere inside a function | 1663 // The scope of a var/const declared variable anywhere inside a function |
| 1641 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 1664 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 1642 // transform a source-level var/const declaration into a (Function) | 1665 // transform a source-level var/const declaration into a (Function) |
| 1643 // Scope declaration, and rewrite the source-level initialization into an | 1666 // Scope declaration, and rewrite the source-level initialization into an |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1725 position = scanner().location().beg_pos; | 1748 position = scanner().location().beg_pos; |
| 1726 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1749 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1727 // Don't infer if it is "a = function(){...}();"-like expression. | 1750 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1728 if (fni_ != NULL && | 1751 if (fni_ != NULL && |
| 1729 value->AsCall() == NULL && | 1752 value->AsCall() == NULL && |
| 1730 value->AsCallNew() == NULL) { | 1753 value->AsCallNew() == NULL) { |
| 1731 fni_->Infer(); | 1754 fni_->Infer(); |
| 1732 } | 1755 } |
| 1733 } | 1756 } |
| 1734 | 1757 |
| 1735 // Make sure that 'const c' actually initializes 'c' to undefined | 1758 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 1736 // even though it seems like a stupid thing to do. | 1759 if (value == NULL && needs_init) { |
| 1737 if (value == NULL && is_const) { | |
| 1738 value = GetLiteralUndefined(); | 1760 value = GetLiteralUndefined(); |
| 1739 } | 1761 } |
| 1740 | 1762 |
| 1741 // Global variable declarations must be compiled in a specific | 1763 // Global variable declarations must be compiled in a specific |
| 1742 // way. When the script containing the global variable declaration | 1764 // way. When the script containing the global variable declaration |
| 1743 // is entered, the global variable must be declared, so that if it | 1765 // is entered, the global variable must be declared, so that if it |
| 1744 // doesn't exist (not even in a prototype of the global object) it | 1766 // doesn't exist (not even in a prototype of the global object) it |
| 1745 // gets created with an initial undefined value. This is handled | 1767 // gets created with an initial undefined value. This is handled |
| 1746 // by the declarations part of the function representing the | 1768 // by the declarations part of the function representing the |
| 1747 // top-level global code; see Runtime::DeclareGlobalVariable. If | 1769 // top-level global code; see Runtime::DeclareGlobalVariable. If |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1804 new(zone()) CallRuntime( | 1826 new(zone()) CallRuntime( |
| 1805 isolate(), | 1827 isolate(), |
| 1806 isolate()->factory()->InitializeVarGlobal_symbol(), | 1828 isolate()->factory()->InitializeVarGlobal_symbol(), |
| 1807 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 1829 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 1808 arguments); | 1830 arguments); |
| 1809 } | 1831 } |
| 1810 | 1832 |
| 1811 block->AddStatement(new(zone()) ExpressionStatement(initialize)); | 1833 block->AddStatement(new(zone()) ExpressionStatement(initialize)); |
| 1812 } | 1834 } |
| 1813 | 1835 |
| 1814 // Add an assignment node to the initialization statement block if | 1836 // Add an assignment node to the initialization statement block if we still |
| 1815 // we still have a pending initialization value. We must distinguish | 1837 // have a pending initialization value. We must distinguish between |
| 1816 // between variables and constants: Variable initializations are simply | 1838 // different kinds of declarations: 'var' initializations are simply |
| 1817 // assignments (with all the consequences if they are inside a 'with' | 1839 // assignments (with all the consequences if they are inside a 'with' |
| 1818 // statement - they may change a 'with' object property). Constant | 1840 // statement - they may change a 'with' object property). Constant |
| 1819 // initializations always assign to the declared constant which is | 1841 // initializations always assign to the declared constant which is |
| 1820 // always at the function scope level. This is only relevant for | 1842 // always at the function scope level. This is only relevant for |
| 1821 // dynamically looked-up variables and constants (the start context | 1843 // dynamically looked-up variables and constants (the start context |
| 1822 // for constant lookups is always the function context, while it is | 1844 // for constant lookups is always the function context, while it is |
| 1823 // the top context for variables). Sigh... | 1845 // the top context for var declared variables). Sigh... |
| 1846 // For 'let' declared variables the initialization is in the same scope |
| 1847 // as the declaration. Thus dynamic lookups are unnecessary even if the |
| 1848 // block scope is inside a with. |
| 1824 if (value != NULL) { | 1849 if (value != NULL) { |
| 1825 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); | 1850 bool in_with = mode == Variable::VAR ? inside_with() : false; |
| 1826 bool in_with = is_const ? false : inside_with(); | |
| 1827 VariableProxy* proxy = | 1851 VariableProxy* proxy = |
| 1828 initialization_scope->NewUnresolved(name, in_with); | 1852 initialization_scope->NewUnresolved(name, in_with); |
| 1829 Assignment* assignment = | 1853 Assignment* assignment = |
| 1830 new(zone()) Assignment(isolate(), op, proxy, value, position); | 1854 new(zone()) Assignment(isolate(), init_op, proxy, value, position); |
| 1831 if (block) { | 1855 if (block) { |
| 1832 block->AddStatement(new(zone()) ExpressionStatement(assignment)); | 1856 block->AddStatement(new(zone()) ExpressionStatement(assignment)); |
| 1833 } | 1857 } |
| 1834 } | 1858 } |
| 1835 | 1859 |
| 1836 if (fni_ != NULL) fni_->Leave(); | 1860 if (fni_ != NULL) fni_->Leave(); |
| 1837 } while (peek() == Token::COMMA); | 1861 } while (peek() == Token::COMMA); |
| 1838 | 1862 |
| 1839 // If there was a single non-const declaration, return it in the output | 1863 // If there was a single non-const declaration, return it in the output |
| 1840 // parameter for possible use by for/in. | 1864 // parameter for possible use by for/in. |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2185 | 2209 |
| 2186 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { | 2210 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2187 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2211 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2188 *ok = false; | 2212 *ok = false; |
| 2189 return NULL; | 2213 return NULL; |
| 2190 } | 2214 } |
| 2191 | 2215 |
| 2192 Expect(Token::RPAREN, CHECK_OK); | 2216 Expect(Token::RPAREN, CHECK_OK); |
| 2193 | 2217 |
| 2194 if (peek() == Token::LBRACE) { | 2218 if (peek() == Token::LBRACE) { |
| 2195 // Rewrite the catch body { B } to a block: | |
| 2196 // { { B } ExitContext; }. | |
| 2197 Target target(&this->target_stack_, &catch_collector); | 2219 Target target(&this->target_stack_, &catch_collector); |
| 2198 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | 2220 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
| 2199 if (top_scope_->is_strict_mode()) { | 2221 if (top_scope_->is_strict_mode()) { |
| 2200 catch_scope->EnableStrictMode(); | 2222 catch_scope->EnableStrictMode(); |
| 2201 } | 2223 } |
| 2202 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR); | 2224 Variable::Mode mode = harmony_block_scoping_ |
| 2203 catch_block = new(zone()) Block(isolate(), NULL, 2, false); | 2225 ? Variable::LET : Variable::VAR; |
| 2226 catch_variable = catch_scope->DeclareLocal(name, mode); |
| 2204 | 2227 |
| 2205 Scope* saved_scope = top_scope_; | 2228 Scope* saved_scope = top_scope_; |
| 2206 top_scope_ = catch_scope; | 2229 top_scope_ = catch_scope; |
| 2207 Block* catch_body = ParseBlock(NULL, CHECK_OK); | 2230 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2208 top_scope_ = saved_scope; | 2231 top_scope_ = saved_scope; |
| 2209 catch_block->AddStatement(catch_body); | |
| 2210 catch_block->AddStatement(new(zone()) ExitContextStatement()); | |
| 2211 } else { | 2232 } else { |
| 2212 Expect(Token::LBRACE, CHECK_OK); | 2233 Expect(Token::LBRACE, CHECK_OK); |
| 2213 } | 2234 } |
| 2214 | 2235 |
| 2215 tok = peek(); | 2236 tok = peek(); |
| 2216 } | 2237 } |
| 2217 | 2238 |
| 2218 Block* finally_block = NULL; | 2239 Block* finally_block = NULL; |
| 2219 if (tok == Token::FINALLY || catch_block == NULL) { | 2240 if (tok == Token::FINALLY || catch_block == NULL) { |
| 2220 Consume(Token::FINALLY); | 2241 Consume(Token::FINALLY); |
| (...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3721 name_loc = scanner().location(); | 3742 name_loc = scanner().location(); |
| 3722 } | 3743 } |
| 3723 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 3744 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 3724 has_duplicate_parameters = true; | 3745 has_duplicate_parameters = true; |
| 3725 dupe_loc = scanner().location(); | 3746 dupe_loc = scanner().location(); |
| 3726 } | 3747 } |
| 3727 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3748 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3728 reserved_loc = scanner().location(); | 3749 reserved_loc = scanner().location(); |
| 3729 } | 3750 } |
| 3730 | 3751 |
| 3731 top_scope_->DeclareParameter(param_name); | 3752 top_scope_->DeclareParameter(param_name, |
| 3753 harmony_block_scoping_ |
| 3754 ? Variable::LET |
| 3755 : Variable::VAR); |
| 3732 num_parameters++; | 3756 num_parameters++; |
| 3733 if (num_parameters > kMaxNumFunctionParameters) { | 3757 if (num_parameters > kMaxNumFunctionParameters) { |
| 3734 ReportMessageAt(scanner().location(), "too_many_parameters", | 3758 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 3735 Vector<const char*>::empty()); | 3759 Vector<const char*>::empty()); |
| 3736 *ok = false; | 3760 *ok = false; |
| 3737 return NULL; | 3761 return NULL; |
| 3738 } | 3762 } |
| 3739 done = (peek() == Token::RPAREN); | 3763 done = (peek() == Token::RPAREN); |
| 3740 if (!done) Expect(Token::COMMA, CHECK_OK); | 3764 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3741 } | 3765 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3848 if (reserved_loc.IsValid()) { | 3872 if (reserved_loc.IsValid()) { |
| 3849 ReportMessageAt(reserved_loc, "strict_reserved_word", | 3873 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3850 Vector<const char*>::empty()); | 3874 Vector<const char*>::empty()); |
| 3851 *ok = false; | 3875 *ok = false; |
| 3852 return NULL; | 3876 return NULL; |
| 3853 } | 3877 } |
| 3854 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3878 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
| 3855 } | 3879 } |
| 3856 } | 3880 } |
| 3857 | 3881 |
| 3882 if (harmony_block_scoping_) { |
| 3883 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3884 } |
| 3885 |
| 3858 FunctionLiteral* function_literal = | 3886 FunctionLiteral* function_literal = |
| 3859 new(zone()) FunctionLiteral(isolate(), | 3887 new(zone()) FunctionLiteral(isolate(), |
| 3860 function_name, | 3888 function_name, |
| 3861 scope, | 3889 scope, |
| 3862 body, | 3890 body, |
| 3863 materialized_literal_count, | 3891 materialized_literal_count, |
| 3864 expected_property_count, | 3892 expected_property_count, |
| 3865 only_simple_this_property_assignments, | 3893 only_simple_this_property_assignments, |
| 3866 this_property_assignments, | 3894 this_property_assignments, |
| 3867 num_parameters, | 3895 num_parameters, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4054 beg_pos <= octal.beg_pos && | 4082 beg_pos <= octal.beg_pos && |
| 4055 octal.end_pos <= end_pos) { | 4083 octal.end_pos <= end_pos) { |
| 4056 ReportMessageAt(octal, "strict_octal_literal", | 4084 ReportMessageAt(octal, "strict_octal_literal", |
| 4057 Vector<const char*>::empty()); | 4085 Vector<const char*>::empty()); |
| 4058 scanner().clear_octal_position(); | 4086 scanner().clear_octal_position(); |
| 4059 *ok = false; | 4087 *ok = false; |
| 4060 } | 4088 } |
| 4061 } | 4089 } |
| 4062 | 4090 |
| 4063 | 4091 |
| 4092 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4093 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4094 if (decl != NULL) { |
| 4095 // In harmony mode we treat conflicting variable bindinds as early |
| 4096 // errors. See ES5 16 for a definition of early errors. |
| 4097 Handle<String> name = decl->proxy()->name(); |
| 4098 SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4099 const char* elms[2] = { "Variable", *c_string }; |
| 4100 Vector<const char*> args(elms, 2); |
| 4101 int position = decl->proxy()->position(); |
| 4102 Scanner::Location location = position == RelocInfo::kNoPosition |
| 4103 ? Scanner::Location::invalid() |
| 4104 : Scanner::Location(position, position + 1); |
| 4105 ReportMessageAt(location, "redeclaration", args); |
| 4106 *ok = false; |
| 4107 } |
| 4108 } |
| 4109 |
| 4110 |
| 4064 // This function reads an identifier name and determines whether or not it | 4111 // This function reads an identifier name and determines whether or not it |
| 4065 // is 'get' or 'set'. | 4112 // is 'get' or 'set'. |
| 4066 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 4113 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 4067 bool* is_set, | 4114 bool* is_set, |
| 4068 bool* ok) { | 4115 bool* ok) { |
| 4069 Handle<String> result = ParseIdentifierName(ok); | 4116 Handle<String> result = ParseIdentifierName(ok); |
| 4070 if (!*ok) return Handle<String>(); | 4117 if (!*ok) return Handle<String>(); |
| 4071 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { | 4118 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { |
| 4072 const char* token = scanner().literal_ascii_string().start(); | 4119 const char* token = scanner().literal_ascii_string().start(); |
| 4073 *is_get = strncmp(token, "get", 3) == 0; | 4120 *is_get = strncmp(token, "get", 3) == 0; |
| (...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5175 result = parser.ParseProgram(source, | 5222 result = parser.ParseProgram(source, |
| 5176 info->is_global(), | 5223 info->is_global(), |
| 5177 info->StrictMode()); | 5224 info->StrictMode()); |
| 5178 } | 5225 } |
| 5179 } | 5226 } |
| 5180 info->SetFunction(result); | 5227 info->SetFunction(result); |
| 5181 return (result != NULL); | 5228 return (result != NULL); |
| 5182 } | 5229 } |
| 5183 | 5230 |
| 5184 } } // namespace v8::internal | 5231 } } // namespace v8::internal |
| OLD | NEW |