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

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

Issue 9706086: Clean-up CodeGenState: remove unused loop_level and move context_level to CodeGenerator (and add it… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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
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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 23 matching lines...) Expand all
34 // CodeGenerator::HandlerList can probably be moved to code_generator.cc, since 34 // CodeGenerator::HandlerList can probably be moved to code_generator.cc, since
35 // they seem to be architecture independent. 35 // they seem to be architecture independent.
36 36
37 37
38 CodeGeneratorState::CodeGeneratorState(CodeGenerator* codegen) 38 CodeGeneratorState::CodeGeneratorState(CodeGenerator* codegen)
39 : StackResource(Isolate::Current()), 39 : StackResource(Isolate::Current()),
40 codegen_(codegen), 40 codegen_(codegen),
41 parent_(codegen->state()) { 41 parent_(codegen->state()) {
42 if (parent_ != NULL) { 42 if (parent_ != NULL) {
43 root_node_ = parent_->root_node_; 43 root_node_ = parent_->root_node_;
44 loop_level_ = parent_->loop_level_;
45 context_level_ = parent_->context_level_;
46 current_try_index_ = parent_->current_try_index_; 44 current_try_index_ = parent_->current_try_index_;
47 } else { 45 } else {
48 root_node_ = NULL; 46 root_node_ = NULL;
49 loop_level_ = 0;
50 context_level_ = 0;
51 current_try_index_ = CatchClauseNode::kInvalidTryIndex; 47 current_try_index_ = CatchClauseNode::kInvalidTryIndex;
52 } 48 }
53 codegen_->set_state(this); 49 codegen_->set_state(this);
54 } 50 }
55 51
56 52
57 CodeGeneratorState::~CodeGeneratorState() { 53 CodeGeneratorState::~CodeGeneratorState() {
58 codegen_->set_state(parent_); 54 codegen_->set_state(parent_);
59 } 55 }
60 56
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 104
109 105
110 CodeGenerator::CodeGenerator(Assembler* assembler, 106 CodeGenerator::CodeGenerator(Assembler* assembler,
111 const ParsedFunction& parsed_function) 107 const ParsedFunction& parsed_function)
112 : assembler_(assembler), 108 : assembler_(assembler),
113 parsed_function_(parsed_function), 109 parsed_function_(parsed_function),
114 locals_space_size_(-1), 110 locals_space_size_(-1),
115 state_(NULL), 111 state_(NULL),
116 pc_descriptors_list_(NULL), 112 pc_descriptors_list_(NULL),
117 exception_handlers_list_(NULL), 113 exception_handlers_list_(NULL),
118 try_index_(CatchClauseNode::kInvalidTryIndex) { 114 try_index_(CatchClauseNode::kInvalidTryIndex),
115 context_level_(0) {
119 ASSERT(assembler_ != NULL); 116 ASSERT(assembler_ != NULL);
120 ASSERT(parsed_function.node_sequence() != NULL); 117 ASSERT(parsed_function.node_sequence() != NULL);
121 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); 118 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump());
122 pc_descriptors_list_ = new CodeGenerator::DescriptorList(); 119 pc_descriptors_list_ = new CodeGenerator::DescriptorList();
123 exception_handlers_list_ = new CodeGenerator::HandlerList(); 120 exception_handlers_list_ = new CodeGenerator::HandlerList();
124 } 121 }
125 122
126 123
127 bool CodeGenerator::IsResultNeeded(AstNode* node) const { 124 bool CodeGenerator::IsResultNeeded(AstNode* node) const {
128 return !state()->IsRootNode(node); 125 return !state()->IsRootNode(node);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( 230 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
234 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); 231 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
235 code.set_exception_handlers(handlers); 232 code.set_exception_handlers(handlers);
236 } 233 }
237 234
238 235
239 void CodeGenerator::GenerateLoadVariable(Register dst, 236 void CodeGenerator::GenerateLoadVariable(Register dst,
240 const LocalVariable& variable) { 237 const LocalVariable& variable) {
241 if (variable.is_captured()) { 238 if (variable.is_captured()) {
242 // The variable lives in the context. 239 // The variable lives in the context.
243 int delta = state()->context_level() - variable.owner()->context_level(); 240 intptr_t delta = context_level() - variable.owner()->context_level();
244 ASSERT(delta >= 0); 241 ASSERT(delta >= 0);
245 Register base = CTX; 242 Register base = CTX;
246 while (delta-- > 0) { 243 while (delta-- > 0) {
247 __ movq(dst, FieldAddress(base, Context::parent_offset())); 244 __ movq(dst, FieldAddress(base, Context::parent_offset()));
248 base = dst; 245 base = dst;
249 } 246 }
250 __ movq(dst, 247 __ movq(dst,
251 FieldAddress(base, Context::variable_offset(variable.index()))); 248 FieldAddress(base, Context::variable_offset(variable.index())));
252 } else { 249 } else {
253 // The variable lives in the current stack frame. 250 // The variable lives in the current stack frame.
254 __ movq(dst, Address(RBP, variable.index() * kWordSize)); 251 __ movq(dst, Address(RBP, variable.index() * kWordSize));
255 } 252 }
256 } 253 }
257 254
258 255
259 void CodeGenerator::GenerateStoreVariable(const LocalVariable& variable, 256 void CodeGenerator::GenerateStoreVariable(const LocalVariable& variable,
260 Register src, 257 Register src,
261 Register scratch) { 258 Register scratch) {
262 if (variable.is_captured()) { 259 if (variable.is_captured()) {
263 // The variable lives in the context. 260 // The variable lives in the context.
264 int delta = state()->context_level() - variable.owner()->context_level(); 261 intptr_t delta = context_level() - variable.owner()->context_level();
265 ASSERT(delta >= 0); 262 ASSERT(delta >= 0);
266 Register base = CTX; 263 Register base = CTX;
267 while (delta-- > 0) { 264 while (delta-- > 0) {
268 __ movq(scratch, FieldAddress(base, Context::parent_offset())); 265 __ movq(scratch, FieldAddress(base, Context::parent_offset()));
269 base = scratch; 266 base = scratch;
270 } 267 }
271 __ StoreIntoObject( 268 __ StoreIntoObject(
272 base, 269 base,
273 FieldAddress(base, Context::variable_offset(variable.index())), 270 FieldAddress(base, Context::variable_offset(variable.index())),
274 src); 271 src);
275 } else { 272 } else {
276 // The variable lives in the current stack frame. 273 // The variable lives in the current stack frame.
277 __ movq(Address(RBP, variable.index() * kWordSize), src); 274 __ movq(Address(RBP, variable.index() * kWordSize), src);
278 } 275 }
279 } 276 }
280 277
281 278
282 void CodeGenerator::GeneratePushVariable(const LocalVariable& variable, 279 void CodeGenerator::GeneratePushVariable(const LocalVariable& variable,
283 Register scratch) { 280 Register scratch) {
284 if (variable.is_captured()) { 281 if (variable.is_captured()) {
285 // The variable lives in the context. 282 // The variable lives in the context.
286 int delta = state()->context_level() - variable.owner()->context_level(); 283 intptr_t delta = context_level() - variable.owner()->context_level();
287 ASSERT(delta >= 0); 284 ASSERT(delta >= 0);
288 Register base = CTX; 285 Register base = CTX;
289 while (delta-- > 0) { 286 while (delta-- > 0) {
290 __ movq(scratch, FieldAddress(base, Context::parent_offset())); 287 __ movq(scratch, FieldAddress(base, Context::parent_offset()));
291 base = scratch; 288 base = scratch;
292 } 289 }
293 __ pushq(FieldAddress(base, Context::variable_offset(variable.index()))); 290 __ pushq(FieldAddress(base, Context::variable_offset(variable.index())));
294 } else { 291 } else {
295 // The variable lives in the current stack frame. 292 // The variable lives in the current stack frame.
296 __ pushq(Address(RBP, variable.index() * kWordSize)); 293 __ pushq(Address(RBP, variable.index() * kWordSize));
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 __ j(ABOVE, &no_stack_overflow); 603 __ j(ABOVE, &no_stack_overflow);
607 GenerateCallRuntime(AstNode::kNoId, 604 GenerateCallRuntime(AstNode::kNoId,
608 0, 605 0,
609 kStackOverflowRuntimeEntry); 606 kStackOverflowRuntimeEntry);
610 __ Bind(&no_stack_overflow); 607 __ Bind(&no_stack_overflow);
611 } 608 }
612 609
613 610
614 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 611 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
615 // Unchain the context(s) up to context level 0. 612 // Unchain the context(s) up to context level 0.
616 int context_level = state()->context_level(); 613 intptr_t current_context_level = context_level();
617 ASSERT(context_level >= 0); 614 ASSERT(current_context_level >= 0);
618 if (!parsed_function_.function().IsClosureFunction()) { 615 if (!parsed_function_.function().IsClosureFunction()) {
619 if (context_level > 0) { 616 if (current_context_level > 0) {
620 // CTX on entry was saved on the stack, but not linked as context parent. 617 // CTX on entry was saved on the stack, but not linked as context parent.
621 __ popq(CTX); 618 __ popq(CTX);
622 } 619 }
623 } else { 620 } else {
624 while (context_level-- > 0) { 621 while (current_context_level-- > 0) {
625 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 622 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
626 } 623 }
627 } 624 }
628 #ifdef DEBUG 625 #ifdef DEBUG
629 // Check that the entry stack size matches the exit stack size. 626 // Check that the entry stack size matches the exit stack size.
630 __ movq(R10, RBP); 627 __ movq(R10, RBP);
631 __ subq(R10, RSP); 628 __ subq(R10, RSP);
632 ASSERT(locals_space_size() >= 0); 629 ASSERT(locals_space_size() >= 0);
633 __ cmpq(R10, Immediate(locals_space_size())); 630 __ cmpq(R10, Immediate(locals_space_size()));
634 Label wrong_stack; 631 Label wrong_stack;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 } 738 }
742 } 739 }
743 740
744 741
745 void CodeGenerator::VisitClosureNode(ClosureNode* node) { 742 void CodeGenerator::VisitClosureNode(ClosureNode* node) {
746 const Function& function = node->function(); 743 const Function& function = node->function();
747 if (function.IsNonImplicitClosureFunction()) { 744 if (function.IsNonImplicitClosureFunction()) {
748 // The context scope may have already been set by the new non-optimizing 745 // The context scope may have already been set by the new non-optimizing
749 // compiler. If it was not, set it here. 746 // compiler. If it was not, set it here.
750 if (function.context_scope() == ContextScope::null()) { 747 if (function.context_scope() == ContextScope::null()) {
751 const int current_context_level = state()->context_level(); 748 const intptr_t current_context_level = context_level();
752 const ContextScope& context_scope = ContextScope::ZoneHandle( 749 const ContextScope& context_scope = ContextScope::ZoneHandle(
753 node->scope()->PreserveOuterScope(current_context_level)); 750 node->scope()->PreserveOuterScope(current_context_level));
754 ASSERT(!function.HasCode()); 751 ASSERT(!function.HasCode());
755 function.set_context_scope(context_scope); 752 function.set_context_scope(context_scope);
756 } 753 }
757 } else if (function.IsImplicitInstanceClosureFunction()) { 754 } else if (function.IsImplicitInstanceClosureFunction()) {
758 node->receiver()->Visit(this); 755 node->receiver()->Visit(this);
759 } 756 }
760 ASSERT(function.context_scope() != ContextScope::null()); 757 ASSERT(function.context_scope() != ContextScope::null());
761 758
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 __ popq(RAX); 795 __ popq(RAX);
799 __ popq(CTX); // result: cloned context. Set as current context. 796 __ popq(CTX); // result: cloned context. Set as current context.
800 } 797 }
801 798
802 799
803 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) { 800 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) {
804 CodeGeneratorState codegen_state(this); 801 CodeGeneratorState codegen_state(this);
805 LocalScope* scope = node_sequence->scope(); 802 LocalScope* scope = node_sequence->scope();
806 const intptr_t num_context_variables = 803 const intptr_t num_context_variables =
807 (scope != NULL) ? scope->num_context_variables() : 0; 804 (scope != NULL) ? scope->num_context_variables() : 0;
805 intptr_t previous_context_level = context_level();
808 if (num_context_variables > 0) { 806 if (num_context_variables > 0) {
809 // The loop local scope declares variables that are captured. 807 // The loop local scope declares variables that are captured.
810 // Allocate and chain a new context. 808 // Allocate and chain a new context.
811 __ movq(R10, Immediate(num_context_variables)); 809 __ movq(R10, Immediate(num_context_variables));
812 const ExternalLabel label("alloc_context", 810 const ExternalLabel label("alloc_context",
813 StubCode::AllocateContextEntryPoint()); 811 StubCode::AllocateContextEntryPoint());
814 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); 812 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
815 813
816 // If this node_sequence is the body of the function being compiled, and if 814 // If this node_sequence is the body of the function being compiled, and if
817 // this function is not a closure, do not link the current context as the 815 // this function is not a closure, do not link the current context as the
818 // parent of the newly allocated context, as it is not accessible. Instead, 816 // parent of the newly allocated context, as it is not accessible. Instead,
819 // save it on the stack and restore it on exit. 817 // save it on the stack and restore it on exit.
820 if ((node_sequence == parsed_function_.node_sequence()) && 818 if ((node_sequence == parsed_function_.node_sequence()) &&
821 !parsed_function_.function().IsClosureFunction()) { 819 !parsed_function_.function().IsClosureFunction()) {
822 __ pushq(CTX); 820 __ pushq(CTX);
823 const Immediate raw_null = 821 const Immediate raw_null =
824 Immediate(reinterpret_cast<intptr_t>(Object::null())); 822 Immediate(reinterpret_cast<intptr_t>(Object::null()));
825 __ movq(CTX, raw_null); 823 __ movq(CTX, raw_null);
826 } 824 }
827 825
828 // Chain the new context in RAX to its parent in CTX. 826 // Chain the new context in RAX to its parent in CTX.
829 __ StoreIntoObject(RAX, 827 __ StoreIntoObject(RAX,
830 FieldAddress(RAX, Context::parent_offset()), 828 FieldAddress(RAX, Context::parent_offset()),
831 CTX); 829 CTX);
832 // Set new context as current context. 830 // Set new context as current context.
833 __ movq(CTX, RAX); 831 __ movq(CTX, RAX);
834 state()->set_context_level(scope->context_level()); 832 set_context_level(scope->context_level());
835 833
836 // If this node_sequence is the body of the function being compiled, copy 834 // If this node_sequence is the body of the function being compiled, copy
837 // the captured parameters from the frame into the context. 835 // the captured parameters from the frame into the context.
838 if (node_sequence == parsed_function_.node_sequence()) { 836 if (node_sequence == parsed_function_.node_sequence()) {
839 ASSERT(scope->context_level() == 1); 837 ASSERT(scope->context_level() == 1);
840 const Immediate raw_null = 838 const Immediate raw_null =
841 Immediate(reinterpret_cast<intptr_t>(Object::null())); 839 Immediate(reinterpret_cast<intptr_t>(Object::null()));
842 const Function& function = parsed_function_.function(); 840 const Function& function = parsed_function_.function();
843 const int num_params = function.NumberOfParameters(); 841 const int num_params = function.NumberOfParameters();
844 int param_frame_index = 842 int param_frame_index =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 // If this node sequence is labeled, a break out of the sequence will have 880 // If this node sequence is labeled, a break out of the sequence will have
883 // taken care of unchaining the context. 881 // taken care of unchaining the context.
884 if (node_sequence->label() != NULL) { 882 if (node_sequence->label() != NULL) {
885 __ Bind(node_sequence->label()->break_label()); 883 __ Bind(node_sequence->label()->break_label());
886 if ((num_context_variables > 0) && 884 if ((num_context_variables > 0) &&
887 (node_sequence == parsed_function_.node_sequence()) && 885 (node_sequence == parsed_function_.node_sequence()) &&
888 !parsed_function_.function().IsClosureFunction()) { 886 !parsed_function_.function().IsClosureFunction()) {
889 __ popq(CTX); 887 __ popq(CTX);
890 } 888 }
891 } 889 }
890 set_context_level(previous_context_level);
892 } 891 }
893 892
894 893
895 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) { 894 void CodeGenerator::VisitArgumentListNode(ArgumentListNode* arguments) {
896 for (int i = 0; i < arguments->length(); i++) { 895 for (int i = 0; i < arguments->length(); i++) {
897 AstNode* argument = arguments->NodeAt(i); 896 AstNode* argument = arguments->NodeAt(i);
898 argument->Visit(this); 897 argument->Visit(this);
899 } 898 }
900 } 899 }
901 900
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 1857
1859 // Generate inlined code for all finally blocks as we may transfer 1858 // Generate inlined code for all finally blocks as we may transfer
1860 // control out of the 'try' blocks if any. 1859 // control out of the 'try' blocks if any.
1861 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1860 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1862 node->InlinedFinallyNodeAt(i)->Visit(this); 1861 node->InlinedFinallyNodeAt(i)->Visit(this);
1863 } 1862 }
1864 1863
1865 // Unchain the context(s) up to the outer context level of the scope which 1864 // Unchain the context(s) up to the outer context level of the scope which
1866 // contains the destination label. 1865 // contains the destination label.
1867 ASSERT(label->owner() != NULL); 1866 ASSERT(label->owner() != NULL);
1868 int target_context_level = 0; 1867 intptr_t target_context_level = 0;
1869 LocalScope* target_scope = label->owner(); 1868 LocalScope* target_scope = label->owner();
1870 if (target_scope->num_context_variables() > 0) { 1869 if (target_scope->num_context_variables() > 0) {
1871 // The scope of the target label allocates a context, therefore its outer 1870 // The scope of the target label allocates a context, therefore its outer
1872 // scope is at a lower context level. 1871 // scope is at a lower context level.
1873 target_context_level = target_scope->context_level() - 1; 1872 target_context_level = target_scope->context_level() - 1;
1874 } else { 1873 } else {
1875 // The scope of the target label does not allocate a context, so its outer 1874 // The scope of the target label does not allocate a context, so its outer
1876 // scope is at the same context level. Find it. 1875 // scope is at the same context level. Find it.
1877 while ((target_scope != NULL) && 1876 while ((target_scope != NULL) &&
1878 (target_scope->num_context_variables() == 0)) { 1877 (target_scope->num_context_variables() == 0)) {
1879 target_scope = target_scope->parent(); 1878 target_scope = target_scope->parent();
1880 } 1879 }
1881 if (target_scope != NULL) { 1880 if (target_scope != NULL) {
1882 target_context_level = target_scope->context_level(); 1881 target_context_level = target_scope->context_level();
1883 } 1882 }
1884 } 1883 }
1885 ASSERT(target_context_level >= 0); 1884 ASSERT(target_context_level >= 0);
1886 int context_level = state()->context_level(); 1885 int current_context_level = context_level();
1887 ASSERT(context_level >= target_context_level); 1886 ASSERT(current_context_level >= target_context_level);
1888 while (context_level-- > target_context_level) { 1887 while (current_context_level-- > target_context_level) {
1889 __ movq(CTX, FieldAddress(CTX, Context::parent_offset())); 1888 __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
1890 } 1889 }
1891 1890
1892 if (node->kind() == Token::kBREAK) { 1891 if (node->kind() == Token::kBREAK) {
1893 __ jmp(label->break_label()); 1892 __ jmp(label->break_label());
1894 } else { 1893 } else {
1895 __ jmp(label->continue_label()); 1894 __ jmp(label->continue_label());
1896 } 1895 }
1897 } 1896 }
1898 1897
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 // and ':stacktrace_var' can never be captured variables. 2539 // and ':stacktrace_var' can never be captured variables.
2541 // Restore CTX from local variable ':saved_context'. 2540 // Restore CTX from local variable ':saved_context'.
2542 GenerateLoadVariable(CTX, node->context_var()); 2541 GenerateLoadVariable(CTX, node->context_var());
2543 2542
2544 // Restore RSP from RBP as we are coming from a throw and the code for 2543 // Restore RSP from RBP as we are coming from a throw and the code for
2545 // popping arguments has not been run. 2544 // popping arguments has not been run.
2546 ASSERT(locals_space_size() >= 0); 2545 ASSERT(locals_space_size() >= 0);
2547 __ movq(RSP, RBP); 2546 __ movq(RSP, RBP);
2548 __ subq(RSP, Immediate(locals_space_size())); 2547 __ subq(RSP, Immediate(locals_space_size()));
2549 2548
2550 if ((state()->context_level() > 0) && 2549 if ((context_level() > 0) &&
2551 !parsed_function_.function().IsClosureFunction()) { 2550 !parsed_function_.function().IsClosureFunction()) {
2552 // CTX was saved on entry. 2551 // CTX was saved on entry.
2553 __ subq(RSP, Immediate(kWordSize)); 2552 __ subq(RSP, Immediate(kWordSize));
2554 } 2553 }
2555 2554
2556 // The JumpToExceptionHandler trampoline code sets up 2555 // The JumpToExceptionHandler trampoline code sets up
2557 // - the exception object in RAX (kExceptionObjectReg) 2556 // - the exception object in RAX (kExceptionObjectReg)
2558 // - the stacktrace object in register RDX (kStackTraceObjectReg) 2557 // - the stacktrace object in register RDX (kStackTraceObjectReg)
2559 // We now setup the exception object and the trace object 2558 // We now setup the exception object and the trace object
2560 // so that the handler code has access to these objects. 2559 // so that the handler code has access to these objects.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2696 const Error& error = Error::Handle( 2695 const Error& error = Error::Handle(
2697 Parser::FormatError(script, token_index, "Error", format, args)); 2696 Parser::FormatError(script, token_index, "Error", format, args));
2698 va_end(args); 2697 va_end(args);
2699 Isolate::Current()->long_jump_base()->Jump(1, error); 2698 Isolate::Current()->long_jump_base()->Jump(1, error);
2700 UNREACHABLE(); 2699 UNREACHABLE();
2701 } 2700 }
2702 2701
2703 } // namespace dart 2702 } // namespace dart
2704 2703
2705 #endif // defined TARGET_ARCH_X64 2704 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698