diff --git a/include/v8-message.h b/include/v8-message.h index 195ca79bd9..9b24d498d5 100644 --- a/include/v8-message.h +++ b/include/v8-message.h @@ -7,6 +7,8 @@ #include +#include + #include "v8-local-handle.h" // NOLINT(build/include_directory) #include "v8-maybe.h" // NOLINT(build/include_directory) #include "v8config.h" // NOLINT(build/include_directory) @@ -206,8 +208,9 @@ class V8_EXPORT Message { bool IsSharedCrossOrigin() const; bool IsOpaque() const; - // TODO(1245381): Print to a string instead of on a FILE. + V8_DEPRECATE_SOON("Use the version that takes a std::ostream&.") static void PrintCurrentStackTrace(Isolate* isolate, FILE* out); + static void PrintCurrentStackTrace(Isolate* isolate, std::ostream& out); static const int kNoLineNumberInfo = 0; static const int kNoColumnInfo = 0; diff --git a/src/api/api.cc b/src/api/api.cc index ad9aeccbb2..9102f6b3c5 100644 --- a/src/api/api.cc +++ b/src/api/api.cc @@ -7,6 +7,7 @@ #include // For min #include // For isnan. #include +#include #include #include // For move #include @@ -3094,6 +3095,14 @@ MaybeLocal Message::GetSourceLine(Local context) const { } void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + std::ostringstream stack_trace_stream; + i_isolate->PrintCurrentStackTrace(stack_trace_stream); + i::PrintF(out, "%s", stack_trace_stream.str().c_str()); +} + +void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) { i::Isolate* i_isolate = reinterpret_cast(isolate); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); i_isolate->PrintCurrentStackTrace(out); diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index de7378acd5..6e2d92151f 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -1564,7 +1564,9 @@ Handle Isolate::CreateMessageOrAbort( // print a user-friendly stack trace (not an internal one). PrintF(stderr, "%s\n\nFROM\n", MessageHandler::GetLocalizedMessage(this, message_obj).get()); - PrintCurrentStackTrace(stderr); + std::ostringstream stack_trace_stream; + PrintCurrentStackTrace(stack_trace_stream); + PrintF(stderr, "%s", stack_trace_stream.str().c_str()); base::OS::Abort(); } } @@ -2125,7 +2127,7 @@ Object Isolate::PromoteScheduledException() { return ReThrow(thrown); } -void Isolate::PrintCurrentStackTrace(FILE* out) { +void Isolate::PrintCurrentStackTrace(std::ostream& out) { CaptureStackTraceOptions options; options.limit = 0; options.skip_mode = SKIP_NONE; diff --git a/src/execution/isolate.h b/src/execution/isolate.h index 92a4e74399..277fb2cacb 100644 --- a/src/execution/isolate.h +++ b/src/execution/isolate.h @@ -853,7 +853,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { v8::Isolate::AbortOnUncaughtExceptionCallback callback); enum PrintStackMode { kPrintStackConcise, kPrintStackVerbose }; - void PrintCurrentStackTrace(FILE* out); + void PrintCurrentStackTrace(std::ostream& out); void PrintStack(StringStream* accumulator, PrintStackMode mode = kPrintStackVerbose); void PrintStack(FILE* out, PrintStackMode mode = kPrintStackVerbose); diff --git a/src/objects/string.cc b/src/objects/string.cc index 4b18ee3d05..7ff80c2faf 100644 --- a/src/objects/string.cc +++ b/src/objects/string.cc @@ -1453,6 +1453,13 @@ void String::PrintOn(FILE* file) { } } +void String::PrintOn(std::ostream& ostream) { + int length = this->length(); + for (int i = 0; i < length; i++) { + ostream.put(Get(i)); + } +} + Handle SeqString::Truncate(Handle string, int new_length) { if (new_length == 0) return string->GetReadOnlyRoots().empty_string_handle(); diff --git a/src/objects/string.h b/src/objects/string.h index 3bb3ba1d6e..895eb25d07 100644 --- a/src/objects/string.h +++ b/src/objects/string.h @@ -403,6 +403,7 @@ class String : public TorqueGeneratedString { enum TrimMode { kTrim, kTrimStart, kTrimEnd }; V8_EXPORT_PRIVATE void PrintOn(FILE* out); + V8_EXPORT_PRIVATE void PrintOn(std::ostream& out); // For use during stack traces. Performs rudimentary sanity check. bool LooksValid();