-
Notifications
You must be signed in to change notification settings - Fork 30.5k
/
Copy pathbootstrapper.cc
133 lines (109 loc) Β· 4.42 KB
/
bootstrapper.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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