| 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/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/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 } | 583 } |
| 584 | 584 |
| 585 | 585 |
| 586 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { | 586 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { |
| 587 ASSERT(is_open()); | 587 ASSERT(is_open()); |
| 588 if (is_empty()) { | 588 if (is_empty()) { |
| 589 entry_ = new GotoInstr(join); | 589 entry_ = new GotoInstr(join); |
| 590 } else { | 590 } else { |
| 591 exit()->Goto(join); | 591 exit()->Goto(join); |
| 592 } | 592 } |
| 593 exit_ = NULL; | 593 CloseFragment(); |
| 594 } | 594 } |
| 595 | 595 |
| 596 | 596 |
| 597 // Appends a graph fragment to a block entry instruction. Returns the entry | 597 // Appends a graph fragment to a block entry instruction. Returns the entry |
| 598 // instruction if the fragment was empty or else the exit of the fragment if | 598 // instruction if the fragment was empty or else the exit of the fragment if |
| 599 // it was non-empty (so NULL if the fragment is closed). | 599 // it was non-empty (so NULL if the fragment is closed). |
| 600 // | 600 // |
| 601 // Note that the fragment is no longer a valid fragment after calling this | 601 // Note that the fragment is no longer a valid fragment after calling this |
| 602 // function -- the fragment is closed at its entry because the entry has a | 602 // function -- the fragment is closed at its entry because the entry has a |
| 603 // predecessor in the graph. | 603 // predecessor in the graph. |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 if (owner()->IsInlining()) owner()->Bailout(reason); | 942 if (owner()->IsInlining()) owner()->Bailout(reason); |
| 943 } | 943 } |
| 944 | 944 |
| 945 | 945 |
| 946 // <Statement> ::= Return { value: <Expression> | 946 // <Statement> ::= Return { value: <Expression> |
| 947 // inlined_finally_list: <InlinedFinally>* } | 947 // inlined_finally_list: <InlinedFinally>* } |
| 948 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 948 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 949 ValueGraphVisitor for_value(owner()); | 949 ValueGraphVisitor for_value(owner()); |
| 950 node->value()->Visit(&for_value); | 950 node->value()->Visit(&for_value); |
| 951 Append(for_value); | 951 Append(for_value); |
| 952 Value* return_value = for_value.value(); |
| 952 | 953 |
| 953 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 954 if (node->inlined_finally_list_length() > 0) { |
| 954 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); | 955 LocalVariable* temp = node->saved_return_value_var(); |
| 955 EffectGraphVisitor for_effect(owner()); | 956 Do(BuildStoreLocal(*temp, return_value, kResultNotNeeded)); |
| 956 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 957 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 957 Append(for_effect); | 958 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); |
| 958 if (!is_open()) { | 959 EffectGraphVisitor for_effect(owner()); |
| 959 owner()->DeallocateTemps(owner()->temp_count()); | 960 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 960 return; | 961 Append(for_effect); |
| 962 if (!is_open()) { |
| 963 return; |
| 964 } |
| 961 } | 965 } |
| 966 return_value = Bind(BuildLoadLocal(*temp)); |
| 962 } | 967 } |
| 963 | 968 |
| 964 // Call to stub that checks whether the debugger is in single | 969 // Call to stub that checks whether the debugger is in single |
| 965 // step mode. This call must happen before the contexts are | 970 // step mode. This call must happen before the contexts are |
| 966 // unchained so that captured variables can be inspected. | 971 // unchained so that captured variables can be inspected. |
| 967 // No debugger check is done in native functions or for return | 972 // No debugger check is done in native functions or for return |
| 968 // statements for which there is no associated source position. | 973 // statements for which there is no associated source position. |
| 969 const Function& function = owner()->parsed_function()->function(); | 974 const Function& function = owner()->parsed_function()->function(); |
| 970 if ((node->token_pos() != Scanner::kNoSourcePos) && | 975 if ((node->token_pos() != Scanner::kNoSourcePos) && |
| 971 !function.is_native()) { | 976 !function.is_native()) { |
| 972 AddInstruction(new DebugStepCheckInstr(node->token_pos(), | 977 AddInstruction(new DebugStepCheckInstr(node->token_pos(), |
| 973 PcDescriptors::kReturn)); | 978 PcDescriptors::kReturn)); |
| 974 } | 979 } |
| 975 | 980 |
| 976 Value* return_value = for_value.value(); | |
| 977 if (FLAG_enable_type_checks) { | 981 if (FLAG_enable_type_checks) { |
| 978 const bool is_implicit_dynamic_getter = | 982 const bool is_implicit_dynamic_getter = |
| 979 (!function.is_static() && | 983 (!function.is_static() && |
| 980 ((function.kind() == RawFunction::kImplicitGetter) || | 984 ((function.kind() == RawFunction::kImplicitGetter) || |
| 981 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); | 985 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); |
| 982 // Implicit getters do not need a type check at return, unless they compute | 986 // Implicit getters do not need a type check at return, unless they compute |
| 983 // the initial value of a static field. | 987 // the initial value of a static field. |
| 984 // The body of a constructor cannot modify the type of the | 988 // The body of a constructor cannot modify the type of the |
| 985 // constructed instance, which is passed in as an implicit parameter. | 989 // constructed instance, which is passed in as an implicit parameter. |
| 986 // However, factories may create an instance of the wrong type. | 990 // However, factories may create an instance of the wrong type. |
| (...skipping 3064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4051 LanguageError::kError, | 4055 LanguageError::kError, |
| 4052 Heap::kNew, | 4056 Heap::kNew, |
| 4053 "FlowGraphBuilder Bailout: %s %s", | 4057 "FlowGraphBuilder Bailout: %s %s", |
| 4054 String::Handle(function.name()).ToCString(), | 4058 String::Handle(function.name()).ToCString(), |
| 4055 reason)); | 4059 reason)); |
| 4056 Isolate::Current()->long_jump_base()->Jump(1, error); | 4060 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 4057 } | 4061 } |
| 4058 | 4062 |
| 4059 | 4063 |
| 4060 } // namespace dart | 4064 } // namespace dart |
| OLD | NEW |