OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1541 | 1541 |
1542 OpenFunctionBlock(func); | 1542 OpenFunctionBlock(func); |
1543 | 1543 |
1544 ParamList params; | 1544 ParamList params; |
1545 params.AddFinalParameter( | 1545 params.AddFinalParameter( |
1546 token_pos, | 1546 token_pos, |
1547 &Symbols::ClosureParameter(), | 1547 &Symbols::ClosureParameter(), |
1548 &Object::dynamic_type()); | 1548 &Object::dynamic_type()); |
1549 | 1549 |
1550 const Function& parent = Function::Handle(func.parent_function()); | 1550 const Function& parent = Function::Handle(func.parent_function()); |
1551 const String& target_name = String::Handle(parent.name()); | 1551 if (parent.IsImplicitSetterFunction()) { |
1552 const Class& owner = Class::Handle(parent.Owner()); | |
1553 Function& target = Function::ZoneHandle(owner.LookupFunction(target_name)); | |
1554 if (target.raw() != parent.raw()) { | |
1555 ASSERT(Isolate::Current()->HasAttemptedReload()); | |
1556 if (target.IsNull() || | |
1557 (target.is_static() != parent.is_static()) || | |
1558 (target.kind() != parent.kind())) { | |
1559 // TODO(26977): call noSuchMethod/throw NSME instead. | |
1560 target = parent.raw(); | |
1561 } | |
1562 } | |
1563 | |
1564 if (target.IsImplicitSetterFunction()) { | |
1565 const TokenPosition ident_pos = func.token_pos(); | 1552 const TokenPosition ident_pos = func.token_pos(); |
1566 ASSERT(IsIdentifier()); | 1553 ASSERT(IsIdentifier()); |
1567 const String& field_name = *CurrentLiteral(); | |
1568 const Class& field_class = Class::ZoneHandle(Z, target.Owner()); | |
1569 const Field& field = | |
1570 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | |
1571 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | |
1572 params.AddFinalParameter(ident_pos, | 1554 params.AddFinalParameter(ident_pos, |
1573 &Symbols::Value(), | 1555 &Symbols::Value(), |
Cutch
2016/08/04 00:38:05
why drop the field type here?
rmacnak
2016/08/04 16:19:31
The lookup can fail if the target no longer exists
| |
1574 &field_type); | 1556 &Object::dynamic_type()); |
1575 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | 1557 ASSERT(func.num_fixed_parameters() == 2); // closure, value. |
1576 } else if (!target.IsGetterFunction() && !target.IsImplicitGetterFunction()) { | 1558 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) { |
1577 const bool allow_explicit_default_values = true; | 1559 const bool allow_explicit_default_values = true; |
1578 SkipFunctionPreamble(); | 1560 SkipFunctionPreamble(); |
1579 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 1561 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
1580 SetupDefaultsForOptionalParams(params); | 1562 SetupDefaultsForOptionalParams(params); |
1581 } | 1563 } |
1582 | 1564 |
1583 // Populate function scope with the formal parameters. | 1565 // Populate function scope with the formal parameters. |
1584 LocalScope* scope = current_block_->scope; | 1566 LocalScope* scope = current_block_->scope; |
1585 AddFormalParamsToScope(¶ms, scope); | 1567 AddFormalParamsToScope(¶ms, scope); |
1586 | 1568 |
(...skipping 10 matching lines...) Expand all Loading... | |
1597 // TODO(srdjan): Must allocate array in old space, since it | 1579 // TODO(srdjan): Must allocate array in old space, since it |
1598 // runs in background compiler. Find a better way. | 1580 // runs in background compiler. Find a better way. |
1599 const Array& arg_names = | 1581 const Array& arg_names = |
1600 Array::ZoneHandle(Array::New(func.NumOptionalParameters(), Heap::kOld)); | 1582 Array::ZoneHandle(Array::New(func.NumOptionalParameters(), Heap::kOld)); |
1601 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | 1583 for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
1602 intptr_t index = func.num_fixed_parameters() + i; | 1584 intptr_t index = func.num_fixed_parameters() + i; |
1603 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); | 1585 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); |
1604 } | 1586 } |
1605 func_args->set_names(arg_names); | 1587 func_args->set_names(arg_names); |
1606 } | 1588 } |
1607 StaticCallNode* call = new StaticCallNode(token_pos, target, func_args); | 1589 |
1590 const String& func_name = String::ZoneHandle(parent.name()); | |
1591 const Class& owner = Class::Handle(parent.Owner()); | |
1592 Function& target = Function::ZoneHandle(owner.LookupFunction(func_name)); | |
1593 if (target.raw() != parent.raw()) { | |
1594 ASSERT(Isolate::Current()->HasAttemptedReload()); | |
1595 if (target.IsNull() || | |
1596 (target.is_static() != parent.is_static()) || | |
1597 (target.kind() != parent.kind())) { | |
1598 target = Function::null(); | |
1599 } | |
1600 } | |
1601 | |
1602 AstNode* call = NULL; | |
1603 if (!target.IsNull()) { | |
1604 call = new StaticCallNode(token_pos, target, func_args); | |
1605 } else if (!parent.is_static()) { | |
1606 ASSERT(Isolate::Current()->HasAttemptedReload()); | |
1607 // If a subsequent reload reintroduces the target in the middle of the | |
1608 // Invocation object being constructed, we won't be able to successfully | |
1609 // deopt because the generated AST will change. | |
1610 current_function().SetIsOptimizable(false); | |
1611 | |
1612 ArgumentListNode* arguments = BuildNoSuchMethodArguments( | |
1613 token_pos, func_name, *func_args, NULL, false); | |
1614 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. | |
1615 ArgumentsDescriptor args_desc( | |
1616 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); | |
1617 Function& no_such_method = Function::ZoneHandle(Z, | |
1618 Resolver::ResolveDynamicForReceiverClass(owner, | |
1619 Symbols::NoSuchMethod(), | |
1620 args_desc)); | |
1621 if (no_such_method.IsNull()) { | |
1622 // If noSuchMethod(i) is not found, call Object:noSuchMethod. | |
1623 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( | |
1624 Class::Handle(Z, I->object_store()->object_class()), | |
1625 Symbols::NoSuchMethod(), | |
1626 args_desc); | |
1627 } | |
1628 call = new StaticCallNode(token_pos, no_such_method, arguments); | |
1629 } else { | |
1630 ASSERT(Isolate::Current()->HasAttemptedReload()); | |
1631 // If a subsequent reload reintroduces the target in the middle of the | |
1632 // arguments array being constructed, we won't be able to successfully | |
1633 // deopt because the generated AST will change. | |
1634 current_function().SetIsOptimizable(false); | |
1635 | |
1636 InvocationMirror::Type im_type; | |
1637 if (parent.IsImplicitGetterFunction()) { | |
1638 im_type = InvocationMirror::kGetter; | |
1639 } else if (parent.IsImplicitSetterFunction()) { | |
1640 im_type = InvocationMirror::kSetter; | |
1641 } else { | |
1642 im_type = InvocationMirror::kMethod; | |
1643 } | |
1644 call = ThrowNoSuchMethodError(TokenPos(), | |
1645 owner, | |
1646 func_name, | |
1647 func_args, | |
1648 InvocationMirror::kStatic, | |
1649 im_type, | |
1650 NULL); // No existing function. | |
1651 } | |
1652 | |
1653 ASSERT(call != NULL); | |
1608 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1654 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1609 current_block_->statements->Add(return_node); | 1655 current_block_->statements->Add(return_node); |
1610 return CloseBlock(); | 1656 return CloseBlock(); |
1611 } | 1657 } |
1612 | 1658 |
1613 | 1659 |
1614 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1660 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
1615 TRACE_PARSER("ParseMethodExtractor"); | 1661 TRACE_PARSER("ParseMethodExtractor"); |
1616 | 1662 |
1617 ParamList params; | 1663 ParamList params; |
(...skipping 13034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14652 const ArgumentListNode& function_args, | 14698 const ArgumentListNode& function_args, |
14653 const LocalVariable* temp_for_last_arg, | 14699 const LocalVariable* temp_for_last_arg, |
14654 bool is_super_invocation) { | 14700 bool is_super_invocation) { |
14655 UNREACHABLE(); | 14701 UNREACHABLE(); |
14656 return NULL; | 14702 return NULL; |
14657 } | 14703 } |
14658 | 14704 |
14659 } // namespace dart | 14705 } // namespace dart |
14660 | 14706 |
14661 #endif // DART_PRECOMPILED_RUNTIME | 14707 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |