Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index ebece8a43d8a8aa9d856d7cc0d167961eb00332d..eab8fc5782297747a9b577214ba4bda4d409cba2 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -15568,6 +15568,82 @@ const char* Stacktrace::ToCStringInternal(intptr_t* frame_index) const { |
} |
+ExceptionStackTrace* Stacktrace::BuildExceptionStackTrace() const { |
+ ExceptionStackTrace* result = new ExceptionStackTrace(8); |
+ String& function_name = String::Handle(); |
+ String& script_uri = String::Handle(); |
+ Script& script = Script::Handle(); |
+ |
+ Function& function = Function::Handle(); |
+ Code& code = Code::Handle(); |
+ for (intptr_t i = 0; i < Length(); i++) { |
+ function = FunctionAtFrame(i); |
+ if (function.IsNull()) { |
+ // Check if null function object indicates a stack trace overflow. |
+ if ((i < (Length() - 1)) && |
+ (FunctionAtFrame(i + 1) != Function::null())) { |
+ function_name = Symbols::Empty().raw(); |
+ script_uri = Symbols::Empty().raw(); |
+ intptr_t line = -1; |
+ intptr_t column = -1; |
+ result->AddFrame( |
+ new ExceptionStackFrame(function_name, script_uri, line, column)); |
+ } |
+ } else if (function.is_visible()) { |
+ code = CodeAtFrame(i); |
+ ASSERT(function.raw() == code.function()); |
+ uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); |
+ if (code.is_optimized() && expand_inlined()) { |
+ // Traverse inlined frames. |
+ for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) { |
+ function = it.function(); |
+ code = it.code(); |
+ ASSERT(function.raw() == code.function()); |
+ uword pc = it.pc(); |
+ ASSERT(pc != 0); |
+ ASSERT(code.EntryPoint() <= pc); |
+ ASSERT(pc < (code.EntryPoint() + code.Size())); |
+ |
+ function_name = function.QualifiedUserVisibleName(); |
+ script = function.script(); |
+ script_uri = script.url(); |
+ const intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
+ intptr_t line = -1; |
+ intptr_t column = -1; |
+ if (token_pos >= 0) { |
+ if (script.HasSource()) { |
+ script.GetTokenLocation(token_pos, &line, &column); |
+ } else { |
+ script.GetTokenLocation(token_pos, &line, NULL); |
+ } |
+ } |
+ result->AddFrame( |
+ new ExceptionStackFrame(function_name, script_uri, line, column)); |
+ } |
+ } else { |
+ function_name = function.QualifiedUserVisibleName(); |
+ script = function.script(); |
+ script_uri = script.url(); |
+ const intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
+ intptr_t line = -1; |
+ intptr_t column = -1; |
+ if (token_pos >= 0) { |
+ if (script.HasSource()) { |
+ script.GetTokenLocation(token_pos, &line, &column); |
+ } else { |
+ script.GetTokenLocation(token_pos, &line, NULL); |
+ } |
+ } |
+ result->AddFrame( |
+ new ExceptionStackFrame(function_name, script_uri, line, column)); |
+ } |
+ } |
+ } |
+ |
+ return result; |
+} |
+ |
+ |
void JSRegExp::set_pattern(const String& pattern) const { |
StorePointer(&raw_ptr()->pattern_, pattern.raw()); |
} |