Chromium Code Reviews| Index: runtime/lib/errors.cc |
| diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc |
| index 28d4ef49c41d6c823a2c98caf59ec782b93222d0..20d18512f9e23ef0e9ff7a3ddbc84a8af9c11e9b 100644 |
| --- a/runtime/lib/errors.cc |
| +++ b/runtime/lib/errors.cc |
| @@ -7,9 +7,53 @@ |
| #include "vm/object_store.h" |
| #include "vm/runtime_entry.h" |
| #include "vm/stack_frame.h" |
| +#include "vm/symbols.h" |
| namespace dart { |
| +static bool IsAssertionerrorFunction(const Function& function) { |
| + const Class& assert_error_class = Class::Handle( |
| + Library::LookupCoreClass(Symbols::AssertionError())); |
| + return function.Owner() == assert_error_class.raw(); |
| +} |
| + |
| + |
| +// Scan the stack until we hit the first function in the _AssertionError |
| +// class. We then return the next frame's script taking inlining into account. |
| +static RawScript* FindScript(DartFrameIterator* iterator) { |
| + StackFrame* stack_frame = iterator->NextFrame(); |
| + Code& code = Code::Handle(); |
| + Function& func = Function::Handle(); |
| + bool hit_assertion_error = false; |
|
siva
2016/10/27 10:46:48
why not add
const Class& assert_error_class = ....
Cutch
2016/10/27 11:25:29
Done.
|
| + while (stack_frame != NULL) { |
| + code ^= stack_frame->LookupDartCode(); |
| + if (code.is_optimized()) { |
| + InlinedFunctionsIterator inlined_iterator(code, stack_frame->pc()); |
| + while (!inlined_iterator.Done()) { |
| + func ^= inlined_iterator.function(); |
| + if (hit_assertion_error) { |
| + return func.script(); |
| + } |
| + ASSERT(!hit_assertion_error); |
| + hit_assertion_error = IsAssertionerrorFunction(func); |
| + inlined_iterator.Advance(); |
| + } |
| + } else { |
| + func ^= code.function(); |
| + ASSERT(!func.IsNull()); |
| + if (hit_assertion_error) { |
| + return func.script(); |
| + } |
| + ASSERT(!hit_assertion_error); |
| + hit_assertion_error = IsAssertionerrorFunction(func); |
| + } |
| + stack_frame = iterator->NextFrame(); |
| + } |
| + UNREACHABLE(); |
| + return Script::null(); |
| +} |
| + |
| + |
| // Allocate and throw a new AssertionError. |
| // Arg0: index of the first token of the failed assertion. |
| // Arg1: index of the first token after the failed assertion. |
| @@ -26,8 +70,7 @@ DEFINE_NATIVE_ENTRY(AssertionError_throwNew, 2) { |
| DartFrameIterator iterator; |
| iterator.NextFrame(); // Skip native call. |
| - iterator.NextFrame(); // Skip _AssertionError._checkAssertion frame |
| - const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator)); |
| + const Script& script = Script::Handle(FindScript(&iterator)); |
| // Initialize argument 'failed_assertion' with source snippet. |
| intptr_t from_line, from_column; |