OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 case Token::CONST: | 1435 case Token::CONST: |
1436 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1436 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); |
1437 break; | 1437 break; |
1438 | 1438 |
1439 default: | 1439 default: |
1440 *ok = false; | 1440 *ok = false; |
1441 ReportUnexpectedToken(scanner()->current_token()); | 1441 ReportUnexpectedToken(scanner()->current_token()); |
1442 return NULL; | 1442 return NULL; |
1443 } | 1443 } |
1444 | 1444 |
| 1445 // Every export of a module may be assigned. |
| 1446 for (int i = 0; i < names.length(); ++i) { |
| 1447 Variable* var = scope_->Lookup(names[i]); |
| 1448 if (var == NULL) { |
| 1449 // TODO(sigurds) This is an export that has no definition yet, |
| 1450 // not clear what to do in this case. |
| 1451 continue; |
| 1452 } |
| 1453 if (!IsImmutableVariableMode(var->mode())) { |
| 1454 var->set_maybe_assigned(); |
| 1455 } |
| 1456 } |
| 1457 |
1445 // Extract declared names into export declarations and interface. | 1458 // Extract declared names into export declarations and interface. |
1446 Interface* interface = scope_->interface(); | 1459 Interface* interface = scope_->interface(); |
1447 for (int i = 0; i < names.length(); ++i) { | 1460 for (int i = 0; i < names.length(); ++i) { |
1448 #ifdef DEBUG | 1461 #ifdef DEBUG |
1449 if (FLAG_print_interface_details) | 1462 if (FLAG_print_interface_details) |
1450 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); | 1463 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
1451 #endif | 1464 #endif |
1452 Interface* inner = Interface::NewUnknown(zone()); | 1465 Interface* inner = Interface::NewUnknown(zone()); |
1453 interface->Add(names[i], inner, zone(), CHECK_OK); | 1466 interface->Add(names[i], inner, zone(), CHECK_OK); |
1454 if (!*ok) | 1467 if (!*ok) |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 declaration_scope->is_global_scope()) { | 1661 declaration_scope->is_global_scope()) { |
1649 // Declare the variable in the declaration scope. | 1662 // Declare the variable in the declaration scope. |
1650 // For the global scope, we have to check for collisions with earlier | 1663 // For the global scope, we have to check for collisions with earlier |
1651 // (i.e., enclosing) global scopes, to maintain the illusion of a single | 1664 // (i.e., enclosing) global scopes, to maintain the illusion of a single |
1652 // global scope. | 1665 // global scope. |
1653 var = declaration_scope->is_global_scope() | 1666 var = declaration_scope->is_global_scope() |
1654 ? declaration_scope->Lookup(name) | 1667 ? declaration_scope->Lookup(name) |
1655 : declaration_scope->LookupLocal(name); | 1668 : declaration_scope->LookupLocal(name); |
1656 if (var == NULL) { | 1669 if (var == NULL) { |
1657 // Declare the name. | 1670 // Declare the name. |
1658 var = declaration_scope->DeclareLocal( | 1671 var = declaration_scope->DeclareLocal(name, mode, |
1659 name, mode, declaration->initialization(), proxy->interface()); | 1672 declaration->initialization(), |
| 1673 kNotAssigned, proxy->interface()); |
1660 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) | 1674 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) |
1661 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | 1675 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
1662 !declaration_scope->is_global_scope())) { | 1676 !declaration_scope->is_global_scope())) { |
1663 // The name was declared in this scope before; check for conflicting | 1677 // The name was declared in this scope before; check for conflicting |
1664 // re-declarations. We have a conflict if either of the declarations is | 1678 // re-declarations. We have a conflict if either of the declarations is |
1665 // not a var (in the global scope, we also have to ignore legacy const for | 1679 // not a var (in the global scope, we also have to ignore legacy const for |
1666 // compatibility). There is similar code in runtime.cc in the Declare | 1680 // compatibility). There is similar code in runtime.cc in the Declare |
1667 // functions. The function CheckConflictingVarDeclarations checks for | 1681 // functions. The function CheckConflictingVarDeclarations checks for |
1668 // var and let bindings from different scopes whereas this is a check for | 1682 // var and let bindings from different scopes whereas this is a check for |
1669 // conflicting declarations within the same scope. This check also covers | 1683 // conflicting declarations within the same scope. This check also covers |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 // same variable if it is declared several times. This is not a | 1718 // same variable if it is declared several times. This is not a |
1705 // semantic issue as long as we keep the source order, but it may be | 1719 // semantic issue as long as we keep the source order, but it may be |
1706 // a performance issue since it may lead to repeated | 1720 // a performance issue since it may lead to repeated |
1707 // RuntimeHidden_DeclareLookupSlot calls. | 1721 // RuntimeHidden_DeclareLookupSlot calls. |
1708 declaration_scope->AddDeclaration(declaration); | 1722 declaration_scope->AddDeclaration(declaration); |
1709 | 1723 |
1710 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { | 1724 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { |
1711 // For global const variables we bind the proxy to a variable. | 1725 // For global const variables we bind the proxy to a variable. |
1712 ASSERT(resolve); // should be set by all callers | 1726 ASSERT(resolve); // should be set by all callers |
1713 Variable::Kind kind = Variable::NORMAL; | 1727 Variable::Kind kind = Variable::NORMAL; |
1714 var = new(zone()) Variable( | 1728 var = new (zone()) |
1715 declaration_scope, name, mode, true, kind, | 1729 Variable(declaration_scope, name, mode, true, kind, |
1716 kNeedsInitialization, proxy->interface()); | 1730 kNeedsInitialization, kNotAssigned, proxy->interface()); |
1717 } else if (declaration_scope->is_eval_scope() && | 1731 } else if (declaration_scope->is_eval_scope() && |
1718 declaration_scope->strict_mode() == SLOPPY) { | 1732 declaration_scope->strict_mode() == SLOPPY) { |
1719 // For variable declarations in a sloppy eval scope the proxy is bound | 1733 // For variable declarations in a sloppy eval scope the proxy is bound |
1720 // to a lookup variable to force a dynamic declaration using the | 1734 // to a lookup variable to force a dynamic declaration using the |
1721 // DeclareLookupSlot runtime function. | 1735 // DeclareLookupSlot runtime function. |
1722 Variable::Kind kind = Variable::NORMAL; | 1736 Variable::Kind kind = Variable::NORMAL; |
1723 var = new(zone()) Variable( | 1737 // TODO(sigurds) figure out if kNotAssigned is OK here |
1724 declaration_scope, name, mode, true, kind, | 1738 var = new (zone()) Variable(declaration_scope, name, mode, true, kind, |
1725 declaration->initialization(), proxy->interface()); | 1739 declaration->initialization(), kNotAssigned, |
| 1740 proxy->interface()); |
1726 var->AllocateTo(Variable::LOOKUP, -1); | 1741 var->AllocateTo(Variable::LOOKUP, -1); |
1727 resolve = true; | 1742 resolve = true; |
1728 } | 1743 } |
1729 | 1744 |
1730 // If requested and we have a local variable, bind the proxy to the variable | 1745 // If requested and we have a local variable, bind the proxy to the variable |
1731 // at parse-time. This is used for functions (and consts) declared inside | 1746 // at parse-time. This is used for functions (and consts) declared inside |
1732 // statements: the corresponding function (or const) variable must be in the | 1747 // statements: the corresponding function (or const) variable must be in the |
1733 // function scope and not a statement-local scope, e.g. as provided with a | 1748 // function scope and not a statement-local scope, e.g. as provided with a |
1734 // 'with' statement: | 1749 // 'with' statement: |
1735 // | 1750 // |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2618 Expect(Token::LPAREN, CHECK_OK); | 2633 Expect(Token::LPAREN, CHECK_OK); |
2619 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2634 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2620 catch_scope->set_start_position(scanner()->location().beg_pos); | 2635 catch_scope->set_start_position(scanner()->location().beg_pos); |
2621 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2636 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2622 | 2637 |
2623 Expect(Token::RPAREN, CHECK_OK); | 2638 Expect(Token::RPAREN, CHECK_OK); |
2624 | 2639 |
2625 Target target(&this->target_stack_, &catch_collector); | 2640 Target target(&this->target_stack_, &catch_collector); |
2626 VariableMode mode = | 2641 VariableMode mode = |
2627 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; | 2642 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR; |
2628 catch_variable = | 2643 catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
2629 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | |
2630 | |
2631 BlockState block_state(&scope_, catch_scope); | 2644 BlockState block_state(&scope_, catch_scope); |
2632 catch_block = ParseBlock(NULL, CHECK_OK); | 2645 catch_block = ParseBlock(NULL, CHECK_OK); |
2633 | 2646 |
2634 catch_scope->set_end_position(scanner()->location().end_pos); | 2647 catch_scope->set_end_position(scanner()->location().end_pos); |
2635 tok = peek(); | 2648 tok = peek(); |
2636 } | 2649 } |
2637 | 2650 |
2638 Block* finally_block = NULL; | 2651 Block* finally_block = NULL; |
2639 ASSERT(tok == Token::FINALLY || catch_block != NULL); | 2652 ASSERT(tok == Token::FINALLY || catch_block != NULL); |
2640 if (tok == Token::FINALLY) { | 2653 if (tok == Token::FINALLY) { |
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3447 eval_args_error_log = scanner()->location(); | 3460 eval_args_error_log = scanner()->location(); |
3448 } | 3461 } |
3449 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3462 if (!reserved_loc.IsValid() && is_strict_reserved) { |
3450 reserved_loc = scanner()->location(); | 3463 reserved_loc = scanner()->location(); |
3451 } | 3464 } |
3452 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3465 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
3453 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3466 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
3454 dupe_error_loc = scanner()->location(); | 3467 dupe_error_loc = scanner()->location(); |
3455 } | 3468 } |
3456 | 3469 |
3457 scope_->DeclareParameter(param_name, VAR); | 3470 Variable* var = scope_->DeclareParameter(param_name, VAR); |
| 3471 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
| 3472 // conservative approximation necessary to account for parameters |
| 3473 // that are assigned via the arguments array. |
| 3474 var->set_maybe_assigned(); |
| 3475 |
3458 num_parameters++; | 3476 num_parameters++; |
3459 if (num_parameters > Code::kMaxArguments) { | 3477 if (num_parameters > Code::kMaxArguments) { |
3460 ReportMessage("too_many_parameters"); | 3478 ReportMessage("too_many_parameters"); |
3461 *ok = false; | 3479 *ok = false; |
3462 return NULL; | 3480 return NULL; |
3463 } | 3481 } |
3464 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; | 3482 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; |
3465 done = (peek() == Token::RPAREN); | 3483 done = (peek() == Token::RPAREN); |
3466 if (!done) Expect(Token::COMMA, CHECK_OK); | 3484 if (!done) Expect(Token::COMMA, CHECK_OK); |
3467 } | 3485 } |
(...skipping 10 matching lines...) Expand all Loading... |
3478 Variable* fvar = NULL; | 3496 Variable* fvar = NULL; |
3479 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3497 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
3480 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3498 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
3481 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3499 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3482 fvar_init_op = Token::INIT_CONST; | 3500 fvar_init_op = Token::INIT_CONST; |
3483 } | 3501 } |
3484 VariableMode fvar_mode = | 3502 VariableMode fvar_mode = |
3485 allow_harmony_scoping() && strict_mode() == STRICT | 3503 allow_harmony_scoping() && strict_mode() == STRICT |
3486 ? CONST : CONST_LEGACY; | 3504 ? CONST : CONST_LEGACY; |
3487 ASSERT(function_name != NULL); | 3505 ASSERT(function_name != NULL); |
3488 fvar = new(zone()) Variable(scope_, | 3506 fvar = new (zone()) |
3489 function_name, fvar_mode, true /* is valid LHS */, | 3507 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, |
3490 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3508 Variable::NORMAL, kCreatedInitialized, kNotAssigned, |
| 3509 Interface::NewConst()); |
3491 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3510 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
3492 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3511 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
3493 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3512 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
3494 scope_->DeclareFunctionVar(fvar_declaration); | 3513 scope_->DeclareFunctionVar(fvar_declaration); |
3495 } | 3514 } |
3496 | 3515 |
3497 // Determine if the function can be parsed lazily. Lazy parsing is different | 3516 // Determine if the function can be parsed lazily. Lazy parsing is different |
3498 // from lazy compilation; we need to parse more eagerly than we compile. | 3517 // from lazy compilation; we need to parse more eagerly than we compile. |
3499 | 3518 |
3500 // We can only parse lazily if we also compile lazily. The heuristics for | 3519 // We can only parse lazily if we also compile lazily. The heuristics for |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4785 info()->SetAstValueFactory(ast_value_factory_); | 4804 info()->SetAstValueFactory(ast_value_factory_); |
4786 } | 4805 } |
4787 ast_value_factory_ = NULL; | 4806 ast_value_factory_ = NULL; |
4788 | 4807 |
4789 InternalizeUseCounts(); | 4808 InternalizeUseCounts(); |
4790 | 4809 |
4791 return (result != NULL); | 4810 return (result != NULL); |
4792 } | 4811 } |
4793 | 4812 |
4794 } } // namespace v8::internal | 4813 } } // namespace v8::internal |
OLD | NEW |