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/compiler.h" | 5 #include "vm/compiler.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 | 8 |
9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 67 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
68 if (!error.IsNull()) { | 68 if (!error.IsNull()) { |
69 Exceptions::PropagateError(error); | 69 Exceptions::PropagateError(error); |
70 } | 70 } |
71 } | 71 } |
72 | 72 |
73 | 73 |
74 RawError* Compiler::Compile(const Library& library, const Script& script) { | 74 RawError* Compiler::Compile(const Library& library, const Script& script) { |
75 Isolate* isolate = Isolate::Current(); | 75 Isolate* isolate = Isolate::Current(); |
76 StackZone zone(isolate); | 76 StackZone zone(isolate); |
77 LongJump* base = isolate->long_jump_base(); | 77 LongJumpScope jump; |
78 LongJump jump; | |
79 isolate->set_long_jump_base(&jump); | |
80 if (setjmp(*jump.Set()) == 0) { | 78 if (setjmp(*jump.Set()) == 0) { |
81 if (FLAG_trace_compiler) { | 79 if (FLAG_trace_compiler) { |
82 const String& script_url = String::Handle(script.url()); | 80 const String& script_url = String::Handle(script.url()); |
83 // TODO(iposva): Extract script kind. | 81 // TODO(iposva): Extract script kind. |
84 OS::Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 82 OS::Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
85 } | 83 } |
86 const String& library_key = String::Handle(library.private_key()); | 84 const String& library_key = String::Handle(library.private_key()); |
87 script.Tokenize(library_key); | 85 script.Tokenize(library_key); |
88 Parser::ParseCompilationUnit(library, script); | 86 Parser::ParseCompilationUnit(library, script); |
89 isolate->set_long_jump_base(base); | |
90 return Error::null(); | 87 return Error::null(); |
91 } else { | 88 } else { |
92 Error& error = Error::Handle(); | 89 Error& error = Error::Handle(); |
93 error = isolate->object_store()->sticky_error(); | 90 error = isolate->object_store()->sticky_error(); |
94 isolate->object_store()->clear_sticky_error(); | 91 isolate->object_store()->clear_sticky_error(); |
95 isolate->set_long_jump_base(base); | |
96 return error.raw(); | 92 return error.raw(); |
97 } | 93 } |
98 UNREACHABLE(); | 94 UNREACHABLE(); |
99 return Error::null(); | 95 return Error::null(); |
100 } | 96 } |
101 | 97 |
102 | 98 |
103 static void AddRelatedClassesToList(const Class& cls, | 99 static void AddRelatedClassesToList(const Class& cls, |
104 const GrowableObjectArray& parse_list, | 100 const GrowableObjectArray& parse_list, |
105 const GrowableObjectArray& patch_list) { | 101 const GrowableObjectArray& patch_list) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 // also allows us to reset the marked_for_parsing state in case we see an | 157 // also allows us to reset the marked_for_parsing state in case we see an |
162 // error. | 158 // error. |
163 Class& parse_class = Class::Handle(); | 159 Class& parse_class = Class::Handle(); |
164 const GrowableObjectArray& parse_list = | 160 const GrowableObjectArray& parse_list = |
165 GrowableObjectArray::Handle(GrowableObjectArray::New(4)); | 161 GrowableObjectArray::Handle(GrowableObjectArray::New(4)); |
166 const GrowableObjectArray& patch_list = | 162 const GrowableObjectArray& patch_list = |
167 GrowableObjectArray::Handle(GrowableObjectArray::New(4)); | 163 GrowableObjectArray::Handle(GrowableObjectArray::New(4)); |
168 | 164 |
169 // Parse the class and all the interfaces it implements and super classes. | 165 // Parse the class and all the interfaces it implements and super classes. |
170 StackZone zone(isolate); | 166 StackZone zone(isolate); |
171 LongJump* base = isolate->long_jump_base(); | 167 LongJumpScope jump; |
172 LongJump jump; | |
173 isolate->set_long_jump_base(&jump); | |
174 if (setjmp(*jump.Set()) == 0) { | 168 if (setjmp(*jump.Set()) == 0) { |
175 if (FLAG_trace_compiler) { | 169 if (FLAG_trace_compiler) { |
176 OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString()); | 170 OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString()); |
177 } | 171 } |
178 | 172 |
179 // Add the primary class which needs to be parsed to the parse list. | 173 // Add the primary class which needs to be parsed to the parse list. |
180 // Mark the class as parsed so that we don't recursively add the same | 174 // Mark the class as parsed so that we don't recursively add the same |
181 // class back into the list. | 175 // class back into the list. |
182 parse_list.Add(cls); | 176 parse_list.Add(cls); |
183 cls.set_is_marked_for_parsing(); | 177 cls.set_is_marked_for_parsing(); |
(...skipping 24 matching lines...) Expand all Loading... |
208 } | 202 } |
209 | 203 |
210 // Finalize these classes. | 204 // Finalize these classes. |
211 for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) { | 205 for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) { |
212 parse_class ^= parse_list.At(i); | 206 parse_class ^= parse_list.At(i); |
213 ASSERT(!parse_class.IsNull()); | 207 ASSERT(!parse_class.IsNull()); |
214 ClassFinalizer::FinalizeClass(parse_class); | 208 ClassFinalizer::FinalizeClass(parse_class); |
215 parse_class.reset_is_marked_for_parsing(); | 209 parse_class.reset_is_marked_for_parsing(); |
216 } | 210 } |
217 | 211 |
218 isolate->set_long_jump_base(base); | |
219 return Error::null(); | 212 return Error::null(); |
220 } else { | 213 } else { |
221 // Reset the marked for parsing flags. | 214 // Reset the marked for parsing flags. |
222 for (intptr_t i = 0; i < parse_list.Length(); i++) { | 215 for (intptr_t i = 0; i < parse_list.Length(); i++) { |
223 parse_class ^= parse_list.At(i); | 216 parse_class ^= parse_list.At(i); |
224 if (parse_class.is_marked_for_parsing()) { | 217 if (parse_class.is_marked_for_parsing()) { |
225 parse_class.reset_is_marked_for_parsing(); | 218 parse_class.reset_is_marked_for_parsing(); |
226 } | 219 } |
227 } | 220 } |
228 for (intptr_t i = 0; i < patch_list.Length(); i++) { | 221 for (intptr_t i = 0; i < patch_list.Length(); i++) { |
229 parse_class ^= patch_list.At(i); | 222 parse_class ^= patch_list.At(i); |
230 if (parse_class.is_marked_for_parsing()) { | 223 if (parse_class.is_marked_for_parsing()) { |
231 parse_class.reset_is_marked_for_parsing(); | 224 parse_class.reset_is_marked_for_parsing(); |
232 } | 225 } |
233 } | 226 } |
234 | 227 |
235 Error& error = Error::Handle(); | 228 Error& error = Error::Handle(); |
236 error = isolate->object_store()->sticky_error(); | 229 error = isolate->object_store()->sticky_error(); |
237 isolate->object_store()->clear_sticky_error(); | 230 isolate->object_store()->clear_sticky_error(); |
238 isolate->set_long_jump_base(base); | |
239 return error.raw(); | 231 return error.raw(); |
240 } | 232 } |
241 UNREACHABLE(); | 233 UNREACHABLE(); |
242 return Error::null(); | 234 return Error::null(); |
243 } | 235 } |
244 | 236 |
245 | 237 |
246 static void InstallUnoptimizedCode(const Function& function) { | 238 static void InstallUnoptimizedCode(const Function& function) { |
247 // Disable optimized code. | 239 // Disable optimized code. |
248 ASSERT(function.HasOptimizedCode()); | 240 ASSERT(function.HasOptimizedCode()); |
(...skipping 27 matching lines...) Expand all Loading... |
276 // done is set to false, and use_far_branches is set to true if there is a | 268 // done is set to false, and use_far_branches is set to true if there is a |
277 // longjmp from the ARM or MIPS assemblers. In all other paths through this | 269 // longjmp from the ARM or MIPS assemblers. In all other paths through this |
278 // while loop, done is set to true. use_far_branches is always false on ia32 | 270 // while loop, done is set to true. use_far_branches is always false on ia32 |
279 // and x64. | 271 // and x64. |
280 bool done = false; | 272 bool done = false; |
281 // volatile because the variable may be clobbered by a longjmp. | 273 // volatile because the variable may be clobbered by a longjmp. |
282 volatile bool use_far_branches = false; | 274 volatile bool use_far_branches = false; |
283 while (!done) { | 275 while (!done) { |
284 const intptr_t prev_deopt_id = isolate->deopt_id(); | 276 const intptr_t prev_deopt_id = isolate->deopt_id(); |
285 isolate->set_deopt_id(0); | 277 isolate->set_deopt_id(0); |
286 LongJump* old_base = isolate->long_jump_base(); | 278 LongJumpScope jump; |
287 LongJump bailout_jump; | 279 if (setjmp(*jump.Set()) == 0) { |
288 isolate->set_long_jump_base(&bailout_jump); | |
289 if (setjmp(*bailout_jump.Set()) == 0) { | |
290 FlowGraph* flow_graph = NULL; | 280 FlowGraph* flow_graph = NULL; |
291 // TimerScope needs an isolate to be properly terminated in case of a | 281 // TimerScope needs an isolate to be properly terminated in case of a |
292 // LongJump. | 282 // LongJump. |
293 { | 283 { |
294 TimerScope timer(FLAG_compiler_stats, | 284 TimerScope timer(FLAG_compiler_stats, |
295 &CompilerStats::graphbuilder_timer, | 285 &CompilerStats::graphbuilder_timer, |
296 isolate); | 286 isolate); |
297 Array& ic_data_array = Array::Handle(); | 287 Array& ic_data_array = Array::Handle(); |
298 if (optimized) { | 288 if (optimized) { |
299 ASSERT(function.HasCode()); | 289 ASSERT(function.HasCode()); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 OS::Print("%s\n", bailout_error.ToErrorCString()); | 591 OS::Print("%s\n", bailout_error.ToErrorCString()); |
602 } | 592 } |
603 done = true; | 593 done = true; |
604 ASSERT(optimized); | 594 ASSERT(optimized); |
605 } | 595 } |
606 | 596 |
607 isolate->object_store()->clear_sticky_error(); | 597 isolate->object_store()->clear_sticky_error(); |
608 is_compiled = false; | 598 is_compiled = false; |
609 } | 599 } |
610 // Reset global isolate state. | 600 // Reset global isolate state. |
611 isolate->set_long_jump_base(old_base); | |
612 isolate->set_deopt_id(prev_deopt_id); | 601 isolate->set_deopt_id(prev_deopt_id); |
613 } | 602 } |
614 return is_compiled; | 603 return is_compiled; |
615 } | 604 } |
616 | 605 |
617 | 606 |
618 static void DisassembleCode(const Function& function, bool optimized) { | 607 static void DisassembleCode(const Function& function, bool optimized) { |
619 const char* function_fullname = function.ToFullyQualifiedCString(); | 608 const char* function_fullname = function.ToFullyQualifiedCString(); |
620 OS::Print("Code for %sfunction '%s' {\n", | 609 OS::Print("Code for %sfunction '%s' {\n", |
621 optimized ? "optimized " : "", | 610 optimized ? "optimized " : "", |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 OS::Print("}\n"); | 727 OS::Print("}\n"); |
739 } | 728 } |
740 } | 729 } |
741 | 730 |
742 | 731 |
743 static RawError* CompileFunctionHelper(const Function& function, | 732 static RawError* CompileFunctionHelper(const Function& function, |
744 bool optimized, | 733 bool optimized, |
745 intptr_t osr_id) { | 734 intptr_t osr_id) { |
746 Isolate* isolate = Isolate::Current(); | 735 Isolate* isolate = Isolate::Current(); |
747 StackZone zone(isolate); | 736 StackZone zone(isolate); |
748 LongJump* base = isolate->long_jump_base(); | 737 LongJumpScope jump; |
749 LongJump jump; | |
750 isolate->set_long_jump_base(&jump); | |
751 // Make sure unoptimized code is not collected while we are compiling. | 738 // Make sure unoptimized code is not collected while we are compiling. |
752 const Code& unoptimized_code = Code::ZoneHandle(function.unoptimized_code()); | 739 const Code& unoptimized_code = Code::ZoneHandle(function.unoptimized_code()); |
753 // Skips parsing if we need to only install unoptimized code. | 740 // Skips parsing if we need to only install unoptimized code. |
754 if (!optimized && !unoptimized_code.IsNull()) { | 741 if (!optimized && !unoptimized_code.IsNull()) { |
755 InstallUnoptimizedCode(function); | 742 InstallUnoptimizedCode(function); |
756 isolate->set_long_jump_base(base); | |
757 return Error::null(); | 743 return Error::null(); |
758 } | 744 } |
759 if (setjmp(*jump.Set()) == 0) { | 745 if (setjmp(*jump.Set()) == 0) { |
760 TIMERSCOPE(time_compilation); | 746 TIMERSCOPE(time_compilation); |
761 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 747 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |
762 per_compile_timer.Start(); | 748 per_compile_timer.Start(); |
763 ParsedFunction* parsed_function = | 749 ParsedFunction* parsed_function = |
764 new ParsedFunction(Function::ZoneHandle(function.raw())); | 750 new ParsedFunction(Function::ZoneHandle(function.raw())); |
765 if (FLAG_trace_compiler) { | 751 if (FLAG_trace_compiler) { |
766 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 752 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
(...skipping 13 matching lines...) Expand all Loading... |
780 CompileParsedFunctionHelper(parsed_function, optimized, osr_id); | 766 CompileParsedFunctionHelper(parsed_function, optimized, osr_id); |
781 if (optimized && !success) { | 767 if (optimized && !success) { |
782 // Optimizer bailed out. Disable optimizations and to never try again. | 768 // Optimizer bailed out. Disable optimizations and to never try again. |
783 if (FLAG_trace_compiler) { | 769 if (FLAG_trace_compiler) { |
784 OS::Print("--> disabling optimizations for '%s'\n", | 770 OS::Print("--> disabling optimizations for '%s'\n", |
785 function.ToFullyQualifiedCString()); | 771 function.ToFullyQualifiedCString()); |
786 } else if (FLAG_trace_failed_optimization_attempts) { | 772 } else if (FLAG_trace_failed_optimization_attempts) { |
787 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); | 773 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); |
788 } | 774 } |
789 function.SetIsOptimizable(false); | 775 function.SetIsOptimizable(false); |
790 isolate->set_long_jump_base(base); | |
791 return Error::null(); | 776 return Error::null(); |
792 } | 777 } |
793 | 778 |
794 ASSERT(success); | 779 ASSERT(success); |
795 per_compile_timer.Stop(); | 780 per_compile_timer.Stop(); |
796 | 781 |
797 if (FLAG_trace_compiler) { | 782 if (FLAG_trace_compiler) { |
798 OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", | 783 OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |
799 function.ToFullyQualifiedCString(), | 784 function.ToFullyQualifiedCString(), |
800 Code::Handle(function.CurrentCode()).EntryPoint(), | 785 Code::Handle(function.CurrentCode()).EntryPoint(), |
801 Code::Handle(function.CurrentCode()).Size(), | 786 Code::Handle(function.CurrentCode()).Size(), |
802 per_compile_timer.TotalElapsedTime()); | 787 per_compile_timer.TotalElapsedTime()); |
803 } | 788 } |
804 | 789 |
805 isolate->debugger()->NotifyCompilation(function); | 790 isolate->debugger()->NotifyCompilation(function); |
806 | 791 |
807 if (FLAG_disassemble) { | 792 if (FLAG_disassemble) { |
808 DisassembleCode(function, optimized); | 793 DisassembleCode(function, optimized); |
809 } else if (FLAG_disassemble_optimized && optimized) { | 794 } else if (FLAG_disassemble_optimized && optimized) { |
810 // TODO(fschneider): Print unoptimized code along with the optimized code. | 795 // TODO(fschneider): Print unoptimized code along with the optimized code. |
811 OS::Print("*** BEGIN CODE\n"); | 796 OS::Print("*** BEGIN CODE\n"); |
812 DisassembleCode(function, true); | 797 DisassembleCode(function, true); |
813 OS::Print("*** END CODE\n"); | 798 OS::Print("*** END CODE\n"); |
814 } | 799 } |
815 | 800 |
816 isolate->set_long_jump_base(base); | |
817 return Error::null(); | 801 return Error::null(); |
818 } else { | 802 } else { |
819 Error& error = Error::Handle(); | 803 Error& error = Error::Handle(); |
820 // We got an error during compilation. | 804 // We got an error during compilation. |
821 error = isolate->object_store()->sticky_error(); | 805 error = isolate->object_store()->sticky_error(); |
822 isolate->object_store()->clear_sticky_error(); | 806 isolate->object_store()->clear_sticky_error(); |
823 isolate->set_long_jump_base(base); | |
824 return error.raw(); | 807 return error.raw(); |
825 } | 808 } |
826 UNREACHABLE(); | 809 UNREACHABLE(); |
827 return Error::null(); | 810 return Error::null(); |
828 } | 811 } |
829 | 812 |
830 | 813 |
831 RawError* Compiler::CompileFunction(const Function& function) { | 814 RawError* Compiler::CompileFunction(const Function& function) { |
832 return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); | 815 return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); |
833 } | 816 } |
834 | 817 |
835 | 818 |
836 RawError* Compiler::CompileOptimizedFunction(const Function& function, | 819 RawError* Compiler::CompileOptimizedFunction(const Function& function, |
837 intptr_t osr_id) { | 820 intptr_t osr_id) { |
838 return CompileFunctionHelper(function, true, osr_id); | 821 return CompileFunctionHelper(function, true, osr_id); |
839 } | 822 } |
840 | 823 |
841 | 824 |
842 RawError* Compiler::CompileParsedFunction( | 825 RawError* Compiler::CompileParsedFunction( |
843 ParsedFunction* parsed_function) { | 826 ParsedFunction* parsed_function) { |
844 Isolate* isolate = Isolate::Current(); | 827 Isolate* isolate = Isolate::Current(); |
845 LongJump* base = isolate->long_jump_base(); | 828 LongJumpScope jump; |
846 LongJump jump; | |
847 isolate->set_long_jump_base(&jump); | |
848 if (setjmp(*jump.Set()) == 0) { | 829 if (setjmp(*jump.Set()) == 0) { |
849 // Non-optimized code generator. | 830 // Non-optimized code generator. |
850 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); | 831 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |
851 if (FLAG_disassemble) { | 832 if (FLAG_disassemble) { |
852 DisassembleCode(parsed_function->function(), false); | 833 DisassembleCode(parsed_function->function(), false); |
853 } | 834 } |
854 isolate->set_long_jump_base(base); | |
855 return Error::null(); | 835 return Error::null(); |
856 } else { | 836 } else { |
857 Error& error = Error::Handle(); | 837 Error& error = Error::Handle(); |
858 // We got an error during compilation. | 838 // We got an error during compilation. |
859 error = isolate->object_store()->sticky_error(); | 839 error = isolate->object_store()->sticky_error(); |
860 isolate->object_store()->clear_sticky_error(); | 840 isolate->object_store()->clear_sticky_error(); |
861 isolate->set_long_jump_base(base); | |
862 return error.raw(); | 841 return error.raw(); |
863 } | 842 } |
864 UNREACHABLE(); | 843 UNREACHABLE(); |
865 return Error::null(); | 844 return Error::null(); |
866 } | 845 } |
867 | 846 |
868 | 847 |
869 RawError* Compiler::CompileAllFunctions(const Class& cls) { | 848 RawError* Compiler::CompileAllFunctions(const Class& cls) { |
870 Error& error = Error::Handle(); | 849 Error& error = Error::Handle(); |
871 Array& functions = Array::Handle(cls.functions()); | 850 Array& functions = Array::Handle(cls.functions()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 } | 883 } |
905 } | 884 } |
906 } | 885 } |
907 } | 886 } |
908 return error.raw(); | 887 return error.raw(); |
909 } | 888 } |
910 | 889 |
911 | 890 |
912 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 891 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
913 Isolate* isolate = Isolate::Current(); | 892 Isolate* isolate = Isolate::Current(); |
914 LongJump* base = isolate->long_jump_base(); | 893 LongJumpScope jump; |
915 LongJump jump; | |
916 isolate->set_long_jump_base(&jump); | |
917 if (setjmp(*jump.Set()) == 0) { | 894 if (setjmp(*jump.Set()) == 0) { |
918 if (FLAG_trace_compiler) { | 895 if (FLAG_trace_compiler) { |
919 OS::Print("compiling expression: "); | 896 OS::Print("compiling expression: "); |
920 AstPrinter::PrintNode(fragment); | 897 AstPrinter::PrintNode(fragment); |
921 } | 898 } |
922 | 899 |
923 // Create a dummy function object for the code generator. | 900 // Create a dummy function object for the code generator. |
924 // The function needs to be associated with a named Class: the interface | 901 // The function needs to be associated with a named Class: the interface |
925 // Function fits the bill. | 902 // Function fits the bill. |
926 const char* kEvalConst = "eval_const"; | 903 const char* kEvalConst = "eval_const"; |
(...skipping 22 matching lines...) Expand all Loading... |
949 parsed_function->set_default_parameter_values(Object::null_array()); | 926 parsed_function->set_default_parameter_values(Object::null_array()); |
950 parsed_function->EnsureExpressionTemp(); | 927 parsed_function->EnsureExpressionTemp(); |
951 fragment->scope()->AddVariable(parsed_function->expression_temp_var()); | 928 fragment->scope()->AddVariable(parsed_function->expression_temp_var()); |
952 parsed_function->AllocateVariables(); | 929 parsed_function->AllocateVariables(); |
953 | 930 |
954 // Non-optimized code generator. | 931 // Non-optimized code generator. |
955 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); | 932 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |
956 | 933 |
957 const Object& result = Object::Handle( | 934 const Object& result = Object::Handle( |
958 DartEntry::InvokeFunction(func, Object::empty_array())); | 935 DartEntry::InvokeFunction(func, Object::empty_array())); |
959 isolate->set_long_jump_base(base); | |
960 return result.raw(); | 936 return result.raw(); |
961 } else { | 937 } else { |
962 const Object& result = | 938 const Object& result = |
963 Object::Handle(isolate->object_store()->sticky_error()); | 939 Object::Handle(isolate->object_store()->sticky_error()); |
964 isolate->object_store()->clear_sticky_error(); | 940 isolate->object_store()->clear_sticky_error(); |
965 isolate->set_long_jump_base(base); | |
966 return result.raw(); | 941 return result.raw(); |
967 } | 942 } |
968 UNREACHABLE(); | 943 UNREACHABLE(); |
969 return Object::null(); | 944 return Object::null(); |
970 } | 945 } |
971 | 946 |
972 } // namespace dart | 947 } // namespace dart |
OLD | NEW |