Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 15979010: Fix two bugs in the Dart VM's super-noSuchMethod invocation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 23 matching lines...) Expand all
34 DECLARE_FLAG(bool, enable_type_checks); 34 DECLARE_FLAG(bool, enable_type_checks);
35 35
36 36
37 static const String& PrivateCoreLibName(const String& str) { 37 static const String& PrivateCoreLibName(const String& str) {
38 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 38 const Library& core_lib = Library::Handle(Library::CoreLibrary());
39 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); 39 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str));
40 return private_name; 40 return private_name;
41 } 41 }
42 42
43 43
44 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function, 44 FlowGraphBuilder::FlowGraphBuilder(ParsedFunction* parsed_function,
45 const Array& ic_data_array, 45 const Array& ic_data_array,
46 InlineExitCollector* exit_collector) 46 InlineExitCollector* exit_collector)
47 : parsed_function_(parsed_function), 47 : parsed_function_(parsed_function),
48 ic_data_array_(ic_data_array), 48 ic_data_array_(ic_data_array),
49 num_copied_params_(parsed_function.num_copied_params()), 49 num_copied_params_(parsed_function->num_copied_params()),
50 // All parameters are copied if any parameter is. 50 // All parameters are copied if any parameter is.
51 num_non_copied_params_((num_copied_params_ == 0) 51 num_non_copied_params_((num_copied_params_ == 0)
52 ? parsed_function.function().num_fixed_parameters() 52 ? parsed_function->function().num_fixed_parameters()
53 : 0), 53 : 0),
54 num_stack_locals_(parsed_function.num_stack_locals()), 54 num_stack_locals_(parsed_function->num_stack_locals()),
55 exit_collector_(exit_collector), 55 exit_collector_(exit_collector),
56 last_used_block_id_(0), // 0 is used for the graph entry. 56 last_used_block_id_(0), // 0 is used for the graph entry.
57 context_level_(0), 57 context_level_(0),
58 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), 58 last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
59 try_index_(CatchClauseNode::kInvalidTryIndex), 59 try_index_(CatchClauseNode::kInvalidTryIndex),
60 graph_entry_(NULL), 60 graph_entry_(NULL),
61 args_pushed_(0) { } 61 args_pushed_(0) { }
62 62
63 63
64 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { 64 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 515
516 516
517 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, 517 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
518 Value* value) { 518 Value* value) {
519 ASSERT(!local.is_captured()); 519 ASSERT(!local.is_captured());
520 return new StoreLocalInstr(local, value); 520 return new StoreLocalInstr(local, value);
521 } 521 }
522 522
523 523
524 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) { 524 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) {
525 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), 525 return BuildStoreTemp(*owner()->parsed_function()->expression_temp_var(),
526 value); 526 value);
527 } 527 }
528 528
529 529
530 Definition* EffectGraphVisitor::BuildLoadExprTemp() { 530 Definition* EffectGraphVisitor::BuildLoadExprTemp() {
531 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); 531 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var());
532 } 532 }
533 533
534 534
535 Definition* EffectGraphVisitor::BuildStoreLocal( 535 Definition* EffectGraphVisitor::BuildStoreLocal(
536 const LocalVariable& local, Value* value, bool result_is_needed) { 536 const LocalVariable& local, Value* value, bool result_is_needed) {
537 if (local.is_captured()) { 537 if (local.is_captured()) {
538 InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)"); 538 InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)");
539 if (result_is_needed) { 539 if (result_is_needed) {
540 value = Bind(BuildStoreExprTemp(value)); 540 value = Bind(BuildStoreExprTemp(value));
541 } 541 }
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 ValueGraphVisitor::VisitBinaryOpNode(node); 762 ValueGraphVisitor::VisitBinaryOpNode(node);
763 } 763 }
764 764
765 765
766 void EffectGraphVisitor::Bailout(const char* reason) { 766 void EffectGraphVisitor::Bailout(const char* reason) {
767 owner()->Bailout(reason); 767 owner()->Bailout(reason);
768 } 768 }
769 769
770 770
771 void EffectGraphVisitor::InlineBailout(const char* reason) { 771 void EffectGraphVisitor::InlineBailout(const char* reason) {
772 owner()->parsed_function().function().set_is_inlinable(false); 772 owner()->parsed_function()->function().set_is_inlinable(false);
773 if (owner()->IsInlining()) owner()->Bailout(reason); 773 if (owner()->IsInlining()) owner()->Bailout(reason);
774 } 774 }
775 775
776 776
777 // <Statement> ::= Return { value: <Expression> 777 // <Statement> ::= Return { value: <Expression>
778 // inlined_finally_list: <InlinedFinally>* } 778 // inlined_finally_list: <InlinedFinally>* }
779 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 779 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
780 ValueGraphVisitor for_value(owner(), temp_index()); 780 ValueGraphVisitor for_value(owner(), temp_index());
781 node->value()->Visit(&for_value); 781 node->value()->Visit(&for_value);
782 Append(for_value); 782 Append(for_value);
783 783
784 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 784 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
785 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); 785 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
786 EffectGraphVisitor for_effect(owner(), temp_index()); 786 EffectGraphVisitor for_effect(owner(), temp_index());
787 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 787 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
788 Append(for_effect); 788 Append(for_effect);
789 if (!is_open()) return; 789 if (!is_open()) return;
790 } 790 }
791 791
792 Value* return_value = for_value.value(); 792 Value* return_value = for_value.value();
793 if (FLAG_enable_type_checks) { 793 if (FLAG_enable_type_checks) {
794 const Function& function = owner()->parsed_function().function(); 794 const Function& function = owner()->parsed_function()->function();
795 const bool is_implicit_dynamic_getter = 795 const bool is_implicit_dynamic_getter =
796 (!function.is_static() && 796 (!function.is_static() &&
797 ((function.kind() == RawFunction::kImplicitGetter) || 797 ((function.kind() == RawFunction::kImplicitGetter) ||
798 (function.kind() == RawFunction::kConstImplicitGetter))); 798 (function.kind() == RawFunction::kConstImplicitGetter)));
799 // Implicit getters do not need a type check at return, unless they compute 799 // Implicit getters do not need a type check at return, unless they compute
800 // the initial value of a static field. 800 // the initial value of a static field.
801 // The body of a constructor cannot modify the type of the 801 // The body of a constructor cannot modify the type of the
802 // constructed instance, which is passed in as an implicit parameter. 802 // constructed instance, which is passed in as an implicit parameter.
803 // However, factories may create an instance of the wrong type. 803 // However, factories may create an instance of the wrong type.
804 if (!is_implicit_dynamic_getter && !function.IsConstructor()) { 804 if (!is_implicit_dynamic_getter && !function.IsConstructor()) {
805 const AbstractType& dst_type = 805 const AbstractType& dst_type =
806 AbstractType::ZoneHandle( 806 AbstractType::ZoneHandle(
807 owner()->parsed_function().function().result_type()); 807 owner()->parsed_function()->function().result_type());
808 return_value = BuildAssignableValue(node->value()->token_pos(), 808 return_value = BuildAssignableValue(node->value()->token_pos(),
809 return_value, 809 return_value,
810 dst_type, 810 dst_type,
811 Symbols::FunctionResult()); 811 Symbols::FunctionResult());
812 } 812 }
813 } 813 }
814 814
815 intptr_t current_context_level = owner()->context_level(); 815 intptr_t current_context_level = owner()->context_level();
816 ASSERT(current_context_level >= 0); 816 ASSERT(current_context_level >= 0);
817 if (owner()->parsed_function().saved_entry_context_var() != NULL) { 817 if (owner()->parsed_function()->saved_entry_context_var() != NULL) {
818 // CTX on entry was saved, but not linked as context parent. 818 // CTX on entry was saved, but not linked as context parent.
819 BuildLoadContext(*owner()->parsed_function().saved_entry_context_var()); 819 BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var());
820 } else { 820 } else {
821 while (current_context_level-- > 0) { 821 while (current_context_level-- > 0) {
822 UnchainContext(); 822 UnchainContext();
823 } 823 }
824 } 824 }
825 825
826 AddReturnExit(node->token_pos(), return_value); 826 AddReturnExit(node->token_pos(), return_value);
827 } 827 }
828 828
829 829
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 879
880 // If nothing is known about the value, as is the case for passed-in 880 // If nothing is known about the value, as is the case for passed-in
881 // parameters, and since dst_type is not one of the tested cases above, then 881 // parameters, and since dst_type is not one of the tested cases above, then
882 // the type test cannot be eliminated. 882 // the type test cannot be eliminated.
883 if (value == NULL) { 883 if (value == NULL) {
884 return false; 884 return false;
885 } 885 }
886 886
887 const bool eliminated = value->Type()->IsAssignableTo(dst_type); 887 const bool eliminated = value->Type()->IsAssignableTo(dst_type);
888 if (FLAG_trace_type_check_elimination) { 888 if (FLAG_trace_type_check_elimination) {
889 FlowGraphPrinter::PrintTypeCheck(owner()->parsed_function(), 889 FlowGraphPrinter::PrintTypeCheck(*owner()->parsed_function(),
890 token_pos, 890 token_pos,
891 value, 891 value,
892 dst_type, 892 dst_type,
893 dst_name, 893 dst_name,
894 eliminated); 894 eliminated);
895 } 895 }
896 return eliminated; 896 return eliminated;
897 } 897 }
898 898
899 899
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 } 1027 }
1028 EffectGraphVisitor::VisitBinaryOpNode(node); 1028 EffectGraphVisitor::VisitBinaryOpNode(node);
1029 } 1029 }
1030 1030
1031 1031
1032 void EffectGraphVisitor::BuildTypecheckPushArguments( 1032 void EffectGraphVisitor::BuildTypecheckPushArguments(
1033 intptr_t token_pos, 1033 intptr_t token_pos,
1034 PushArgumentInstr** push_instantiator_result, 1034 PushArgumentInstr** push_instantiator_result,
1035 PushArgumentInstr** push_instantiator_type_arguments_result) { 1035 PushArgumentInstr** push_instantiator_type_arguments_result) {
1036 const Class& instantiator_class = Class::Handle( 1036 const Class& instantiator_class = Class::Handle(
1037 owner()->parsed_function().function().Owner()); 1037 owner()->parsed_function()->function().Owner());
1038 // Since called only when type tested against is not instantiated. 1038 // Since called only when type tested against is not instantiated.
1039 ASSERT(instantiator_class.NumTypeParameters() > 0); 1039 ASSERT(instantiator_class.NumTypeParameters() > 0);
1040 Value* instantiator_type_arguments = NULL; 1040 Value* instantiator_type_arguments = NULL;
1041 Value* instantiator = BuildInstantiator(); 1041 Value* instantiator = BuildInstantiator();
1042 if (instantiator == NULL) { 1042 if (instantiator == NULL) {
1043 // No instantiator when inside factory. 1043 // No instantiator when inside factory.
1044 *push_instantiator_result = PushArgument(BuildNullValue()); 1044 *push_instantiator_result = PushArgument(BuildNullValue());
1045 instantiator_type_arguments = 1045 instantiator_type_arguments =
1046 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1046 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1047 } else { 1047 } else {
1048 instantiator = Bind(BuildStoreExprTemp(instantiator)); 1048 instantiator = Bind(BuildStoreExprTemp(instantiator));
1049 *push_instantiator_result = PushArgument(instantiator); 1049 *push_instantiator_result = PushArgument(instantiator);
1050 Value* loaded = Bind(BuildLoadExprTemp()); 1050 Value* loaded = Bind(BuildLoadExprTemp());
1051 instantiator_type_arguments = 1051 instantiator_type_arguments =
1052 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); 1052 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
1053 } 1053 }
1054 *push_instantiator_type_arguments_result = 1054 *push_instantiator_type_arguments_result =
1055 PushArgument(instantiator_type_arguments); 1055 PushArgument(instantiator_type_arguments);
1056 } 1056 }
1057 1057
1058 1058
1059 1059
1060 void EffectGraphVisitor::BuildTypecheckArguments( 1060 void EffectGraphVisitor::BuildTypecheckArguments(
1061 intptr_t token_pos, 1061 intptr_t token_pos,
1062 Value** instantiator_result, 1062 Value** instantiator_result,
1063 Value** instantiator_type_arguments_result) { 1063 Value** instantiator_type_arguments_result) {
1064 Value* instantiator = NULL; 1064 Value* instantiator = NULL;
1065 Value* instantiator_type_arguments = NULL; 1065 Value* instantiator_type_arguments = NULL;
1066 const Class& instantiator_class = Class::Handle( 1066 const Class& instantiator_class = Class::Handle(
1067 owner()->parsed_function().function().Owner()); 1067 owner()->parsed_function()->function().Owner());
1068 // Since called only when type tested against is not instantiated. 1068 // Since called only when type tested against is not instantiated.
1069 ASSERT(instantiator_class.NumTypeParameters() > 0); 1069 ASSERT(instantiator_class.NumTypeParameters() > 0);
1070 instantiator = BuildInstantiator(); 1070 instantiator = BuildInstantiator();
1071 if (instantiator == NULL) { 1071 if (instantiator == NULL) {
1072 // No instantiator when inside factory. 1072 // No instantiator when inside factory.
1073 instantiator = BuildNullValue(); 1073 instantiator = BuildNullValue();
1074 instantiator_type_arguments = 1074 instantiator_type_arguments =
1075 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1075 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1076 } else { 1076 } else {
1077 // Preserve instantiator. 1077 // Preserve instantiator.
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 1831
1832 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { 1832 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const {
1833 return kFirstLocalSlotFromFp 1833 return kFirstLocalSlotFromFp
1834 - owner()->num_stack_locals() 1834 - owner()->num_stack_locals()
1835 - owner()->num_copied_params() 1835 - owner()->num_copied_params()
1836 - owner()->args_pushed() 1836 - owner()->args_pushed()
1837 - temp_index() + 1; 1837 - temp_index() + 1;
1838 } 1838 }
1839 1839
1840 1840
1841 class TempLocalScope : public ValueObject { 1841 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
1842 public: 1842 Do(new PushTempInstr(value));
1843 TempLocalScope(EffectGraphVisitor* visitor, Value* value) 1843 AllocateTempIndex();
1844 : visitor_(visitor) {
1845 ASSERT(value->definition()->temp_index() == visitor->temp_index() - 1);
1846 intptr_t index = visitor->GetCurrentTempLocalIndex();
1847 char name[64];
1848 OS::SNPrint(name, 64, ":tmp_local%"Pd, index);
1849 var_ = new LocalVariable(0, String::ZoneHandle(Symbols::New(name)),
1850 Type::ZoneHandle(Type::DynamicType()));
1851 var_->set_index(index);
1852 visitor->Do(new PushTempInstr(value));
1853 visitor->AllocateTempIndex();
1854 }
1855 1844
1856 LocalVariable* var() const { return var_; } 1845 ASSERT(value->definition()->temp_index() == temp_index() - 1);
1846 intptr_t index = GetCurrentTempLocalIndex();
1847 char name[64];
1848 OS::SNPrint(name, 64, ":tmp_local%"Pd, index);
1849 LocalVariable* var =
1850 new LocalVariable(0, String::ZoneHandle(Symbols::New(name)),
1851 Type::ZoneHandle(Type::DynamicType()));
1852 var->set_index(index);
1853 return var;
1854 }
1857 1855
1858 ~TempLocalScope() {
1859 Value* result = visitor_->Bind(new LoadLocalInstr(*var_));
1860 visitor_->DeallocateTempIndex(1);
1861 visitor_->ReturnDefinition(new DropTempsInstr(1, result));
1862 }
1863 1856
1864 private: 1857 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
1865 EffectGraphVisitor* visitor_; 1858 Value* tmp = Bind(new LoadLocalInstr(*var));
1866 LocalVariable* var_; 1859 DeallocateTempIndex(1);
1867 }; 1860 ASSERT(GetCurrentTempLocalIndex() == var->index());
1861 return new DropTempsInstr(1, tmp);
1862 }
1868 1863
1869 1864
1870 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { 1865 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) {
1871 intptr_t num_temps = node->num_temps(); 1866 intptr_t num_temps = node->num_temps();
1872 for (intptr_t i = 0; i < num_temps; ++i) { 1867 for (intptr_t i = 0; i < num_temps; ++i) {
1873 ValueGraphVisitor for_value(owner(), temp_index()); 1868 ValueGraphVisitor for_value(owner(), temp_index());
1874 node->InitializerAt(i)->Visit(&for_value); 1869 node->InitializerAt(i)->Visit(&for_value);
1875 Append(for_value); 1870 Append(for_value);
1876 Value* temp_val = for_value.value(); 1871 Value* temp_val = for_value.value();
1877 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); 1872 node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 const AbstractTypeArguments& type_args = 1914 const AbstractTypeArguments& type_args =
1920 AbstractTypeArguments::ZoneHandle(node->type().arguments()); 1915 AbstractTypeArguments::ZoneHandle(node->type().arguments());
1921 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 1916 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
1922 type_args); 1917 type_args);
1923 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), 1918 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(),
1924 node->length(), 1919 node->length(),
1925 node->type(), 1920 node->type(),
1926 element_type); 1921 element_type);
1927 Value* array_val = Bind(create); 1922 Value* array_val = Bind(create);
1928 1923
1929 { TempLocalScope tmp(this, array_val); 1924 { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
1930 const intptr_t class_id = create->Type()->ToCid(); 1925 const intptr_t class_id = create->Type()->ToCid();
1931 const intptr_t deopt_id = Isolate::kNoDeoptId; 1926 const intptr_t deopt_id = Isolate::kNoDeoptId;
1932 for (int i = 0; i < node->length(); ++i) { 1927 for (int i = 0; i < node->length(); ++i) {
1933 Value* array = Bind(new LoadLocalInstr(*tmp.var())); 1928 Value* array = Bind(new LoadLocalInstr(*tmp_var));
1934 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); 1929 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i))));
1935 ValueGraphVisitor for_value(owner(), temp_index()); 1930 ValueGraphVisitor for_value(owner(), temp_index());
1936 node->ElementAt(i)->Visit(&for_value); 1931 node->ElementAt(i)->Visit(&for_value);
1937 Append(for_value); 1932 Append(for_value);
1938 // No store barrier needed for constants. 1933 // No store barrier needed for constants.
1939 const StoreBarrierType emit_store_barrier = 1934 const StoreBarrierType emit_store_barrier =
1940 for_value.value()->BindsToConstant() 1935 for_value.value()->BindsToConstant()
1941 ? kNoStoreBarrier 1936 ? kNoStoreBarrier
1942 : kEmitStoreBarrier; 1937 : kEmitStoreBarrier;
1943 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id); 1938 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id);
1944 StoreIndexedInstr* store = new StoreIndexedInstr( 1939 StoreIndexedInstr* store = new StoreIndexedInstr(
1945 array, index, for_value.value(), 1940 array, index, for_value.value(),
1946 emit_store_barrier, index_scale, class_id, deopt_id); 1941 emit_store_barrier, index_scale, class_id, deopt_id);
1947 Do(store); 1942 Do(store);
1948 } 1943 }
1944 ReturnDefinition(ExitTempLocalScope(tmp_var));
1949 } 1945 }
1950 } 1946 }
1951 1947
1952 1948
1953 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 1949 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
1954 const Function& function = node->function(); 1950 const Function& function = node->function();
1955 1951
1956 if (function.IsImplicitStaticClosureFunction()) { 1952 if (function.IsImplicitStaticClosureFunction()) {
1957 Instance& closure = Instance::ZoneHandle(); 1953 Instance& closure = Instance::ZoneHandle();
1958 closure ^= function.implicit_static_closure(); 1954 closure ^= function.implicit_static_closure();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 1989
1994 // The function type of a closure may have type arguments. In that case, pass 1990 // The function type of a closure may have type arguments. In that case, pass
1995 // the type arguments of the instantiator. Otherwise, pass null object. 1991 // the type arguments of the instantiator. Otherwise, pass null object.
1996 const Class& cls = Class::Handle(function.signature_class()); 1992 const Class& cls = Class::Handle(function.signature_class());
1997 ASSERT(!cls.IsNull()); 1993 ASSERT(!cls.IsNull());
1998 const bool requires_type_arguments = cls.HasTypeArguments(); 1994 const bool requires_type_arguments = cls.HasTypeArguments();
1999 Value* type_arguments = NULL; 1995 Value* type_arguments = NULL;
2000 if (requires_type_arguments) { 1996 if (requires_type_arguments) {
2001 ASSERT(!function.IsImplicitStaticClosureFunction()); 1997 ASSERT(!function.IsImplicitStaticClosureFunction());
2002 const Class& instantiator_class = Class::Handle( 1998 const Class& instantiator_class = Class::Handle(
2003 owner()->parsed_function().function().Owner()); 1999 owner()->parsed_function()->function().Owner());
2004 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2000 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2005 instantiator_class, 2001 instantiator_class,
2006 NULL); 2002 NULL);
2007 } else { 2003 } else {
2008 type_arguments = BuildNullValue(); 2004 type_arguments = BuildNullValue();
2009 } 2005 }
2010 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); 2006 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments);
2011 arguments->Add(push_type_arguments); 2007 arguments->Add(push_type_arguments);
2012 ReturnDefinition( 2008 ReturnDefinition(
2013 new CreateClosureInstr(node->function(), arguments, node->token_pos())); 2009 new CreateClosureInstr(node->function(), arguments, node->token_pos()));
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 node->closure()->Visit(&for_closure); 2110 node->closure()->Visit(&for_closure);
2115 Append(for_closure); 2111 Append(for_closure);
2116 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); 2112 PushArgumentInstr* push_closure = PushArgument(for_closure.value());
2117 2113
2118 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2114 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2119 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2115 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2120 arguments->Add(push_closure); 2116 arguments->Add(push_closure);
2121 BuildPushArguments(*node->arguments(), arguments); 2117 BuildPushArguments(*node->arguments(), arguments);
2122 2118
2123 // Save context around the call. 2119 // Save context around the call.
2124 ASSERT(owner()->parsed_function().saved_current_context_var() != NULL); 2120 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
2125 BuildStoreContext(*owner()->parsed_function().saved_current_context_var()); 2121 BuildStoreContext(*owner()->parsed_function()->saved_current_context_var());
2126 return new ClosureCallInstr(node, arguments); 2122 return new ClosureCallInstr(node, arguments);
2127 } 2123 }
2128 2124
2129 2125
2130 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2126 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2131 Do(BuildClosureCall(node)); 2127 Do(BuildClosureCall(node));
2132 // Restore context from saved location. 2128 // Restore context from saved location.
2133 ASSERT(owner()->parsed_function().saved_current_context_var() != NULL); 2129 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
2134 BuildLoadContext(*owner()->parsed_function().saved_current_context_var()); 2130 BuildLoadContext(*owner()->parsed_function()->saved_current_context_var());
2135 } 2131 }
2136 2132
2137 2133
2138 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2134 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2139 Value* result = Bind(BuildClosureCall(node)); 2135 Value* result = Bind(BuildClosureCall(node));
2140 // Restore context from temp. 2136 // Restore context from temp.
2141 ASSERT(owner()->parsed_function().saved_current_context_var() != NULL); 2137 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
2142 BuildLoadContext(*owner()->parsed_function().saved_current_context_var()); 2138 BuildLoadContext(*owner()->parsed_function()->saved_current_context_var());
2143 ReturnValue(result); 2139 ReturnValue(result);
2144 } 2140 }
2145 2141
2146 2142
2147 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2143 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2148 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (context)"); 2144 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (context)");
2149 Value* context = Bind(new CurrentContextInstr()); 2145 Value* context = Bind(new CurrentContextInstr());
2150 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); 2146 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context));
2151 AddInstruction(new StoreContextInstr(clone)); 2147 AddInstruction(new StoreContextInstr(clone));
2152 } 2148 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 // StaticCall(constructor, t_n+1, t_n+2, ...) 2293 // StaticCall(constructor, t_n+1, t_n+2, ...)
2298 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 2294 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
2299 Value* allocated_value = BuildObjectAllocation(node); 2295 Value* allocated_value = BuildObjectAllocation(node);
2300 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2296 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2301 BuildConstructorCall(node, push_allocated_value); 2297 BuildConstructorCall(node, push_allocated_value);
2302 } 2298 }
2303 2299
2304 2300
2305 Value* EffectGraphVisitor::BuildInstantiator() { 2301 Value* EffectGraphVisitor::BuildInstantiator() {
2306 const Class& instantiator_class = Class::Handle( 2302 const Class& instantiator_class = Class::Handle(
2307 owner()->parsed_function().function().Owner()); 2303 owner()->parsed_function()->function().Owner());
2308 if (instantiator_class.NumTypeParameters() == 0) { 2304 if (instantiator_class.NumTypeParameters() == 0) {
2309 return NULL; 2305 return NULL;
2310 } 2306 }
2311 Function& outer_function = 2307 Function& outer_function =
2312 Function::Handle(owner()->parsed_function().function().raw()); 2308 Function::Handle(owner()->parsed_function()->function().raw());
2313 while (outer_function.IsLocalFunction()) { 2309 while (outer_function.IsLocalFunction()) {
2314 outer_function = outer_function.parent_function(); 2310 outer_function = outer_function.parent_function();
2315 } 2311 }
2316 if (outer_function.IsFactory()) { 2312 if (outer_function.IsFactory()) {
2317 return NULL; 2313 return NULL;
2318 } 2314 }
2319 2315
2320 ASSERT(owner()->parsed_function().instantiator() != NULL); 2316 ASSERT(owner()->parsed_function()->instantiator() != NULL);
2321 ValueGraphVisitor for_instantiator(owner(), temp_index()); 2317 ValueGraphVisitor for_instantiator(owner(), temp_index());
2322 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 2318 owner()->parsed_function()->instantiator()->Visit(&for_instantiator);
2323 Append(for_instantiator); 2319 Append(for_instantiator);
2324 return for_instantiator.value(); 2320 return for_instantiator.value();
2325 } 2321 }
2326 2322
2327 2323
2328 // 'expression_temp_var' may not be used inside this method if 'instantiator' 2324 // 'expression_temp_var' may not be used inside this method if 'instantiator'
2329 // is not NULL. 2325 // is not NULL.
2330 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2326 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2331 intptr_t token_pos, 2327 intptr_t token_pos,
2332 const Class& instantiator_class, 2328 const Class& instantiator_class,
2333 Value* instantiator) { 2329 Value* instantiator) {
2334 if (instantiator_class.NumTypeParameters() == 0) { 2330 if (instantiator_class.NumTypeParameters() == 0) {
2335 // The type arguments are compile time constants. 2331 // The type arguments are compile time constants.
2336 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2332 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2337 // Type is temporary. Only its type arguments are preserved. 2333 // Type is temporary. Only its type arguments are preserved.
2338 Type& type = Type::Handle( 2334 Type& type = Type::Handle(
2339 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2335 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2340 type ^= ClassFinalizer::FinalizeType( 2336 type ^= ClassFinalizer::FinalizeType(
2341 instantiator_class, type, ClassFinalizer::kFinalize); 2337 instantiator_class, type, ClassFinalizer::kFinalize);
2342 ASSERT(!type.IsMalformed()); 2338 ASSERT(!type.IsMalformed());
2343 type_arguments = type.arguments(); 2339 type_arguments = type.arguments();
2344 type_arguments = type_arguments.Canonicalize(); 2340 type_arguments = type_arguments.Canonicalize();
2345 return Bind(new ConstantInstr(type_arguments)); 2341 return Bind(new ConstantInstr(type_arguments));
2346 } 2342 }
2347 Function& outer_function = 2343 Function& outer_function =
2348 Function::Handle(owner()->parsed_function().function().raw()); 2344 Function::Handle(owner()->parsed_function()->function().raw());
2349 while (outer_function.IsLocalFunction()) { 2345 while (outer_function.IsLocalFunction()) {
2350 outer_function = outer_function.parent_function(); 2346 outer_function = outer_function.parent_function();
2351 } 2347 }
2352 if (outer_function.IsFactory()) { 2348 if (outer_function.IsFactory()) {
2353 // No instantiator for factories. 2349 // No instantiator for factories.
2354 ASSERT(instantiator == NULL); 2350 ASSERT(instantiator == NULL);
2355 ASSERT(owner()->parsed_function().instantiator() != NULL); 2351 ASSERT(owner()->parsed_function()->instantiator() != NULL);
2356 ValueGraphVisitor for_instantiator(owner(), temp_index()); 2352 ValueGraphVisitor for_instantiator(owner(), temp_index());
2357 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 2353 owner()->parsed_function()->instantiator()->Visit(&for_instantiator);
2358 Append(for_instantiator); 2354 Append(for_instantiator);
2359 return for_instantiator.value(); 2355 return for_instantiator.value();
2360 } 2356 }
2361 if (instantiator == NULL) { 2357 if (instantiator == NULL) {
2362 instantiator = BuildInstantiator(); 2358 instantiator = BuildInstantiator();
2363 } 2359 }
2364 // The instantiator is the receiver of the caller, which is not a factory. 2360 // The instantiator is the receiver of the caller, which is not a factory.
2365 // The receiver cannot be null; extract its AbstractTypeArguments object. 2361 // The receiver cannot be null; extract its AbstractTypeArguments object.
2366 // Note that in the factory case, the instantiator is the first parameter 2362 // Note that in the factory case, the instantiator is the first parameter
2367 // of the factory, i.e. already an AbstractTypeArguments object. 2363 // of the factory, i.e. already an AbstractTypeArguments object.
2368 intptr_t type_arguments_field_offset = 2364 intptr_t type_arguments_field_offset =
2369 instantiator_class.type_arguments_field_offset(); 2365 instantiator_class.type_arguments_field_offset();
2370 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2366 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2371 2367
2372 return Bind(new LoadFieldInstr( 2368 return Bind(new LoadFieldInstr(
2373 instantiator, 2369 instantiator,
2374 type_arguments_field_offset, 2370 type_arguments_field_offset,
2375 Type::ZoneHandle())); // Not an instance, no type. 2371 Type::ZoneHandle())); // Not an instance, no type.
2376 } 2372 }
2377 2373
2378 2374
2379 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2375 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2380 intptr_t token_pos, 2376 intptr_t token_pos,
2381 const AbstractTypeArguments& type_arguments) { 2377 const AbstractTypeArguments& type_arguments) {
2382 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2378 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2383 return Bind(new ConstantInstr(type_arguments)); 2379 return Bind(new ConstantInstr(type_arguments));
2384 } 2380 }
2385 // The type arguments are uninstantiated. 2381 // The type arguments are uninstantiated.
2386 const Class& instantiator_class = Class::ZoneHandle( 2382 const Class& instantiator_class = Class::ZoneHandle(
2387 owner()->parsed_function().function().Owner()); 2383 owner()->parsed_function()->function().Owner());
2388 Value* instantiator_value = 2384 Value* instantiator_value =
2389 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2385 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2390 const bool use_instantiator_type_args = 2386 const bool use_instantiator_type_args =
2391 type_arguments.IsUninstantiatedIdentity() || 2387 type_arguments.IsUninstantiatedIdentity() ||
2392 type_arguments.CanShareInstantiatorTypeArguments( 2388 type_arguments.CanShareInstantiatorTypeArguments(
2393 instantiator_class); 2389 instantiator_class);
2394 return use_instantiator_type_args 2390 return use_instantiator_type_args
2395 ? instantiator_value 2391 ? instantiator_value
2396 : Bind(new InstantiateTypeArgumentsInstr(token_pos, 2392 : Bind(new InstantiateTypeArgumentsInstr(token_pos,
2397 type_arguments, 2393 type_arguments,
(...skipping 14 matching lines...) Expand all
2412 2408
2413 // No instantiator required. 2409 // No instantiator required.
2414 Value* instantiator_val = Bind(new ConstantInstr( 2410 Value* instantiator_val = Bind(new ConstantInstr(
2415 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); 2411 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
2416 call_arguments->Add(PushArgument(instantiator_val)); 2412 call_arguments->Add(PushArgument(instantiator_val));
2417 return; 2413 return;
2418 } 2414 }
2419 2415
2420 // The type arguments are uninstantiated. We use expression_temp_var to save 2416 // The type arguments are uninstantiated. We use expression_temp_var to save
2421 // the instantiator type arguments because they have two uses. 2417 // the instantiator type arguments because they have two uses.
2422 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); 2418 ASSERT(owner()->parsed_function()->expression_temp_var() != NULL);
2423 const Class& instantiator_class = Class::Handle( 2419 const Class& instantiator_class = Class::Handle(
2424 owner()->parsed_function().function().Owner()); 2420 owner()->parsed_function()->function().Owner());
2425 Value* type_arguments_val = BuildInstantiatorTypeArguments( 2421 Value* type_arguments_val = BuildInstantiatorTypeArguments(
2426 node->token_pos(), instantiator_class, NULL); 2422 node->token_pos(), instantiator_class, NULL);
2427 2423
2428 const bool use_instantiator_type_args = 2424 const bool use_instantiator_type_args =
2429 node->type_arguments().IsUninstantiatedIdentity() || 2425 node->type_arguments().IsUninstantiatedIdentity() ||
2430 node->type_arguments().CanShareInstantiatorTypeArguments( 2426 node->type_arguments().CanShareInstantiatorTypeArguments(
2431 instantiator_class); 2427 instantiator_class);
2432 2428
2433 if (!use_instantiator_type_args) { 2429 if (!use_instantiator_type_args) {
2434 const intptr_t len = node->type_arguments().Length(); 2430 const intptr_t len = node->type_arguments().Length();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 2471
2476 // t_n contains the allocated and initialized object. 2472 // t_n contains the allocated and initialized object.
2477 // t_n <- AllocateObject(class) 2473 // t_n <- AllocateObject(class)
2478 // t_n <- StoreLocal(temp, t_n); 2474 // t_n <- StoreLocal(temp, t_n);
2479 // t_n+1 <- ctor-arg 2475 // t_n+1 <- ctor-arg
2480 // t_n+2... <- constructor arguments start here 2476 // t_n+2... <- constructor arguments start here
2481 // StaticCall(constructor, t_n, t_n+1, ...) 2477 // StaticCall(constructor, t_n, t_n+1, ...)
2482 // tn <- LoadLocal(temp) 2478 // tn <- LoadLocal(temp)
2483 2479
2484 Value* allocate = BuildObjectAllocation(node); 2480 Value* allocate = BuildObjectAllocation(node);
2485 { TempLocalScope tmp(this, allocate); 2481 { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
2486 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp.var())); 2482 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp_var));
2487 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); 2483 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
2488 BuildConstructorCall(node, push_allocated_value); 2484 BuildConstructorCall(node, push_allocated_value);
2485 ReturnDefinition(ExitTempLocalScope(tmp_var));
2489 } 2486 }
2490 } 2487 }
2491 2488
2492 2489
2493 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2490 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
2494 ValueGraphVisitor for_receiver(owner(), temp_index()); 2491 ValueGraphVisitor for_receiver(owner(), temp_index());
2495 node->receiver()->Visit(&for_receiver); 2492 node->receiver()->Visit(&for_receiver);
2496 Append(for_receiver); 2493 Append(for_receiver);
2497 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2494 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2498 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2495 ZoneGrowableArray<PushArgumentInstr*>* arguments =
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2575 new ZoneGrowableArray<PushArgumentInstr*>(); 2572 new ZoneGrowableArray<PushArgumentInstr*>();
2576 Function& getter_function = Function::ZoneHandle(); 2573 Function& getter_function = Function::ZoneHandle();
2577 if (node->is_super_getter()) { 2574 if (node->is_super_getter()) {
2578 // Statically resolved instance getter, i.e. "super getter". 2575 // Statically resolved instance getter, i.e. "super getter".
2579 ASSERT(node->receiver() != NULL); 2576 ASSERT(node->receiver() != NULL);
2580 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); 2577 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
2581 if (getter_function.IsNull()) { 2578 if (getter_function.IsNull()) {
2582 // Resolve and call noSuchMethod. 2579 // Resolve and call noSuchMethod.
2583 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2580 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2584 arguments->Add(node->receiver()); 2581 arguments->Add(node->receiver());
2585 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(), 2582 StaticCallInstr* call =
2586 node->receiver(), 2583 BuildStaticNoSuchMethodCall(node->cls(),
2587 getter_name, 2584 node->receiver(),
2588 arguments); 2585 getter_name,
2586 arguments,
2587 false); // Don't save last argument.
2589 ReturnDefinition(call); 2588 ReturnDefinition(call);
2590 return; 2589 return;
2591 } else { 2590 } else {
2592 ValueGraphVisitor receiver_value(owner(), temp_index()); 2591 ValueGraphVisitor receiver_value(owner(), temp_index());
2593 node->receiver()->Visit(&receiver_value); 2592 node->receiver()->Visit(&receiver_value);
2594 Append(receiver_value); 2593 Append(receiver_value);
2595 arguments->Add(PushArgument(receiver_value.value())); 2594 arguments->Add(PushArgument(receiver_value.value()));
2596 } 2595 }
2597 } else { 2596 } else {
2598 getter_function = node->cls().LookupStaticFunction(getter_name); 2597 getter_function = node->cls().LookupStaticFunction(getter_name);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2649 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) 2648 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
2650 : node->cls().LookupStaticFunction(setter_name)); 2649 : node->cls().LookupStaticFunction(setter_name));
2651 StaticCallInstr* call; 2650 StaticCallInstr* call;
2652 if (setter_function.IsNull()) { 2651 if (setter_function.IsNull()) {
2653 if (is_super_setter) { 2652 if (is_super_setter) {
2654 ASSERT(node->receiver() != NULL); 2653 ASSERT(node->receiver() != NULL);
2655 // Resolve and call noSuchMethod. 2654 // Resolve and call noSuchMethod.
2656 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2655 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2657 arguments->Add(node->receiver()); 2656 arguments->Add(node->receiver());
2658 arguments->Add(node->value()); 2657 arguments->Add(node->value());
2659 call = BuildStaticNoSuchMethodCall(node->cls(), 2658 call = BuildStaticNoSuchMethodCall(
2660 node->receiver(), 2659 node->cls(),
2661 setter_name, 2660 node->receiver(),
2662 arguments); 2661 setter_name,
2662 arguments,
2663 result_is_needed); // Save last arg if result is needed.
2663 } else { 2664 } else {
2664 // Throw a NoSuchMethodError. 2665 // Throw a NoSuchMethodError.
2665 call = BuildThrowNoSuchMethodError( 2666 call = BuildThrowNoSuchMethodError(
2666 node->token_pos(), 2667 node->token_pos(),
2667 node->cls(), 2668 node->cls(),
2668 setter_name, 2669 setter_name,
2669 InvocationMirror::EncodeType( 2670 InvocationMirror::EncodeType(
2670 node->cls().IsTopLevel() ? 2671 node->cls().IsTopLevel() ?
2671 InvocationMirror::kTopLevel : 2672 InvocationMirror::kTopLevel :
2672 InvocationMirror::kStatic, 2673 InvocationMirror::kStatic,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2884 if (super_function->IsNull()) { 2885 if (super_function->IsNull()) {
2885 // Could not resolve super operator. Generate call noSuchMethod() of the 2886 // Could not resolve super operator. Generate call noSuchMethod() of the
2886 // super class instead. 2887 // super class instead.
2887 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2888 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2888 arguments->Add(node->array()); 2889 arguments->Add(node->array());
2889 arguments->Add(node->index_expr()); 2890 arguments->Add(node->index_expr());
2890 StaticCallInstr* call = 2891 StaticCallInstr* call =
2891 BuildStaticNoSuchMethodCall(node->super_class(), 2892 BuildStaticNoSuchMethodCall(node->super_class(),
2892 node->array(), 2893 node->array(),
2893 Symbols::IndexToken(), 2894 Symbols::IndexToken(),
2894 arguments); 2895 arguments,
2896 false); // Don't save last arg.
2895 ReturnDefinition(call); 2897 ReturnDefinition(call);
2896 return; 2898 return;
2897 } 2899 }
2898 } 2900 }
2899 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2901 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2900 new ZoneGrowableArray<PushArgumentInstr*>(2); 2902 new ZoneGrowableArray<PushArgumentInstr*>(2);
2901 ValueGraphVisitor for_array(owner(), temp_index()); 2903 ValueGraphVisitor for_array(owner(), temp_index());
2902 node->array()->Visit(&for_array); 2904 node->array()->Visit(&for_array);
2903 Append(for_array); 2905 Append(for_array);
2904 arguments->Add(PushArgument(for_array.value())); 2906 arguments->Add(PushArgument(for_array.value()));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 // Resolve the store indexed operator in the super class. 2940 // Resolve the store indexed operator in the super class.
2939 super_function = &Function::ZoneHandle( 2941 super_function = &Function::ZoneHandle(
2940 Resolver::ResolveDynamicAnyArgs(node->super_class(), 2942 Resolver::ResolveDynamicAnyArgs(node->super_class(),
2941 Symbols::AssignIndexToken())); 2943 Symbols::AssignIndexToken()));
2942 if (super_function->IsNull()) { 2944 if (super_function->IsNull()) {
2943 // Could not resolve super operator. Generate call noSuchMethod() of the 2945 // Could not resolve super operator. Generate call noSuchMethod() of the
2944 // super class instead. 2946 // super class instead.
2945 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2947 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2946 arguments->Add(node->array()); 2948 arguments->Add(node->array());
2947 arguments->Add(node->index_expr()); 2949 arguments->Add(node->index_expr());
2948 2950 arguments->Add(node->value());
2949 // Even though noSuchMethod most likely does not return, 2951 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
2950 // we save the stored value if the result is needed. 2952 node->super_class(),
2951 if (result_is_needed) { 2953 node->array(),
2952 ValueGraphVisitor for_value(owner(), temp_index()); 2954 Symbols::AssignIndexToken(),
2953 node->value()->Visit(&for_value); 2955 arguments,
2954 Append(for_value); 2956 result_is_needed); // Save last arg if result is needed.
2955 Do(BuildStoreExprTemp(for_value.value()));
2956
2957 const LocalVariable* temp =
2958 owner()->parsed_function().expression_temp_var();
2959 AstNode* value = new LoadLocalNode(node->token_pos(), temp);
2960 arguments->Add(value);
2961 } else {
2962 arguments->Add(node->value());
2963 }
2964 StaticCallInstr* call =
2965 BuildStaticNoSuchMethodCall(node->super_class(),
2966 node->array(),
2967 Symbols::AssignIndexToken(),
2968 arguments);
2969 if (result_is_needed) { 2957 if (result_is_needed) {
2970 Do(call); 2958 Do(call);
2959 // BuildStaticNoSuchMethodCall stores the value in expression_temp.
2971 return BuildLoadExprTemp(); 2960 return BuildLoadExprTemp();
2972 } else { 2961 } else {
2973 return call; 2962 return call;
2974 } 2963 }
2975 } 2964 }
2976 } 2965 }
2977 2966
2978 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2967 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2979 new ZoneGrowableArray<PushArgumentInstr*>(3); 2968 new ZoneGrowableArray<PushArgumentInstr*>(3);
2980 ValueGraphVisitor for_array(owner(), temp_index()); 2969 ValueGraphVisitor for_array(owner(), temp_index());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); 3028 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded));
3040 } 3029 }
3041 3030
3042 3031
3043 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3032 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3044 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); 3033 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
3045 } 3034 }
3046 3035
3047 3036
3048 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 3037 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
3049 return (node == owner()->parsed_function().node_sequence()) && 3038 return (node == owner()->parsed_function()->node_sequence()) &&
3050 (owner()->parsed_function().saved_entry_context_var() != NULL); 3039 (owner()->parsed_function()->saved_entry_context_var() != NULL);
3051 } 3040 }
3052 3041
3053 3042
3054 void EffectGraphVisitor::UnchainContext() { 3043 void EffectGraphVisitor::UnchainContext() {
3055 InlineBailout("EffectGraphVisitor::UnchainContext (context)"); 3044 InlineBailout("EffectGraphVisitor::UnchainContext (context)");
3056 Value* context = Bind(new CurrentContextInstr()); 3045 Value* context = Bind(new CurrentContextInstr());
3057 Value* parent = Bind( 3046 Value* parent = Bind(
3058 new LoadFieldInstr(context, 3047 new LoadFieldInstr(context,
3059 Context::parent_offset(), 3048 Context::parent_offset(),
3060 Type::ZoneHandle())); // Not an instance, no type. 3049 Type::ZoneHandle())); // Not an instance, no type.
(...skipping 19 matching lines...) Expand all
3080 num_context_variables)); 3069 num_context_variables));
3081 3070
3082 // If this node_sequence is the body of the function being compiled, and if 3071 // If this node_sequence is the body of the function being compiled, and if
3083 // this function allocates context variables, but none of its enclosing 3072 // this function allocates context variables, but none of its enclosing
3084 // functions do, the context on entry is not linked as parent of the 3073 // functions do, the context on entry is not linked as parent of the
3085 // allocated context but saved on entry and restored on exit as to prevent 3074 // allocated context but saved on entry and restored on exit as to prevent
3086 // memory leaks. 3075 // memory leaks.
3087 // In this case, the parser pre-allocates a variable to save the context. 3076 // In this case, the parser pre-allocates a variable to save the context.
3088 if (MustSaveRestoreContext(node)) { 3077 if (MustSaveRestoreContext(node)) {
3089 Value* current_context = Bind(new CurrentContextInstr()); 3078 Value* current_context = Bind(new CurrentContextInstr());
3090 Do(BuildStoreTemp(*owner()->parsed_function().saved_entry_context_var(), 3079 Do(BuildStoreTemp(*owner()->parsed_function()->saved_entry_context_var(),
3091 current_context)); 3080 current_context));
3092 Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle())); 3081 Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle()));
3093 AddInstruction(new StoreContextInstr(null_context)); 3082 AddInstruction(new StoreContextInstr(null_context));
3094 } 3083 }
3095 3084
3096 AddInstruction(new ChainContextInstr(allocated_context)); 3085 AddInstruction(new ChainContextInstr(allocated_context));
3097 owner()->set_context_level(scope->context_level()); 3086 owner()->set_context_level(scope->context_level());
3098 3087
3099 // If this node_sequence is the body of the function being compiled, copy 3088 // If this node_sequence is the body of the function being compiled, copy
3100 // the captured parameters from the frame into the context. 3089 // the captured parameters from the frame into the context.
3101 if (node == owner()->parsed_function().node_sequence()) { 3090 if (node == owner()->parsed_function()->node_sequence()) {
3102 ASSERT(scope->context_level() == 1); 3091 ASSERT(scope->context_level() == 1);
3103 const Function& function = owner()->parsed_function().function(); 3092 const Function& function = owner()->parsed_function()->function();
3104 int num_params = function.NumParameters(); 3093 int num_params = function.NumParameters();
3105 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3094 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3106 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3095 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3107 // Handle the saved arguments descriptor as an additional parameter. 3096 // Handle the saved arguments descriptor as an additional parameter.
3108 if (owner()->parsed_function().GetSavedArgumentsDescriptorVar() != NULL) { 3097 if (owner()->parsed_function()->GetSavedArgumentsDescriptorVar() !=
3098 NULL) {
3109 ASSERT(param_frame_index == kFirstLocalSlotFromFp); 3099 ASSERT(param_frame_index == kFirstLocalSlotFromFp);
3110 num_params++; 3100 num_params++;
3111 } 3101 }
3112 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3102 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3113 const LocalVariable& parameter = *scope->VariableAt(pos); 3103 const LocalVariable& parameter = *scope->VariableAt(pos);
3114 ASSERT(parameter.owner() == scope); 3104 ASSERT(parameter.owner() == scope);
3115 if (parameter.is_captured()) { 3105 if (parameter.is_captured()) {
3116 // Create a temporary local describing the original position. 3106 // Create a temporary local describing the original position.
3117 const String& temp_name = String::ZoneHandle(String::Concat( 3107 const String& temp_name = String::ZoneHandle(String::Concat(
3118 parameter.name(), String::Handle(Symbols::New("-orig")))); 3108 parameter.name(), String::Handle(Symbols::New("-orig"))));
(...skipping 11 matching lines...) Expand all
3130 // the function. 3120 // the function.
3131 Value* null_constant = 3121 Value* null_constant =
3132 Bind(new ConstantInstr(Object::ZoneHandle())); 3122 Bind(new ConstantInstr(Object::ZoneHandle()));
3133 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded)); 3123 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded));
3134 } 3124 }
3135 } 3125 }
3136 } 3126 }
3137 } 3127 }
3138 3128
3139 if (FLAG_enable_type_checks && 3129 if (FLAG_enable_type_checks &&
3140 (node == owner()->parsed_function().node_sequence())) { 3130 (node == owner()->parsed_function()->node_sequence())) {
3141 const Function& function = owner()->parsed_function().function(); 3131 const Function& function = owner()->parsed_function()->function();
3142 const int num_params = function.NumParameters(); 3132 const int num_params = function.NumParameters();
3143 int pos = 0; 3133 int pos = 0;
3144 if (function.IsConstructor()) { 3134 if (function.IsConstructor()) {
3145 // Skip type checking of receiver and phase for constructor functions. 3135 // Skip type checking of receiver and phase for constructor functions.
3146 pos = 2; 3136 pos = 2;
3147 } else if (function.IsFactory() || function.IsDynamicFunction()) { 3137 } else if (function.IsFactory() || function.IsDynamicFunction()) {
3148 // Skip type checking of type arguments for factory functions. 3138 // Skip type checking of type arguments for factory functions.
3149 // Skip type checking of receiver for instance functions. 3139 // Skip type checking of receiver for instance functions.
3150 pos = 1; 3140 pos = 1;
3151 } 3141 }
(...skipping 27 matching lines...) Expand all
3179 Append(for_effect); 3169 Append(for_effect);
3180 if (!is_open()) { 3170 if (!is_open()) {
3181 // E.g., because of a JumpNode. 3171 // E.g., because of a JumpNode.
3182 break; 3172 break;
3183 } 3173 }
3184 } 3174 }
3185 3175
3186 if (is_open()) { 3176 if (is_open()) {
3187 if (MustSaveRestoreContext(node)) { 3177 if (MustSaveRestoreContext(node)) {
3188 ASSERT(num_context_variables > 0); 3178 ASSERT(num_context_variables > 0);
3189 BuildLoadContext(*owner()->parsed_function().saved_entry_context_var()); 3179 BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var());
3190 } else if (num_context_variables > 0) { 3180 } else if (num_context_variables > 0) {
3191 UnchainContext(); 3181 UnchainContext();
3192 } 3182 }
3193 } 3183 }
3194 3184
3195 // No continue on sequence allowed. 3185 // No continue on sequence allowed.
3196 ASSERT((node->label() == NULL) || 3186 ASSERT((node->label() == NULL) ||
3197 (node->label()->join_for_continue() == NULL)); 3187 (node->label()->join_for_continue() == NULL));
3198 // If this node sequence is labeled, a break out of the sequence will have 3188 // If this node sequence is labeled, a break out of the sequence will have
3199 // taken care of unchaining the context. 3189 // taken care of unchaining the context.
3200 if ((node->label() != NULL) && 3190 if ((node->label() != NULL) &&
3201 (node->label()->join_for_break() != NULL)) { 3191 (node->label()->join_for_break() != NULL)) {
3202 if (is_open()) Goto(node->label()->join_for_break()); 3192 if (is_open()) Goto(node->label()->join_for_break());
3203 exit_ = node->label()->join_for_break(); 3193 exit_ = node->label()->join_for_break();
3204 } 3194 }
3205 3195
3206 // The outermost function sequence cannot contain a label. 3196 // The outermost function sequence cannot contain a label.
3207 ASSERT((node->label() == NULL) || 3197 ASSERT((node->label() == NULL) ||
3208 (node != owner()->parsed_function().node_sequence())); 3198 (node != owner()->parsed_function()->node_sequence()));
3209 owner()->set_context_level(previous_context_level); 3199 owner()->set_context_level(previous_context_level);
3210 } 3200 }
3211 3201
3212 3202
3213 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 3203 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
3214 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); 3204 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
3215 // NOTE: The implicit variables ':saved_context', ':exception_var' 3205 // NOTE: The implicit variables ':saved_context', ':exception_var'
3216 // and ':stacktrace_var' can never be captured variables. 3206 // and ':stacktrace_var' can never be captured variables.
3217 // Restores CTX from local variable ':saved_context'. 3207 // Restores CTX from local variable ':saved_context'.
3218 AddInstruction( 3208 AddInstruction(
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 } 3300 }
3311 } 3301 }
3312 3302
3313 3303
3314 // Looks up dynamic method noSuchMethod in target_class 3304 // Looks up dynamic method noSuchMethod in target_class
3315 // (including its super class chain) and builds a static call to it. 3305 // (including its super class chain) and builds a static call to it.
3316 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( 3306 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
3317 const Class& target_class, 3307 const Class& target_class,
3318 AstNode* receiver, 3308 AstNode* receiver,
3319 const String& method_name, 3309 const String& method_name,
3320 ArgumentListNode* method_arguments) { 3310 ArgumentListNode* method_arguments,
3321 // Build the graph to allocate an InvocationMirror object by calling 3311 bool save_last_arg) {
3322 // the static allocation method. 3312 intptr_t args_pos = method_arguments->token_pos();
3323 const Library& corelib = Library::Handle(Library::CoreLibrary()); 3313 LocalVariable* temp = NULL;
3324 const Class& mirror_class = Class::Handle( 3314 if (save_last_arg) {
3325 corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); 3315 temp = owner()->parsed_function()->EnsureExpressionTemp();
3326 ASSERT(!mirror_class.IsNull());
3327 const Function& allocation_function = Function::ZoneHandle(
3328 Resolver::ResolveStaticByName(
3329 mirror_class,
3330 PrivateCoreLibName(Symbols::AllocateInvocationMirror()),
3331 Resolver::kIsQualified));
3332 ASSERT(!allocation_function.IsNull());
3333
3334 // Evaluate the receiver before the arguments. This will be used
3335 // as an argument to the noSuchMethod call.
3336 ValueGraphVisitor for_receiver(owner(), temp_index());
3337 receiver->Visit(&for_receiver);
3338 Append(for_receiver);
3339 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
3340
3341 // Allocate the arguments and pass them into the construction
3342 // of the InvocationMirror.
3343 const intptr_t args_pos = method_arguments->token_pos();
3344 ArgumentListNode* arguments = new ArgumentListNode(args_pos);
3345 // The first argument is the original method name.
3346 arguments->Add(new LiteralNode(args_pos, method_name));
3347 // The second argument is the arguments descriptor of the original method.
3348 const Array& args_descriptor =
3349 Array::ZoneHandle(ArgumentsDescriptor::New(method_arguments->length(),
3350 method_arguments->names()));
3351 arguments->Add(new LiteralNode(args_pos, args_descriptor));
3352 // The third argument is an array containing the original method arguments,
3353 // including the receiver.
3354 ArrayNode* args_array = new ArrayNode(
3355 args_pos,
3356 Type::ZoneHandle(Type::ArrayType()));
3357 for (intptr_t i = 0; i < method_arguments->length(); i++) {
3358 args_array->AddElement(method_arguments->NodeAt(i));
3359 } 3316 }
3360 arguments->Add(args_array); 3317 ArgumentListNode* args =
3361 ZoneGrowableArray<PushArgumentInstr*>* allocation_args = 3318 Parser::BuildNoSuchMethodArguments(args_pos,
3362 new ZoneGrowableArray<PushArgumentInstr*>(arguments->length()); 3319 method_name,
3363 BuildPushArguments(*arguments, allocation_args); 3320 *method_arguments,
3364 StaticCallInstr* allocation = new StaticCallInstr(args_pos, 3321 temp);
3365 allocation_function,
3366 Array::ZoneHandle(),
3367 allocation_args);
3368 Value* invocation_mirror = Bind(allocation);
3369 PushArgumentInstr* push_invocation_mirror = PushArgument(invocation_mirror);
3370 // Lookup noSuchMethod and call it with the receiver and the InvocationMirror.
3371 const Function& no_such_method_func = Function::ZoneHandle( 3322 const Function& no_such_method_func = Function::ZoneHandle(
3372 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); 3323 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod()));
3373 // We are guaranteed to find noSuchMethod of class Object. 3324 // We are guaranteed to find noSuchMethod of class Object.
3374 ASSERT(!no_such_method_func.IsNull()); 3325 ASSERT(!no_such_method_func.IsNull());
3375 ZoneGrowableArray<PushArgumentInstr*>* args = 3326 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
3376 new ZoneGrowableArray<PushArgumentInstr*>(2); 3327 new ZoneGrowableArray<PushArgumentInstr*>(2);
3377 args->Add(push_receiver); 3328 BuildPushArguments(*args, push_arguments);
3378 args->Add(push_invocation_mirror);
3379 return new StaticCallInstr(args_pos, 3329 return new StaticCallInstr(args_pos,
3380 no_such_method_func, 3330 no_such_method_func,
3381 Array::ZoneHandle(), 3331 Array::ZoneHandle(),
3382 args); 3332 push_arguments);
3383 } 3333 }
3384
3385
3386 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 3334 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
3387 intptr_t token_pos, 3335 intptr_t token_pos,
3388 const Class& function_class, 3336 const Class& function_class,
3389 const String& function_name, 3337 const String& function_name,
3390 int invocation_type) { 3338 int invocation_type) {
3391 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3339 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3392 new ZoneGrowableArray<PushArgumentInstr*>(); 3340 new ZoneGrowableArray<PushArgumentInstr*>();
3393 // Object receiver. 3341 // Object receiver.
3394 // TODO(regis): For now, we pass a class literal of the unresolved 3342 // TODO(regis): For now, we pass a class literal of the unresolved
3395 // method's owner, but this is not specified and will probably change. 3343 // method's owner, but this is not specified and will probably change.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 3452
3505 Goto(finally_entry); 3453 Goto(finally_entry);
3506 AppendFragment(finally_entry, for_finally_block); 3454 AppendFragment(finally_entry, for_finally_block);
3507 exit_ = for_finally_block.exit_; 3455 exit_ = for_finally_block.exit_;
3508 } 3456 }
3509 3457
3510 3458
3511 FlowGraph* FlowGraphBuilder::BuildGraph() { 3459 FlowGraph* FlowGraphBuilder::BuildGraph() {
3512 if (FLAG_print_ast) { 3460 if (FLAG_print_ast) {
3513 // Print the function ast before IL generation. 3461 // Print the function ast before IL generation.
3514 AstPrinter::PrintFunctionNodes(parsed_function()); 3462 AstPrinter::PrintFunctionNodes(*parsed_function());
3515 } 3463 }
3516 // Compilation can be nested, preserve the computation-id. 3464 // Compilation can be nested, preserve the computation-id.
3517 const Function& function = parsed_function().function(); 3465 const Function& function = parsed_function()->function();
3518 TargetEntryInstr* normal_entry = 3466 TargetEntryInstr* normal_entry =
3519 new TargetEntryInstr(AllocateBlockId(), 3467 new TargetEntryInstr(AllocateBlockId(),
3520 CatchClauseNode::kInvalidTryIndex); 3468 CatchClauseNode::kInvalidTryIndex);
3521 graph_entry_ = new GraphEntryInstr(parsed_function(), normal_entry); 3469 graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry);
3522 EffectGraphVisitor for_effect(this, 0); 3470 EffectGraphVisitor for_effect(this, 0);
3523 // This check may be deleted if the generated code is leaf. 3471 // This check may be deleted if the generated code is leaf.
3524 CheckStackOverflowInstr* check = 3472 CheckStackOverflowInstr* check =
3525 new CheckStackOverflowInstr(function.token_pos()); 3473 new CheckStackOverflowInstr(function.token_pos());
3526 // If we are inlining don't actually attach the stack check. We must still 3474 // If we are inlining don't actually attach the stack check. We must still
3527 // create the stack check in order to allocate a deopt id. 3475 // create the stack check in order to allocate a deopt id.
3528 if (!IsInlining()) for_effect.AddInstruction(check); 3476 if (!IsInlining()) for_effect.AddInstruction(check);
3529 parsed_function().node_sequence()->Visit(&for_effect); 3477 parsed_function()->node_sequence()->Visit(&for_effect);
3530 AppendFragment(normal_entry, for_effect); 3478 AppendFragment(normal_entry, for_effect);
3531 // Check that the graph is properly terminated. 3479 // Check that the graph is properly terminated.
3532 ASSERT(!for_effect.is_open()); 3480 ASSERT(!for_effect.is_open());
3533 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); 3481 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_);
3534 return graph; 3482 return graph;
3535 } 3483 }
3536 3484
3537 3485
3538 void FlowGraphBuilder::Bailout(const char* reason) { 3486 void FlowGraphBuilder::Bailout(const char* reason) {
3539 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 3487 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
3540 const char* function_name = parsed_function_.function().ToCString(); 3488 const char* function_name = parsed_function_->function().ToCString();
3541 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3489 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3542 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3490 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3543 OS::SNPrint(chars, len, kFormat, function_name, reason); 3491 OS::SNPrint(chars, len, kFormat, function_name, reason);
3544 const Error& error = Error::Handle( 3492 const Error& error = Error::Handle(
3545 LanguageError::New(String::Handle(String::New(chars)))); 3493 LanguageError::New(String::Handle(String::New(chars))));
3546 Isolate::Current()->long_jump_base()->Jump(1, error); 3494 Isolate::Current()->long_jump_base()->Jump(1, error);
3547 } 3495 }
3548 3496
3549 3497
3550 } // namespace dart 3498 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698