diff options
author | Gus Caplan <me@gus.host> | 2019-03-20 02:00:16 +0300 |
---|---|---|
committer | Gus Caplan <me@gus.host> | 2019-05-21 23:39:09 +0300 |
commit | b046bd193573faf89ac088076b223d5535fb4876 (patch) | |
tree | aaf214a6377bf8e14d38d79116e595256df0d03b /src/api | |
parent | 9fec70a703c71c0b5d22fe5f3fbf22daf1e43565 (diff) |
src, lib: take control of prepareStackTrace
Refs https://crbug.com/v8/7848
PR-URL: https://github.com/nodejs/node/pull/23926
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/environment.cc | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/api/environment.cc b/src/api/environment.cc index 548b685dfe4..5dfac00647e 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -13,6 +13,8 @@ #endif namespace node { +using errors::TryCatchScope; +using v8::Array; using v8::Context; using v8::EscapableHandleScope; using v8::Function; @@ -45,6 +47,41 @@ static bool ShouldAbortOnUncaughtException(Isolate* isolate) { !env->inside_should_not_abort_on_uncaught_scope(); } +static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context, + Local<Value> exception, + Local<Array> trace) { + Environment* env = Environment::GetCurrent(context); + if (env == nullptr) { + MaybeLocal<String> s = exception->ToString(context); + return s.IsEmpty() ? + MaybeLocal<Value>() : + MaybeLocal<Value>(s.ToLocalChecked()); + } + Local<Function> prepare = env->prepare_stack_trace_callback(); + if (prepare.IsEmpty()) { + MaybeLocal<String> s = exception->ToString(context); + return s.IsEmpty() ? + MaybeLocal<Value>() : + MaybeLocal<Value>(s.ToLocalChecked()); + } + Local<Value> args[] = { + context->Global(), + exception, + trace, + }; + // This TryCatch + Rethrow is required by V8 due to details around exception + // handling there. For C++ callbacks, V8 expects a scheduled exception (which + // is what ReThrow gives us). Just returning the empty MaybeLocal would leave + // us with a pending exception. + TryCatchScope try_catch(env); + MaybeLocal<Value> result = prepare->Call( + context, Undefined(env->isolate()), arraysize(args), args); + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { + try_catch.ReThrow(); + } + return result; +} + void* NodeArrayBufferAllocator::Allocate(size_t size) { if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) return UncheckedCalloc(size); @@ -166,6 +203,7 @@ void SetIsolateUpForNode(v8::Isolate* isolate, IsolateSettingCategories cat) { isolate->SetAbortOnUncaughtExceptionCallback( ShouldAbortOnUncaughtException); isolate->SetFatalErrorHandler(OnFatalError); + isolate->SetPrepareStackTraceCallback(PrepareStackTraceCallback); break; case IsolateSettingCategories::kMisc: isolate->SetMicrotasksPolicy(MicrotasksPolicy::kExplicit); |