Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
node_util.cc
Go to the documentation of this file.
1 #include "node.h"
2 #include "node_watchdog.h"
3 #include "v8.h"
4 #include "env.h"
5 #include "env-inl.h"
6 
7 namespace node {
8 namespace util {
9 
10 using v8::Array;
11 using v8::Context;
12 using v8::FunctionCallbackInfo;
13 using v8::Integer;
14 using v8::Local;
15 using v8::Maybe;
16 using v8::Object;
17 using v8::Private;
18 using v8::Promise;
19 using v8::Proxy;
20 using v8::Value;
21 
22 
23 #define VALUE_METHOD_MAP(V) \
24  V(isArrayBuffer, IsArrayBuffer) \
25  V(isAsyncFunction, IsAsyncFunction) \
26  V(isDataView, IsDataView) \
27  V(isDate, IsDate) \
28  V(isExternal, IsExternal) \
29  V(isMap, IsMap) \
30  V(isMapIterator, IsMapIterator) \
31  V(isNativeError, IsNativeError) \
32  V(isPromise, IsPromise) \
33  V(isRegExp, IsRegExp) \
34  V(isSet, IsSet) \
35  V(isSetIterator, IsSetIterator) \
36  V(isTypedArray, IsTypedArray) \
37  V(isUint8Array, IsUint8Array)
38 
39 
40 #define V(_, ucname) \
41  static void ucname(const FunctionCallbackInfo<Value>& args) { \
42  CHECK_EQ(1, args.Length()); \
43  args.GetReturnValue().Set(args[0]->ucname()); \
44  }
45 
47 #undef V
48 
49 static void IsAnyArrayBuffer(const FunctionCallbackInfo<Value>& args) {
50  CHECK_EQ(1, args.Length());
51  args.GetReturnValue().Set(
52  args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
53 }
54 
55 static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
56  // Return undefined if it's not a Promise.
57  if (!args[0]->IsPromise())
58  return;
59 
60  auto isolate = args.GetIsolate();
61 
62  Local<Promise> promise = args[0].As<Promise>();
63  Local<Array> ret = Array::New(isolate, 2);
64 
65  int state = promise->State();
66  ret->Set(0, Integer::New(isolate, state));
67  if (state != Promise::PromiseState::kPending)
68  ret->Set(1, promise->Result());
69 
70  args.GetReturnValue().Set(ret);
71 }
72 
73 static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
74  // Return undefined if it's not a proxy.
75  if (!args[0]->IsProxy())
76  return;
77 
78  Local<Proxy> proxy = args[0].As<Proxy>();
79 
80  Local<Array> ret = Array::New(args.GetIsolate(), 2);
81  ret->Set(0, proxy->GetTarget());
82  ret->Set(1, proxy->GetHandler());
83 
84  args.GetReturnValue().Set(ret);
85 }
86 
87 // Side effect-free stringification that will never throw exceptions.
88 static void SafeToString(const FunctionCallbackInfo<Value>& args) {
89  auto context = args.GetIsolate()->GetCurrentContext();
90  args.GetReturnValue().Set(args[0]->ToDetailString(context).ToLocalChecked());
91 }
92 
93 inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
94 #define V(name, _) &Environment::name,
95  static Local<Private> (Environment::*const methods[])() const = {
96  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
97  };
98 #undef V
99  CHECK_LT(index, arraysize(methods));
100  return (env->*methods[index])();
101 }
102 
103 static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
104  Environment* env = Environment::GetCurrent(args);
105 
106  if (!args[0]->IsObject())
107  return env->ThrowTypeError("obj must be an object");
108 
109  if (!args[1]->IsUint32())
110  return env->ThrowTypeError("index must be an uint32");
111 
112  Local<Object> obj = args[0].As<Object>();
113  auto index = args[1]->Uint32Value(env->context()).FromJust();
114  auto private_symbol = IndexToPrivateSymbol(env, index);
115  auto maybe_value = obj->GetPrivate(env->context(), private_symbol);
116 
117  args.GetReturnValue().Set(maybe_value.ToLocalChecked());
118 }
119 
120 static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
121  Environment* env = Environment::GetCurrent(args);
122 
123  if (!args[0]->IsObject())
124  return env->ThrowTypeError("obj must be an object");
125 
126  if (!args[1]->IsUint32())
127  return env->ThrowTypeError("index must be an uint32");
128 
129  Local<Object> obj = args[0].As<Object>();
130  auto index = args[1]->Uint32Value(env->context()).FromJust();
131  auto private_symbol = IndexToPrivateSymbol(env, index);
132  auto maybe_value = obj->SetPrivate(env->context(), private_symbol, args[2]);
133 
134  args.GetReturnValue().Set(maybe_value.FromJust());
135 }
136 
137 
138 void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
139  int ret = SigintWatchdogHelper::GetInstance()->Start();
140  if (ret != 0) {
141  Environment* env = Environment::GetCurrent(args);
142  env->ThrowErrnoException(ret, "StartSigintWatchdog");
143  }
144 }
145 
146 
147 void StopSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
148  bool had_pending_signals = SigintWatchdogHelper::GetInstance()->Stop();
149  args.GetReturnValue().Set(had_pending_signals);
150 }
151 
152 
153 void WatchdogHasPendingSigint(const FunctionCallbackInfo<Value>& args) {
154  bool ret = SigintWatchdogHelper::GetInstance()->HasPendingSignal();
155  args.GetReturnValue().Set(ret);
156 }
157 
158 
159 void CreatePromise(const FunctionCallbackInfo<Value>& args) {
160  Local<Context> context = args.GetIsolate()->GetCurrentContext();
161  auto maybe_resolver = Promise::Resolver::New(context);
162  if (!maybe_resolver.IsEmpty())
163  args.GetReturnValue().Set(maybe_resolver.ToLocalChecked());
164 }
165 
166 
167 void PromiseResolve(const FunctionCallbackInfo<Value>& args) {
168  Local<Context> context = args.GetIsolate()->GetCurrentContext();
169  Local<Value> promise = args[0];
170  CHECK(promise->IsPromise());
171  if (promise.As<Promise>()->State() != Promise::kPending) return;
172  Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>(); // sic
173  Maybe<bool> ret = resolver->Resolve(context, args[1]);
174  args.GetReturnValue().Set(ret.FromMaybe(false));
175 }
176 
177 
178 void PromiseReject(const FunctionCallbackInfo<Value>& args) {
179  Local<Context> context = args.GetIsolate()->GetCurrentContext();
180  Local<Value> promise = args[0];
181  CHECK(promise->IsPromise());
182  if (promise.As<Promise>()->State() != Promise::kPending) return;
183  Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>(); // sic
184  Maybe<bool> ret = resolver->Reject(context, args[1]);
185  args.GetReturnValue().Set(ret.FromMaybe(false));
186 }
187 
188 
189 void Initialize(Local<Object> target,
190  Local<Value> unused,
191  Local<Context> context) {
192  Environment* env = Environment::GetCurrent(context);
193 
194 #define V(lcname, ucname) env->SetMethod(target, #lcname, ucname);
196 #undef V
197 
198  env->SetMethod(target, "isAnyArrayBuffer", IsAnyArrayBuffer);
199 
200 #define V(name, _) \
201  target->Set(context, \
202  FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
203  Integer::NewFromUnsigned(env->isolate(), index++)).FromJust();
204  {
205  uint32_t index = 0;
206  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
207  }
208 #undef V
209 
210  target->DefineOwnProperty(
211  env->context(),
212  OneByteString(env->isolate(), "pushValToArrayMax"),
213  Integer::NewFromUnsigned(env->isolate(), NODE_PUSH_VAL_TO_ARRAY_MAX),
214  v8::ReadOnly).FromJust();
215 
216 #define V(name) \
217  target->Set(context, \
218  FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
219  Integer::New(env->isolate(), Promise::PromiseState::name)) \
220  .FromJust()
221  V(kPending);
222  V(kFulfilled);
223  V(kRejected);
224 #undef V
225 
226  env->SetMethod(target, "getHiddenValue", GetHiddenValue);
227  env->SetMethod(target, "setHiddenValue", SetHiddenValue);
228  env->SetMethod(target, "getPromiseDetails", GetPromiseDetails);
229  env->SetMethod(target, "getProxyDetails", GetProxyDetails);
230  env->SetMethod(target, "safeToString", SafeToString);
231 
232  env->SetMethod(target, "startSigintWatchdog", StartSigintWatchdog);
233  env->SetMethod(target, "stopSigintWatchdog", StopSigintWatchdog);
234  env->SetMethod(target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
235 
236  env->SetMethod(target, "createPromise", CreatePromise);
237  env->SetMethod(target, "promiseResolve", PromiseResolve);
238  env->SetMethod(target, "promiseReject", PromiseReject);
239 }
240 
241 } // namespace util
242 } // namespace node
243 
void Initialize(Local< Object > target, Local< Value > unused, Local< Context > context)
Definition: node_util.cc:189
NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, node::inspector::Agent::InitInspector)
#define VALUE_METHOD_MAP(V)
Definition: node_util.cc:23
void StartSigintWatchdog(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:138
void PromiseReject(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:178
void PromiseResolve(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:167
void WatchdogHasPendingSigint(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:153
void StopSigintWatchdog(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:147
void CreatePromise(const FunctionCallbackInfo< Value > &args)
Definition: node_util.cc:159
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
Definition: node_buffer.cc:241
Local< Private > IndexToPrivateSymbol(Environment *env, uint32_t index)
Definition: node_util.cc:93
#define V(_, ucname)
Definition: node_util.cc:40