| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/exceptions.h" | 5 #include "vm/exceptions.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); | 156 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); |
| 157 } | 157 } |
| 158 cur_index_ = (Stacktrace::kPreallocatedStackdepth - 1); | 158 cur_index_ = (Stacktrace::kPreallocatedStackdepth - 1); |
| 159 } | 159 } |
| 160 stacktrace_.SetCodeAtFrame(cur_index_, code); | 160 stacktrace_.SetCodeAtFrame(cur_index_, code); |
| 161 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); | 161 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); |
| 162 cur_index_ += 1; | 162 cur_index_ += 1; |
| 163 } | 163 } |
| 164 | 164 |
| 165 | 165 |
| 166 static void BuildStackTrace(StacktraceBuilder* builder) { | 166 static void BuildStackTrace(Isolate* isolate, StacktraceBuilder* builder) { |
| 167 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 167 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 168 StackFrame* frame = frames.NextFrame(); | 168 StackFrame* frame = frames.NextFrame(); |
| 169 ASSERT(frame != NULL); // We expect to find a dart invocation frame. | 169 ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| 170 Code& code = Code::Handle(); | 170 Code& code = Code::Handle(); |
| 171 Smi& offset = Smi::Handle(); | 171 Smi& offset = Smi::Handle(); |
| 172 bool dart_handler_found = false; | 172 bool dart_handler_found = false; |
| 173 bool handler_pc_set = false; | 173 bool handler_pc_set = false; |
| 174 while (frame != NULL) { | 174 while (frame != NULL) { |
| 175 while (!frame->IsEntryFrame()) { | 175 while (!frame->IsEntryFrame()) { |
| 176 if (frame->IsDartFrame()) { | 176 if (frame->IsDartFrame()) { |
| 177 code = frame->LookupDartCode(); | 177 code = frame->LookupDartCode(); |
| 178 offset = Smi::New(frame->pc() - code.EntryPoint()); | 178 offset = Smi::New(frame->pc() - code.EntryPoint()); |
| 179 builder->AddFrame(code, offset, dart_handler_found); | 179 builder->AddFrame(code, offset, dart_handler_found); |
| 180 bool needs_stacktrace = false; | 180 bool needs_stacktrace = false; |
| 181 bool is_catch_all = false; | 181 bool is_catch_all = false; |
| 182 uword handler_pc = kUwordMax; | 182 uword handler_pc = kUwordMax; |
| 183 if (!handler_pc_set && | 183 if (!handler_pc_set && |
| 184 frame->FindExceptionHandler(&handler_pc, | 184 frame->FindExceptionHandler(isolate, |
| 185 &handler_pc, |
| 185 &needs_stacktrace, | 186 &needs_stacktrace, |
| 186 &is_catch_all)) { | 187 &is_catch_all)) { |
| 187 handler_pc_set = true; | 188 handler_pc_set = true; |
| 188 dart_handler_found = true; | 189 dart_handler_found = true; |
| 189 if (!builder->FullStacktrace()) { | 190 if (!builder->FullStacktrace()) { |
| 190 return; | 191 return; |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 } | 194 } |
| 194 frame = frames.NextFrame(); | 195 frame = frames.NextFrame(); |
| 195 ASSERT(frame != NULL); | 196 ASSERT(frame != NULL); |
| 196 } | 197 } |
| 197 ASSERT(frame->IsEntryFrame()); | 198 ASSERT(frame->IsEntryFrame()); |
| 198 if (!handler_pc_set) { | 199 if (!handler_pc_set) { |
| 199 handler_pc_set = true; | 200 handler_pc_set = true; |
| 200 if (!builder->FullStacktrace()) { | 201 if (!builder->FullStacktrace()) { |
| 201 return; | 202 return; |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 frame = frames.NextFrame(); | 205 frame = frames.NextFrame(); |
| 205 } | 206 } |
| 206 } | 207 } |
| 207 | 208 |
| 208 | 209 |
| 209 // Iterate through the stack frames and try to find a frame with an | 210 // Iterate through the stack frames and try to find a frame with an |
| 210 // exception handler. Once found, set the pc, sp and fp so that execution | 211 // exception handler. Once found, set the pc, sp and fp so that execution |
| 211 // can continue in that frame. Sets 'needs_stacktrace' if there is no | 212 // can continue in that frame. Sets 'needs_stacktrace' if there is no |
| 212 // cath-all handler or if a stack-trace is specified in the catch. | 213 // cath-all handler or if a stack-trace is specified in the catch. |
| 213 static bool FindExceptionHandler(uword* handler_pc, | 214 static bool FindExceptionHandler(Isolate* isolate, |
| 215 uword* handler_pc, |
| 214 uword* handler_sp, | 216 uword* handler_sp, |
| 215 uword* handler_fp, | 217 uword* handler_fp, |
| 216 bool* needs_stacktrace) { | 218 bool* needs_stacktrace) { |
| 217 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 219 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 218 StackFrame* frame = frames.NextFrame(); | 220 StackFrame* frame = frames.NextFrame(); |
| 219 ASSERT(frame != NULL); // We expect to find a dart invocation frame. | 221 ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| 220 bool handler_pc_set = false; | 222 bool handler_pc_set = false; |
| 221 *needs_stacktrace = false; | 223 *needs_stacktrace = false; |
| 222 bool is_catch_all = false; | 224 bool is_catch_all = false; |
| 223 uword temp_handler_pc = kUwordMax; | 225 uword temp_handler_pc = kUwordMax; |
| 224 while (!frame->IsEntryFrame()) { | 226 while (!frame->IsEntryFrame()) { |
| 225 if (frame->IsDartFrame()) { | 227 if (frame->IsDartFrame()) { |
| 226 if (frame->FindExceptionHandler(&temp_handler_pc, | 228 if (frame->FindExceptionHandler(isolate, |
| 229 &temp_handler_pc, |
| 227 needs_stacktrace, | 230 needs_stacktrace, |
| 228 &is_catch_all)) { | 231 &is_catch_all)) { |
| 229 if (!handler_pc_set) { | 232 if (!handler_pc_set) { |
| 230 handler_pc_set = true; | 233 handler_pc_set = true; |
| 231 *handler_pc = temp_handler_pc; | 234 *handler_pc = temp_handler_pc; |
| 232 *handler_sp = frame->sp(); | 235 *handler_sp = frame->sp(); |
| 233 *handler_fp = frame->fp(); | 236 *handler_fp = frame->fp(); |
| 234 } | 237 } |
| 235 if (*needs_stacktrace || is_catch_all) { | 238 if (*needs_stacktrace || is_catch_all) { |
| 236 return true; | 239 return true; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 263 frame = frames.NextFrame(); | 266 frame = frames.NextFrame(); |
| 264 ASSERT(frame != NULL); | 267 ASSERT(frame != NULL); |
| 265 } | 268 } |
| 266 ASSERT(frame->IsEntryFrame()); | 269 ASSERT(frame->IsEntryFrame()); |
| 267 *handler_pc = frame->pc(); | 270 *handler_pc = frame->pc(); |
| 268 *handler_sp = frame->sp(); | 271 *handler_sp = frame->sp(); |
| 269 *handler_fp = frame->fp(); | 272 *handler_fp = frame->fp(); |
| 270 } | 273 } |
| 271 | 274 |
| 272 | 275 |
| 273 static void JumpToExceptionHandler(uword program_counter, | 276 static void JumpToExceptionHandler(Isolate* isolate, |
| 277 uword program_counter, |
| 274 uword stack_pointer, | 278 uword stack_pointer, |
| 275 uword frame_pointer, | 279 uword frame_pointer, |
| 276 const Object& exception_object, | 280 const Object& exception_object, |
| 277 const Object& stacktrace_object) { | 281 const Object& stacktrace_object) { |
| 278 // The no_gc StackResource is unwound through the tear down of | 282 // The no_gc StackResource is unwound through the tear down of |
| 279 // stack resources below. | 283 // stack resources below. |
| 280 NoGCScope no_gc; | 284 NoGCScope no_gc; |
| 281 RawObject* raw_exception = exception_object.raw(); | 285 RawObject* raw_exception = exception_object.raw(); |
| 282 RawObject* raw_stacktrace = stacktrace_object.raw(); | 286 RawObject* raw_stacktrace = stacktrace_object.raw(); |
| 283 Isolate* isolate = Isolate::Current(); | |
| 284 | 287 |
| 285 #if defined(USING_SIMULATOR) | 288 #if defined(USING_SIMULATOR) |
| 286 // Unwinding of the C++ frames and destroying of their stack resources is done | 289 // Unwinding of the C++ frames and destroying of their stack resources is done |
| 287 // by the simulator, because the target stack_pointer is a simulated stack | 290 // by the simulator, because the target stack_pointer is a simulated stack |
| 288 // pointer and not the C++ stack pointer. | 291 // pointer and not the C++ stack pointer. |
| 289 | 292 |
| 290 // Continue simulating at the given pc in the given frame after setting up the | 293 // Continue simulating at the given pc in the given frame after setting up the |
| 291 // exception object in the kExceptionObjectReg register and the stacktrace | 294 // exception object in the kExceptionObjectReg register and the stacktrace |
| 292 // object (may be raw null) in the kStackTraceObjectReg register. | 295 // object (may be raw null) in the kStackTraceObjectReg register. |
| 293 isolate->set_vm_tag(VMTag::kScriptTagId); | 296 isolate->set_vm_tag(VMTag::kScriptTagId); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 test_class = type.type_class(); | 352 test_class = type.type_class(); |
| 350 } | 353 } |
| 351 UNREACHABLE(); | 354 UNREACHABLE(); |
| 352 return Field::null(); | 355 return Field::null(); |
| 353 } | 356 } |
| 354 | 357 |
| 355 | 358 |
| 356 RawStacktrace* Exceptions::CurrentStacktrace() { | 359 RawStacktrace* Exceptions::CurrentStacktrace() { |
| 357 Isolate* isolate = Isolate::Current(); | 360 Isolate* isolate = Isolate::Current(); |
| 358 RegularStacktraceBuilder frame_builder(true); | 361 RegularStacktraceBuilder frame_builder(true); |
| 359 BuildStackTrace(&frame_builder); | 362 BuildStackTrace(isolate, &frame_builder); |
| 360 | 363 |
| 361 // Create arrays for code and pc_offset tuples of each frame. | 364 // Create arrays for code and pc_offset tuples of each frame. |
| 362 const Array& full_code_array = Array::Handle(isolate, | 365 const Array& full_code_array = Array::Handle(isolate, |
| 363 Array::MakeArray(frame_builder.code_list())); | 366 Array::MakeArray(frame_builder.code_list())); |
| 364 const Array& full_pc_offset_array = Array::Handle(isolate, | 367 const Array& full_pc_offset_array = Array::Handle(isolate, |
| 365 Array::MakeArray(frame_builder.pc_offset_list())); | 368 Array::MakeArray(frame_builder.pc_offset_list())); |
| 366 const Array& full_catch_code_array = Array::Handle(isolate, | 369 const Array& full_catch_code_array = Array::Handle(isolate, |
| 367 Array::MakeArray(frame_builder.catch_code_list())); | 370 Array::MakeArray(frame_builder.catch_code_list())); |
| 368 const Array& full_catch_pc_offset_array = Array::Handle(isolate, | 371 const Array& full_catch_pc_offset_array = Array::Handle(isolate, |
| 369 Array::MakeArray(frame_builder.catch_pc_offset_list())); | 372 Array::MakeArray(frame_builder.catch_pc_offset_list())); |
| 370 const Stacktrace& full_stacktrace = Stacktrace::Handle( | 373 const Stacktrace& full_stacktrace = Stacktrace::Handle( |
| 371 Stacktrace::New(full_code_array, full_pc_offset_array)); | 374 Stacktrace::New(full_code_array, full_pc_offset_array)); |
| 372 full_stacktrace.SetCatchStacktrace(full_catch_code_array, | 375 full_stacktrace.SetCatchStacktrace(full_catch_code_array, |
| 373 full_catch_pc_offset_array); | 376 full_catch_pc_offset_array); |
| 374 return full_stacktrace.raw(); | 377 return full_stacktrace.raw(); |
| 375 } | 378 } |
| 376 | 379 |
| 377 | 380 |
| 378 static void ThrowExceptionHelper(const Instance& incoming_exception, | 381 static void ThrowExceptionHelper(Isolate* isolate, |
| 382 const Instance& incoming_exception, |
| 379 const Instance& existing_stacktrace) { | 383 const Instance& existing_stacktrace) { |
| 380 bool use_preallocated_stacktrace = false; | 384 bool use_preallocated_stacktrace = false; |
| 381 Isolate* isolate = Isolate::Current(); | |
| 382 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); | 385 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); |
| 383 if (exception.IsNull()) { | 386 if (exception.IsNull()) { |
| 384 exception ^= Exceptions::Create(Exceptions::kNullThrown, | 387 exception ^= Exceptions::Create(Exceptions::kNullThrown, |
| 385 Object::empty_array()); | 388 Object::empty_array()); |
| 386 } else if (exception.raw() == isolate->object_store()->out_of_memory() || | 389 } else if (exception.raw() == isolate->object_store()->out_of_memory() || |
| 387 exception.raw() == isolate->object_store()->stack_overflow()) { | 390 exception.raw() == isolate->object_store()->stack_overflow()) { |
| 388 use_preallocated_stacktrace = true; | 391 use_preallocated_stacktrace = true; |
| 389 } | 392 } |
| 390 uword handler_pc = 0; | 393 uword handler_pc = 0; |
| 391 uword handler_sp = 0; | 394 uword handler_sp = 0; |
| 392 uword handler_fp = 0; | 395 uword handler_fp = 0; |
| 393 Stacktrace& stacktrace = Stacktrace::Handle(isolate); | 396 Stacktrace& stacktrace = Stacktrace::Handle(isolate); |
| 394 bool handler_exists = false; | 397 bool handler_exists = false; |
| 395 bool handler_needs_stacktrace = false; | 398 bool handler_needs_stacktrace = false; |
| 396 if (use_preallocated_stacktrace) { | 399 if (use_preallocated_stacktrace) { |
| 397 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); | 400 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); |
| 398 PreallocatedStacktraceBuilder frame_builder(stacktrace); | 401 PreallocatedStacktraceBuilder frame_builder(stacktrace); |
| 399 handler_exists = FindExceptionHandler(&handler_pc, | 402 handler_exists = FindExceptionHandler(isolate, |
| 403 &handler_pc, |
| 400 &handler_sp, | 404 &handler_sp, |
| 401 &handler_fp, | 405 &handler_fp, |
| 402 &handler_needs_stacktrace); | 406 &handler_needs_stacktrace); |
| 403 if (handler_needs_stacktrace) { | 407 if (handler_needs_stacktrace) { |
| 404 BuildStackTrace(&frame_builder); | 408 BuildStackTrace(isolate, &frame_builder); |
| 405 } | 409 } |
| 406 } else { | 410 } else { |
| 407 // Get stacktrace field of class Error. | 411 // Get stacktrace field of class Error. |
| 408 const Field& stacktrace_field = | 412 const Field& stacktrace_field = |
| 409 Field::Handle(isolate, LookupStacktraceField(exception)); | 413 Field::Handle(isolate, LookupStacktraceField(exception)); |
| 410 handler_exists = FindExceptionHandler(&handler_pc, | 414 handler_exists = FindExceptionHandler(isolate, |
| 415 &handler_pc, |
| 411 &handler_sp, | 416 &handler_sp, |
| 412 &handler_fp, | 417 &handler_fp, |
| 413 &handler_needs_stacktrace); | 418 &handler_needs_stacktrace); |
| 414 Array& code_array = Array::Handle(isolate, Object::empty_array().raw()); | 419 Array& code_array = Array::Handle(isolate, Object::empty_array().raw()); |
| 415 Array& pc_offset_array = | 420 Array& pc_offset_array = |
| 416 Array::Handle(isolate, Object::empty_array().raw()); | 421 Array::Handle(isolate, Object::empty_array().raw()); |
| 417 // If we have an error with a stacktrace field then collect the full stack | 422 // If we have an error with a stacktrace field then collect the full stack |
| 418 // trace and store it into the field. | 423 // trace and store it into the field. |
| 419 if (!stacktrace_field.IsNull()) { | 424 if (!stacktrace_field.IsNull()) { |
| 420 if (exception.GetField(stacktrace_field) == Object::null()) { | 425 if (exception.GetField(stacktrace_field) == Object::null()) { |
| 421 // This is an error object and we need to capture the full stack trace | 426 // This is an error object and we need to capture the full stack trace |
| 422 // here implicitly, so we set up the stack trace. The stack trace field | 427 // here implicitly, so we set up the stack trace. The stack trace |
| 423 // is set only once, it is not overriden. | 428 // field is set only once, it is not overriden. |
| 424 const Stacktrace& full_stacktrace = | 429 const Stacktrace& full_stacktrace = |
| 425 Stacktrace::Handle(isolate, Exceptions::CurrentStacktrace()); | 430 Stacktrace::Handle(isolate, Exceptions::CurrentStacktrace()); |
| 426 exception.SetField(stacktrace_field, full_stacktrace); | 431 exception.SetField(stacktrace_field, full_stacktrace); |
| 427 } | 432 } |
| 428 } | 433 } |
| 429 if (handler_needs_stacktrace) { | 434 if (handler_needs_stacktrace) { |
| 430 RegularStacktraceBuilder frame_builder(false); | 435 RegularStacktraceBuilder frame_builder(false); |
| 431 BuildStackTrace(&frame_builder); | 436 BuildStackTrace(isolate, &frame_builder); |
| 432 | 437 |
| 433 // Create arrays for code and pc_offset tuples of each frame. | 438 // Create arrays for code and pc_offset tuples of each frame. |
| 434 code_array = Array::MakeArray(frame_builder.code_list()); | 439 code_array = Array::MakeArray(frame_builder.code_list()); |
| 435 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); | 440 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); |
| 436 } | 441 } |
| 437 if (existing_stacktrace.IsNull()) { | 442 if (existing_stacktrace.IsNull()) { |
| 438 stacktrace = Stacktrace::New(code_array, pc_offset_array); | 443 stacktrace = Stacktrace::New(code_array, pc_offset_array); |
| 439 } else { | 444 } else { |
| 440 stacktrace ^= existing_stacktrace.raw(); | 445 stacktrace ^= existing_stacktrace.raw(); |
| 441 if (pc_offset_array.Length() != 0) { | 446 if (pc_offset_array.Length() != 0) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 453 // stack as Exceptions::Throw should happen only after a dart | 458 // stack as Exceptions::Throw should happen only after a dart |
| 454 // invocation has been done. | 459 // invocation has been done. |
| 455 ASSERT(handler_pc != 0); | 460 ASSERT(handler_pc != 0); |
| 456 | 461 |
| 457 if (FLAG_print_stacktrace_at_throw) { | 462 if (FLAG_print_stacktrace_at_throw) { |
| 458 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); | 463 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); |
| 459 OS::Print("%s\n", stacktrace.ToCString()); | 464 OS::Print("%s\n", stacktrace.ToCString()); |
| 460 } | 465 } |
| 461 if (handler_exists) { | 466 if (handler_exists) { |
| 462 // Found a dart handler for the exception, jump to it. | 467 // Found a dart handler for the exception, jump to it. |
| 463 JumpToExceptionHandler(handler_pc, | 468 JumpToExceptionHandler(isolate, |
| 469 handler_pc, |
| 464 handler_sp, | 470 handler_sp, |
| 465 handler_fp, | 471 handler_fp, |
| 466 exception, | 472 exception, |
| 467 stacktrace); | 473 stacktrace); |
| 468 } else { | 474 } else { |
| 469 // No dart exception handler found in this invocation sequence, | 475 // No dart exception handler found in this invocation sequence, |
| 470 // so we create an unhandled exception object and return to the | 476 // so we create an unhandled exception object and return to the |
| 471 // invocation stub so that it returns this unhandled exception | 477 // invocation stub so that it returns this unhandled exception |
| 472 // object. The C++ code which invoked this dart sequence can check | 478 // object. The C++ code which invoked this dart sequence can check |
| 473 // and do the appropriate thing (rethrow the exception to the | 479 // and do the appropriate thing (rethrow the exception to the |
| 474 // dart invocation sequence above it, print diagnostics and terminate | 480 // dart invocation sequence above it, print diagnostics and terminate |
| 475 // the isolate etc.). | 481 // the isolate etc.). |
| 476 const UnhandledException& unhandled_exception = UnhandledException::Handle( | 482 const UnhandledException& unhandled_exception = UnhandledException::Handle( |
| 477 UnhandledException::New(exception, stacktrace)); | 483 isolate, UnhandledException::New(exception, stacktrace)); |
| 478 stacktrace = Stacktrace::null(); | 484 stacktrace = Stacktrace::null(); |
| 479 JumpToExceptionHandler(handler_pc, | 485 JumpToExceptionHandler(isolate, |
| 486 handler_pc, |
| 480 handler_sp, | 487 handler_sp, |
| 481 handler_fp, | 488 handler_fp, |
| 482 unhandled_exception, | 489 unhandled_exception, |
| 483 stacktrace); | 490 stacktrace); |
| 484 } | 491 } |
| 485 UNREACHABLE(); | 492 UNREACHABLE(); |
| 486 } | 493 } |
| 487 | 494 |
| 488 | 495 |
| 489 // Static helpers for allocating, initializing, and throwing an error instance. | 496 // Static helpers for allocating, initializing, and throwing an error instance. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } else { | 569 } else { |
| 563 OS::Print("type error.\n"); | 570 OS::Print("type error.\n"); |
| 564 } | 571 } |
| 565 } | 572 } |
| 566 // Throw TypeError or CastError instance. | 573 // Throw TypeError or CastError instance. |
| 567 Exceptions::ThrowByType(exception_type, args); | 574 Exceptions::ThrowByType(exception_type, args); |
| 568 UNREACHABLE(); | 575 UNREACHABLE(); |
| 569 } | 576 } |
| 570 | 577 |
| 571 | 578 |
| 572 void Exceptions::Throw(const Instance& exception) { | 579 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { |
| 573 Isolate* isolate = Isolate::Current(); | |
| 574 isolate->debugger()->SignalExceptionThrown(exception); | 580 isolate->debugger()->SignalExceptionThrown(exception); |
| 575 // Null object is a valid exception object. | 581 // Null object is a valid exception object. |
| 576 ThrowExceptionHelper(exception, Instance::Handle(isolate)); | 582 ThrowExceptionHelper(isolate, exception, Instance::Handle(isolate)); |
| 577 } | 583 } |
| 578 | 584 |
| 579 | 585 |
| 580 void Exceptions::ReThrow(const Instance& exception, | 586 void Exceptions::ReThrow(Isolate* isolate, |
| 587 const Instance& exception, |
| 581 const Instance& stacktrace) { | 588 const Instance& stacktrace) { |
| 582 // Null object is a valid exception object. | 589 // Null object is a valid exception object. |
| 583 ThrowExceptionHelper(exception, stacktrace); | 590 ThrowExceptionHelper(isolate, exception, stacktrace); |
| 584 } | 591 } |
| 585 | 592 |
| 586 | 593 |
| 587 void Exceptions::PropagateError(const Error& error) { | 594 void Exceptions::PropagateError(const Error& error) { |
| 588 ASSERT(Isolate::Current()->top_exit_frame_info() != 0); | 595 Isolate* isolate = Isolate::Current(); |
| 596 ASSERT(isolate->top_exit_frame_info() != 0); |
| 589 if (error.IsUnhandledException()) { | 597 if (error.IsUnhandledException()) { |
| 590 // If the error object represents an unhandled exception, then | 598 // If the error object represents an unhandled exception, then |
| 591 // rethrow the exception in the normal fashion. | 599 // rethrow the exception in the normal fashion. |
| 592 const UnhandledException& uhe = UnhandledException::Cast(error); | 600 const UnhandledException& uhe = UnhandledException::Cast(error); |
| 593 const Instance& exc = Instance::Handle(uhe.exception()); | 601 const Instance& exc = Instance::Handle(isolate, uhe.exception()); |
| 594 const Instance& stk = Instance::Handle(uhe.stacktrace()); | 602 const Instance& stk = Instance::Handle(isolate, uhe.stacktrace()); |
| 595 Exceptions::ReThrow(exc, stk); | 603 Exceptions::ReThrow(isolate, exc, stk); |
| 596 } else { | 604 } else { |
| 597 // Return to the invocation stub and return this error object. The | 605 // Return to the invocation stub and return this error object. The |
| 598 // C++ code which invoked this dart sequence can check and do the | 606 // C++ code which invoked this dart sequence can check and do the |
| 599 // appropriate thing. | 607 // appropriate thing. |
| 600 uword handler_pc = 0; | 608 uword handler_pc = 0; |
| 601 uword handler_sp = 0; | 609 uword handler_sp = 0; |
| 602 uword handler_fp = 0; | 610 uword handler_fp = 0; |
| 603 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); | 611 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
| 604 JumpToExceptionHandler(handler_pc, handler_sp, handler_fp, error, | 612 JumpToExceptionHandler(isolate, handler_pc, handler_sp, handler_fp, error, |
| 605 Stacktrace::Handle()); // Null stacktrace. | 613 Stacktrace::Handle(isolate)); // Null stacktrace. |
| 606 } | 614 } |
| 607 UNREACHABLE(); | 615 UNREACHABLE(); |
| 608 } | 616 } |
| 609 | 617 |
| 610 | 618 |
| 611 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { | 619 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { |
| 612 const Object& result = Object::Handle(Create(type, arguments)); | 620 Isolate* isolate = Isolate::Current(); |
| 621 const Object& result = Object::Handle(isolate, Create(type, arguments)); |
| 613 if (result.IsError()) { | 622 if (result.IsError()) { |
| 614 // We got an error while constructing the exception object. | 623 // We got an error while constructing the exception object. |
| 615 // Propagate the error instead of throwing the exception. | 624 // Propagate the error instead of throwing the exception. |
| 616 PropagateError(Error::Cast(result)); | 625 PropagateError(Error::Cast(result)); |
| 617 } else { | 626 } else { |
| 618 ASSERT(result.IsInstance()); | 627 ASSERT(result.IsInstance()); |
| 619 Throw(Instance::Cast(result)); | 628 Throw(isolate, Instance::Cast(result)); |
| 620 } | 629 } |
| 621 } | 630 } |
| 622 | 631 |
| 623 | 632 |
| 624 void Exceptions::ThrowOOM() { | 633 void Exceptions::ThrowOOM() { |
| 625 Isolate* isolate = Isolate::Current(); | 634 Isolate* isolate = Isolate::Current(); |
| 626 const Instance& oom = Instance::Handle( | 635 const Instance& oom = Instance::Handle( |
| 627 isolate, isolate->object_store()->out_of_memory()); | 636 isolate, isolate->object_store()->out_of_memory()); |
| 628 Throw(oom); | 637 Throw(isolate, oom); |
| 629 } | 638 } |
| 630 | 639 |
| 631 | 640 |
| 632 void Exceptions::ThrowStackOverflow() { | 641 void Exceptions::ThrowStackOverflow() { |
| 633 Isolate* isolate = Isolate::Current(); | 642 Isolate* isolate = Isolate::Current(); |
| 634 const Instance& stack_overflow = Instance::Handle( | 643 const Instance& stack_overflow = Instance::Handle( |
| 635 isolate, isolate->object_store()->stack_overflow()); | 644 isolate, isolate->object_store()->stack_overflow()); |
| 636 Throw(stack_overflow); | 645 Throw(isolate, stack_overflow); |
| 637 } | 646 } |
| 638 | 647 |
| 639 | 648 |
| 640 void Exceptions::ThrowArgumentError(const Instance& arg) { | 649 void Exceptions::ThrowArgumentError(const Instance& arg) { |
| 641 const Array& args = Array::Handle(Array::New(1)); | 650 const Array& args = Array::Handle(Array::New(1)); |
| 642 args.SetAt(0, arg); | 651 args.SetAt(0, arg); |
| 643 Exceptions::ThrowByType(Exceptions::kArgument, args); | 652 Exceptions::ThrowByType(Exceptions::kArgument, args); |
| 644 } | 653 } |
| 645 | 654 |
| 646 | 655 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 char* msg = reinterpret_cast<char*>(malloc(len + 1)); | 822 char* msg = reinterpret_cast<char*>(malloc(len + 1)); |
| 814 va_copy(args_copy, args); | 823 va_copy(args_copy, args); |
| 815 OS::VSNPrint(msg, len + 1, format, args_copy); | 824 OS::VSNPrint(msg, len + 1, format, args_copy); |
| 816 va_end(args_copy); | 825 va_end(args_copy); |
| 817 trace_warning.AddProperty("message", msg); | 826 trace_warning.AddProperty("message", msg); |
| 818 } | 827 } |
| 819 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. | 828 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. |
| 820 } | 829 } |
| 821 | 830 |
| 822 } // namespace dart | 831 } // namespace dart |
| OLD | NEW |