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 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 BuildDispatcherScope(func, desc, default_values); | 1191 BuildDispatcherScope(func, desc, default_values); |
1192 | 1192 |
1193 // Receiver is local 0. | 1193 // Receiver is local 0. |
1194 LocalScope* scope = current_block_->scope; | 1194 LocalScope* scope = current_block_->scope; |
1195 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | 1195 ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
1196 for (intptr_t i = 0; i < desc.Count(); ++i) { | 1196 for (intptr_t i = 0; i < desc.Count(); ++i) { |
1197 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1197 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
1198 } | 1198 } |
1199 | 1199 |
1200 if (desc.NamedCount() > 0) { | 1200 if (desc.NamedCount() > 0) { |
1201 const Array& arg_names = | 1201 const Array& arg_names = Array::ZoneHandle(Array::New(desc.NamedCount())); |
1202 Array::ZoneHandle(Array::New(desc.NamedCount())); | |
1203 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | 1202 for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
1204 arg_names.SetAt(i, String::Handle(desc.NameAt(i))); | 1203 arg_names.SetAt(i, String::Handle(desc.NameAt(i))); |
1205 } | 1204 } |
1206 func_args->set_names(arg_names); | 1205 func_args->set_names(arg_names); |
1207 } | 1206 } |
1208 | 1207 |
1209 const String& func_name = String::ZoneHandle(func.name()); | 1208 const String& func_name = String::ZoneHandle(func.name()); |
1210 ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos, | 1209 ArgumentListNode* arguments = BuildNoSuchMethodArguments( |
1211 func_name, | 1210 token_pos, func_name, *func_args, NULL, false); |
1212 *func_args); | |
1213 const Function& no_such_method = Function::ZoneHandle( | 1211 const Function& no_such_method = Function::ZoneHandle( |
1214 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()), | 1212 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()), |
1215 Symbols::NoSuchMethod())); | 1213 Symbols::NoSuchMethod())); |
1216 StaticCallNode* call = | 1214 StaticCallNode* call = |
1217 new StaticCallNode(token_pos, no_such_method, arguments); | 1215 new StaticCallNode(token_pos, no_such_method, arguments); |
1218 | 1216 |
1219 | |
1220 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1217 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1221 current_block_->statements->Add(return_node); | 1218 current_block_->statements->Add(return_node); |
1222 return CloseBlock(); | 1219 return CloseBlock(); |
1223 } | 1220 } |
1224 | 1221 |
1225 | 1222 |
1226 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, | 1223 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, |
1227 Array& default_values) { | 1224 Array& default_values) { |
1228 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1225 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
1229 | 1226 |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 *is_no_such_method = false; | 1639 *is_no_such_method = false; |
1643 } | 1640 } |
1644 return super_func.raw(); | 1641 return super_func.raw(); |
1645 } | 1642 } |
1646 | 1643 |
1647 | 1644 |
1648 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 1645 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
1649 intptr_t call_pos, | 1646 intptr_t call_pos, |
1650 const String& function_name, | 1647 const String& function_name, |
1651 const ArgumentListNode& function_args, | 1648 const ArgumentListNode& function_args, |
1652 const LocalVariable* temp_for_last_arg) { | 1649 const LocalVariable* temp_for_last_arg, |
| 1650 bool is_super_invocation) { |
1653 const intptr_t args_pos = function_args.token_pos(); | 1651 const intptr_t args_pos = function_args.token_pos(); |
1654 // Build arguments to the call to the static | 1652 // Build arguments to the call to the static |
1655 // InvocationMirror._allocateInvocationMirror method. | 1653 // InvocationMirror._allocateInvocationMirror method. |
1656 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1654 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
1657 // The first argument is the original function name. | 1655 // The first argument is the original function name. |
1658 arguments->Add(new LiteralNode(args_pos, function_name)); | 1656 arguments->Add(new LiteralNode(args_pos, function_name)); |
1659 // The second argument is the arguments descriptor of the original function. | 1657 // The second argument is the arguments descriptor of the original function. |
1660 const Array& args_descriptor = | 1658 const Array& args_descriptor = |
1661 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 1659 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
1662 function_args.names())); | 1660 function_args.names())); |
(...skipping 10 matching lines...) Expand all Loading... |
1673 temp_for_last_arg, | 1671 temp_for_last_arg, |
1674 arg)); | 1672 arg)); |
1675 store_arg->AddNode(new LoadLocalNode(arg->token_pos(), | 1673 store_arg->AddNode(new LoadLocalNode(arg->token_pos(), |
1676 temp_for_last_arg)); | 1674 temp_for_last_arg)); |
1677 args_array->AddElement(store_arg); | 1675 args_array->AddElement(store_arg); |
1678 } else { | 1676 } else { |
1679 args_array->AddElement(arg); | 1677 args_array->AddElement(arg); |
1680 } | 1678 } |
1681 } | 1679 } |
1682 arguments->Add(args_array); | 1680 arguments->Add(args_array); |
| 1681 arguments->Add(new LiteralNode(args_pos, Bool::Get(is_super_invocation))); |
1683 // Lookup the static InvocationMirror._allocateInvocationMirror method. | 1682 // Lookup the static InvocationMirror._allocateInvocationMirror method. |
1684 const Class& mirror_class = | 1683 const Class& mirror_class = |
1685 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); | 1684 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); |
1686 ASSERT(!mirror_class.IsNull()); | 1685 ASSERT(!mirror_class.IsNull()); |
1687 const Function& allocation_function = Function::ZoneHandle( | 1686 const Function& allocation_function = Function::ZoneHandle( |
1688 mirror_class.LookupStaticFunction( | 1687 mirror_class.LookupStaticFunction( |
1689 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 1688 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
1690 ASSERT(!allocation_function.IsNull()); | 1689 ASSERT(!allocation_function.IsNull()); |
1691 return new StaticCallNode(call_pos, allocation_function, arguments); | 1690 return new StaticCallNode(call_pos, allocation_function, arguments); |
1692 } | 1691 } |
1693 | 1692 |
1694 | 1693 |
1695 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 1694 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
1696 intptr_t call_pos, | 1695 intptr_t call_pos, |
1697 const String& function_name, | 1696 const String& function_name, |
1698 const ArgumentListNode& function_args, | 1697 const ArgumentListNode& function_args, |
1699 const LocalVariable* temp_for_last_arg) { | 1698 const LocalVariable* temp_for_last_arg, |
| 1699 bool is_super_invocation) { |
1700 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 1700 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
1701 const intptr_t args_pos = function_args.token_pos(); | 1701 const intptr_t args_pos = function_args.token_pos(); |
1702 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1702 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
1703 arguments->Add(function_args.NodeAt(0)); | 1703 arguments->Add(function_args.NodeAt(0)); |
1704 // The second argument is the invocation mirror. | 1704 // The second argument is the invocation mirror. |
1705 arguments->Add(BuildInvocationMirrorAllocation( | 1705 arguments->Add(BuildInvocationMirrorAllocation(call_pos, |
1706 call_pos, function_name, function_args, temp_for_last_arg)); | 1706 function_name, |
| 1707 function_args, |
| 1708 temp_for_last_arg, |
| 1709 is_super_invocation)); |
1707 return arguments; | 1710 return arguments; |
1708 } | 1711 } |
1709 | 1712 |
1710 | 1713 |
1711 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1714 AstNode* Parser::ParseSuperCall(const String& function_name) { |
1712 TRACE_PARSER("ParseSuperCall"); | 1715 TRACE_PARSER("ParseSuperCall"); |
1713 ASSERT(CurrentToken() == Token::kLPAREN); | 1716 ASSERT(CurrentToken() == Token::kLPAREN); |
1714 const intptr_t supercall_pos = TokenPos(); | 1717 const intptr_t supercall_pos = TokenPos(); |
1715 | 1718 |
1716 // 'this' parameter is the first argument to super call. | 1719 // 'this' parameter is the first argument to super call. |
(...skipping 21 matching lines...) Expand all Loading... |
1738 EnsureSavedCurrentContext(); | 1741 EnsureSavedCurrentContext(); |
1739 // 'this' is not passed as parameter to the closure. | 1742 // 'this' is not passed as parameter to the closure. |
1740 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); | 1743 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); |
1741 for (int i = 1; i < arguments->length(); i++) { | 1744 for (int i = 1; i < arguments->length(); i++) { |
1742 closure_arguments->Add(arguments->NodeAt(i)); | 1745 closure_arguments->Add(arguments->NodeAt(i)); |
1743 } | 1746 } |
1744 return new ClosureCallNode(supercall_pos, closure, closure_arguments); | 1747 return new ClosureCallNode(supercall_pos, closure, closure_arguments); |
1745 } | 1748 } |
1746 if (is_no_such_method) { | 1749 if (is_no_such_method) { |
1747 arguments = BuildNoSuchMethodArguments( | 1750 arguments = BuildNoSuchMethodArguments( |
1748 supercall_pos, function_name, *arguments); | 1751 supercall_pos, function_name, *arguments, NULL, true); |
1749 } | 1752 } |
1750 return new StaticCallNode(supercall_pos, super_function, arguments); | 1753 return new StaticCallNode(supercall_pos, super_function, arguments); |
1751 } | 1754 } |
1752 | 1755 |
1753 | 1756 |
1754 // Simple test if a node is side effect free. | 1757 // Simple test if a node is side effect free. |
1755 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 1758 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
1756 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 1759 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
1757 } | 1760 } |
1758 | 1761 |
(...skipping 13 matching lines...) Expand all Loading... |
1772 const bool kResolveGetter = false; | 1775 const bool kResolveGetter = false; |
1773 bool is_no_such_method = false; | 1776 bool is_no_such_method = false; |
1774 const Function& super_operator = Function::ZoneHandle( | 1777 const Function& super_operator = Function::ZoneHandle( |
1775 GetSuperFunction(super_pos, | 1778 GetSuperFunction(super_pos, |
1776 operator_function_name, | 1779 operator_function_name, |
1777 op_arguments, | 1780 op_arguments, |
1778 kResolveGetter, | 1781 kResolveGetter, |
1779 &is_no_such_method)); | 1782 &is_no_such_method)); |
1780 if (is_no_such_method) { | 1783 if (is_no_such_method) { |
1781 op_arguments = BuildNoSuchMethodArguments( | 1784 op_arguments = BuildNoSuchMethodArguments( |
1782 super_pos, operator_function_name, *op_arguments); | 1785 super_pos, operator_function_name, *op_arguments, NULL, true); |
1783 } | 1786 } |
1784 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 1787 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
1785 } else { | 1788 } else { |
1786 ErrorMsg(super_pos, "illegal super operator call"); | 1789 ErrorMsg(super_pos, "illegal super operator call"); |
1787 } | 1790 } |
1788 return super_op; | 1791 return super_op; |
1789 } | 1792 } |
1790 | 1793 |
1791 | 1794 |
1792 AstNode* Parser::ParseSuperOperator() { | 1795 AstNode* Parser::ParseSuperOperator() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 const bool kResolveGetter = false; | 1832 const bool kResolveGetter = false; |
1830 bool is_no_such_method = false; | 1833 bool is_no_such_method = false; |
1831 const Function& super_operator = Function::ZoneHandle( | 1834 const Function& super_operator = Function::ZoneHandle( |
1832 GetSuperFunction(operator_pos, | 1835 GetSuperFunction(operator_pos, |
1833 operator_function_name, | 1836 operator_function_name, |
1834 op_arguments, | 1837 op_arguments, |
1835 kResolveGetter, | 1838 kResolveGetter, |
1836 &is_no_such_method)); | 1839 &is_no_such_method)); |
1837 if (is_no_such_method) { | 1840 if (is_no_such_method) { |
1838 op_arguments = BuildNoSuchMethodArguments( | 1841 op_arguments = BuildNoSuchMethodArguments( |
1839 operator_pos, operator_function_name, *op_arguments); | 1842 operator_pos, operator_function_name, *op_arguments, NULL, true); |
1840 } | 1843 } |
1841 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 1844 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
1842 if (negate_result) { | 1845 if (negate_result) { |
1843 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 1846 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
1844 } | 1847 } |
1845 } | 1848 } |
1846 return super_op; | 1849 return super_op; |
1847 } | 1850 } |
1848 | 1851 |
1849 | 1852 |
(...skipping 8718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10568 void Parser::SkipQualIdent() { | 10571 void Parser::SkipQualIdent() { |
10569 ASSERT(IsIdentifier()); | 10572 ASSERT(IsIdentifier()); |
10570 ConsumeToken(); | 10573 ConsumeToken(); |
10571 if (CurrentToken() == Token::kPERIOD) { | 10574 if (CurrentToken() == Token::kPERIOD) { |
10572 ConsumeToken(); // Consume the kPERIOD token. | 10575 ConsumeToken(); // Consume the kPERIOD token. |
10573 ExpectIdentifier("identifier expected after '.'"); | 10576 ExpectIdentifier("identifier expected after '.'"); |
10574 } | 10577 } |
10575 } | 10578 } |
10576 | 10579 |
10577 } // namespace dart | 10580 } // namespace dart |
OLD | NEW |