summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGus Caplan <me@gus.host>2019-03-19 18:00:16 -0500
committerGus Caplan <me@gus.host>2019-05-21 15:39:09 -0500
commitb046bd193573faf89ac088076b223d5535fb4876 (patch)
treeaaf214a6377bf8e14d38d79116e595256df0d03b /src
parent9fec70a703c71c0b5d22fe5f3fbf22daf1e43565 (diff)
downloadandroid-node-v8-b046bd193573faf89ac088076b223d5535fb4876.tar.gz
android-node-v8-b046bd193573faf89ac088076b223d5535fb4876.tar.bz2
android-node-v8-b046bd193573faf89ac088076b223d5535fb4876.zip
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')
-rw-r--r--src/api/environment.cc38
-rw-r--r--src/env.h1
-rw-r--r--src/node_binding.cc1
-rw-r--r--src/node_errors.cc18
4 files changed, 58 insertions, 0 deletions
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 548b685dfe..5dfac00647 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);
diff --git a/src/env.h b/src/env.h
index 7b7e9f6132..5544ac44db 100644
--- a/src/env.h
+++ b/src/env.h
@@ -402,6 +402,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(native_module_require, v8::Function) \
V(performance_entry_callback, v8::Function) \
V(performance_entry_template, v8::Function) \
+ V(prepare_stack_trace_callback, v8::Function) \
V(process_object, v8::Object) \
V(primordials, v8::Object) \
V(promise_reject_callback, v8::Function) \
diff --git a/src/node_binding.cc b/src/node_binding.cc
index 9a9bfa70a8..99c2406036 100644
--- a/src/node_binding.cc
+++ b/src/node_binding.cc
@@ -48,6 +48,7 @@
V(contextify) \
V(credentials) \
V(domain) \
+ V(errors) \
V(fs) \
V(fs_event_wrap) \
V(heap_utils) \
diff --git a/src/node_errors.cc b/src/node_errors.cc
index 1cd9052383..603c9e415c 100644
--- a/src/node_errors.cc
+++ b/src/node_errors.cc
@@ -17,6 +17,7 @@ using v8::Boolean;
using v8::Context;
using v8::Exception;
using v8::Function;
+using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Int32;
using v8::Isolate;
@@ -767,6 +768,21 @@ void PerIsolateMessageListener(Local<Message> message, Local<Value> error) {
}
}
+void SetPrepareStackTraceCallback(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(args[0]->IsFunction());
+ env->set_prepare_stack_trace_callback(args[0].As<Function>());
+}
+
+void Initialize(Local<Object> target,
+ Local<Value> unused,
+ Local<Context> context,
+ void* priv) {
+ Environment* env = Environment::GetCurrent(context);
+ env->SetMethod(
+ target, "setPrepareStackTraceCallback", SetPrepareStackTraceCallback);
+}
+
} // namespace errors
void DecorateErrorStack(Environment* env,
@@ -880,3 +896,5 @@ void FatalException(Isolate* isolate,
}
} // namespace node
+
+NODE_MODULE_CONTEXT_AWARE_INTERNAL(errors, node::errors::Initialize)