summaryrefslogtreecommitdiff
path: root/src/bootstrapper.cc
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2018-05-23 15:04:23 -0700
committerJames M Snell <jasnell@gmail.com>2018-05-31 14:05:53 -0700
commitcb3d049badb772fc1ea7051540d50c89f73e36dd (patch)
tree4650b56af19be6f85b0c3e063c9cea35b8549dbf /src/bootstrapper.cc
parentdcecfb75080dc98176119a81f0afca5805649e75 (diff)
downloadandroid-node-v8-cb3d049badb772fc1ea7051540d50c89f73e36dd.tar.gz
android-node-v8-cb3d049badb772fc1ea7051540d50c89f73e36dd.tar.bz2
android-node-v8-cb3d049badb772fc1ea7051540d50c89f73e36dd.zip
src: refactor bootstrap to use bootstrap object
PR-URL: https://github.com/nodejs/node/pull/20917 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Michaƫl Zasso <targos@protonmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
Diffstat (limited to 'src/bootstrapper.cc')
-rw-r--r--src/bootstrapper.cc133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
new file mode 100644
index 0000000000..6c7c1af3e3
--- /dev/null
+++ b/src/bootstrapper.cc
@@ -0,0 +1,133 @@
+#include "node.h"
+#include "env.h"
+#include "env-inl.h"
+#include "node_internals.h"
+#include "v8.h"
+
+namespace node {
+
+using v8::Array;
+using v8::Context;
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::Isolate;
+using v8::Local;
+using v8::MaybeLocal;
+using v8::Object;
+using v8::Promise;
+using v8::PromiseRejectEvent;
+using v8::PromiseRejectMessage;
+using v8::Value;
+
+void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(args[0]->IsFunction());
+ env->set_push_values_to_array_function(args[0].As<Function>());
+}
+
+void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
+ args.GetIsolate()->RunMicrotasks();
+}
+
+void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ Isolate* isolate = env->isolate();
+ Local<Context> context = env->context();
+
+ CHECK(args[0]->IsFunction());
+
+ env->set_tick_callback_function(args[0].As<Function>());
+
+ Local<Function> run_microtasks_fn =
+ env->NewFunctionTemplate(RunMicrotasks)->GetFunction(context)
+ .ToLocalChecked();
+ run_microtasks_fn->SetName(FIXED_ONE_BYTE_STRING(isolate, "runMicrotasks"));
+
+ Local<Array> ret = Array::New(isolate, 2);
+ ret->Set(context, 0, env->tick_info()->fields().GetJSArray()).FromJust();
+ ret->Set(context, 1, run_microtasks_fn).FromJust();
+
+ args.GetReturnValue().Set(ret);
+}
+
+void PromiseRejectCallback(PromiseRejectMessage message) {
+ Local<Promise> promise = message.GetPromise();
+ Isolate* isolate = promise->GetIsolate();
+ PromiseRejectEvent event = message.GetEvent();
+
+ Environment* env = Environment::GetCurrent(isolate);
+ Local<Function> callback;
+ Local<Value> value;
+
+ if (event == v8::kPromiseRejectWithNoHandler) {
+ callback = env->promise_reject_unhandled_function();
+ value = message.GetValue();
+
+ if (value.IsEmpty())
+ value = Undefined(isolate);
+ } else if (event == v8::kPromiseHandlerAddedAfterReject) {
+ callback = env->promise_reject_handled_function();
+ value = Undefined(isolate);
+ } else {
+ UNREACHABLE();
+ }
+
+ Local<Value> args[] = { promise, value };
+ MaybeLocal<Value> ret = callback->Call(env->context(),
+ Undefined(isolate),
+ arraysize(args),
+ args);
+
+ if (!ret.IsEmpty() && ret.ToLocalChecked()->IsTrue())
+ env->tick_info()->promise_rejections_toggle_on();
+}
+
+void SetupPromises(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ Isolate* isolate = env->isolate();
+
+ CHECK(args[0]->IsFunction());
+ CHECK(args[1]->IsFunction());
+
+ isolate->SetPromiseRejectCallback(PromiseRejectCallback);
+ env->set_promise_reject_unhandled_function(args[0].As<Function>());
+ env->set_promise_reject_handled_function(args[1].As<Function>());
+}
+
+#define BOOTSTRAP_METHOD(name, fn) env->SetMethod(bootstrapper, #name, fn)
+
+// The Bootstrapper object is an ephemeral object that is used only during
+// the bootstrap process of the Node.js environment. A reference to the
+// bootstrap object must not be kept around after the bootstrap process
+// completes so that it can be gc'd as soon as possible.
+void SetupBootstrapObject(Environment* env,
+ Local<Object> bootstrapper) {
+ BOOTSTRAP_METHOD(_setupProcessObject, SetupProcessObject);
+ BOOTSTRAP_METHOD(_setupNextTick, SetupNextTick);
+ BOOTSTRAP_METHOD(_setupPromises, SetupPromises);
+ BOOTSTRAP_METHOD(_chdir, Chdir);
+ BOOTSTRAP_METHOD(_cpuUsage, CPUUsage);
+ BOOTSTRAP_METHOD(_hrtime, Hrtime);
+ BOOTSTRAP_METHOD(_memoryUsage, MemoryUsage);
+ BOOTSTRAP_METHOD(_rawDebug, RawDebug);
+ BOOTSTRAP_METHOD(_umask, Umask);
+
+#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
+ BOOTSTRAP_METHOD(_initgroups, InitGroups);
+ BOOTSTRAP_METHOD(_setegid, SetEGid);
+ BOOTSTRAP_METHOD(_seteuid, SetEUid);
+ BOOTSTRAP_METHOD(_setgid, SetGid);
+ BOOTSTRAP_METHOD(_setuid, SetUid);
+ BOOTSTRAP_METHOD(_setgroups, SetGroups);
+#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
+
+ auto should_abort_on_uncaught_toggle =
+ FIXED_ONE_BYTE_STRING(env->isolate(), "_shouldAbortOnUncaughtToggle");
+ CHECK(bootstrapper->Set(env->context(),
+ should_abort_on_uncaught_toggle,
+ env->should_abort_on_uncaught_toggle().GetJSArray())
+ .FromJust());
+}
+#undef BOOTSTRAP_METHOD
+
+} // namespace node