Skip to content

Commit 84f0581

Browse files
committed
process: move C++ process events into node_process_events.cc
Move the C++ `process.emit` and `process.emitWarning` methods from `node.cc` into into `node_process_events.cc`, and reuse the implementation in other places that need to do `process.emit` in C++. PR-URL: #25397 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 7824280 commit 84f0581

File tree

5 files changed

+122
-113
lines changed

5 files changed

+122
-113
lines changed

node.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@
370370
'src/node_perf.cc',
371371
'src/node_platform.cc',
372372
'src/node_postmortem_metadata.cc',
373+
'src/node_process_events.cc',
373374
'src/node_process_methods.cc',
374375
'src/node_process_object.cc',
375376
'src/node_serdes.cc',

src/inspector_agent.cc

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -370,26 +370,13 @@ class SameThreadInspectorSession : public InspectorSession {
370370
void NotifyClusterWorkersDebugEnabled(Environment* env) {
371371
Isolate* isolate = env->isolate();
372372
HandleScope handle_scope(isolate);
373-
auto context = env->context();
373+
Local<Context> context = env->context();
374374

375375
// Send message to enable debug in cluster workers
376-
Local<Object> process_object = env->process_object();
377-
Local<Value> emit_fn =
378-
process_object->Get(context, FIXED_ONE_BYTE_STRING(isolate, "emit"))
379-
.ToLocalChecked();
380-
// In case the thread started early during the startup
381-
if (!emit_fn->IsFunction())
382-
return;
383-
384376
Local<Object> message = Object::New(isolate);
385377
message->Set(context, FIXED_ONE_BYTE_STRING(isolate, "cmd"),
386378
FIXED_ONE_BYTE_STRING(isolate, "NODE_DEBUG_ENABLED")).FromJust();
387-
Local<Value> argv[] = {
388-
FIXED_ONE_BYTE_STRING(isolate, "internalMessage"),
389-
message
390-
};
391-
MakeCallback(env->isolate(), process_object, emit_fn.As<Function>(),
392-
arraysize(argv), argv, {0, 0});
379+
ProcessEmit(env, "internalMessage", message);
393380
}
394381

395382
#ifdef _WIN32

src/node.cc

Lines changed: 7 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ using v8::Maybe;
124124
using v8::MaybeLocal;
125125
using v8::Message;
126126
using v8::MicrotasksPolicy;
127-
using v8::NewStringType;
128-
using v8::Nothing;
129127
using v8::Object;
130128
using v8::ObjectTemplate;
131129
using v8::Script;
@@ -582,82 +580,6 @@ void Exit(const FunctionCallbackInfo<Value>& args) {
582580
env->Exit(code);
583581
}
584582

585-
static Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
586-
const char* warning,
587-
const char* type = nullptr,
588-
const char* code = nullptr) {
589-
HandleScope handle_scope(env->isolate());
590-
Context::Scope context_scope(env->context());
591-
592-
Local<Object> process = env->process_object();
593-
Local<Value> emit_warning;
594-
if (!process->Get(env->context(),
595-
env->emit_warning_string()).ToLocal(&emit_warning)) {
596-
return Nothing<bool>();
597-
}
598-
599-
if (!emit_warning->IsFunction()) return Just(false);
600-
601-
int argc = 0;
602-
Local<Value> args[3]; // warning, type, code
603-
604-
// The caller has to be able to handle a failure anyway, so we might as well
605-
// do proper error checking for string creation.
606-
if (!String::NewFromUtf8(env->isolate(),
607-
warning,
608-
NewStringType::kNormal).ToLocal(&args[argc++])) {
609-
return Nothing<bool>();
610-
}
611-
if (type != nullptr) {
612-
if (!String::NewFromOneByte(env->isolate(),
613-
reinterpret_cast<const uint8_t*>(type),
614-
NewStringType::kNormal)
615-
.ToLocal(&args[argc++])) {
616-
return Nothing<bool>();
617-
}
618-
if (code != nullptr &&
619-
!String::NewFromOneByte(env->isolate(),
620-
reinterpret_cast<const uint8_t*>(code),
621-
NewStringType::kNormal)
622-
.ToLocal(&args[argc++])) {
623-
return Nothing<bool>();
624-
}
625-
}
626-
627-
// MakeCallback() unneeded because emitWarning is internal code, it calls
628-
// process.emit('warning', ...), but does so on the nextTick.
629-
if (emit_warning.As<Function>()->Call(env->context(),
630-
process,
631-
argc,
632-
args).IsEmpty()) {
633-
return Nothing<bool>();
634-
}
635-
return Just(true);
636-
}
637-
638-
639-
// Call process.emitWarning(str), fmt is a snprintf() format string
640-
Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
641-
char warning[1024];
642-
va_list ap;
643-
644-
va_start(ap, fmt);
645-
vsnprintf(warning, sizeof(warning), fmt, ap);
646-
va_end(ap);
647-
648-
return ProcessEmitWarningGeneric(env, warning);
649-
}
650-
651-
652-
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
653-
const char* warning,
654-
const char* deprecation_code) {
655-
return ProcessEmitWarningGeneric(env,
656-
warning,
657-
"DeprecationWarning",
658-
deprecation_code);
659-
}
660-
661583
static void OnMessage(Local<Message> message, Local<Value> error) {
662584
Isolate* isolate = message->GetIsolate();
663585
switch (message->ErrorLevel()) {
@@ -1160,19 +1082,14 @@ void RunBeforeExit(Environment* env) {
11601082
void EmitBeforeExit(Environment* env) {
11611083
HandleScope handle_scope(env->isolate());
11621084
Context::Scope context_scope(env->context());
1163-
Local<Object> process_object = env->process_object();
1164-
Local<String> exit_code = env->exit_code_string();
1165-
Local<Value> args[] = {
1166-
FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
1167-
process_object->Get(env->context(), exit_code).ToLocalChecked()
1168-
->ToInteger(env->context()).ToLocalChecked()
1169-
};
1170-
MakeCallback(env->isolate(),
1171-
process_object, "emit", arraysize(args), args,
1172-
{0, 0}).ToLocalChecked();
1085+
Local<Value> exit_code = env->process_object()
1086+
->Get(env->context(), env->exit_code_string())
1087+
.ToLocalChecked()
1088+
->ToInteger(env->context())
1089+
.ToLocalChecked();
1090+
ProcessEmit(env, "beforeExit", exit_code).ToLocalChecked();
11731091
}
11741092

1175-
11761093
int EmitExit(Environment* env) {
11771094
// process.emit('exit')
11781095
HandleScope handle_scope(env->isolate());
@@ -1185,15 +1102,7 @@ int EmitExit(Environment* env) {
11851102
Local<String> exit_code = env->exit_code_string();
11861103
int code = process_object->Get(env->context(), exit_code).ToLocalChecked()
11871104
->Int32Value(env->context()).ToChecked();
1188-
1189-
Local<Value> args[] = {
1190-
FIXED_ONE_BYTE_STRING(env->isolate(), "exit"),
1191-
Integer::New(env->isolate(), code)
1192-
};
1193-
1194-
MakeCallback(env->isolate(),
1195-
process_object, "emit", arraysize(args), args,
1196-
{0, 0}).ToLocalChecked();
1105+
ProcessEmit(env, "exit", Integer::New(env->isolate(), code));
11971106

11981107
// Reload exit code, it may be changed by `emit('exit')`
11991108
return process_object->Get(env->context(), exit_code).ToLocalChecked()

src/node_process.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ v8::Local<v8::Object> CreateEnvVarProxy(v8::Local<v8::Context> context,
1717
// function, it is useful to bypass JavaScript entirely.
1818
void RawDebug(const v8::FunctionCallbackInfo<v8::Value>& args);
1919

20+
v8::MaybeLocal<v8::Value> ProcessEmit(Environment* env,
21+
const char* event,
22+
v8::Local<v8::Value> message);
23+
24+
v8::Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
25+
const char* warning,
26+
const char* type = nullptr,
27+
const char* code = nullptr);
28+
2029
v8::Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...);
2130
v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
2231
const char* warning,

src/node_process_events.cc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <stdarg.h>
2+
3+
#include "env.h"
4+
#include "node_internals.h"
5+
#include "node_process.h"
6+
7+
namespace node {
8+
using v8::Context;
9+
using v8::Function;
10+
using v8::HandleScope;
11+
using v8::Isolate;
12+
using v8::Just;
13+
using v8::Local;
14+
using v8::Maybe;
15+
using v8::MaybeLocal;
16+
using v8::NewStringType;
17+
using v8::Nothing;
18+
using v8::Object;
19+
using v8::String;
20+
using v8::Value;
21+
22+
MaybeLocal<Value> ProcessEmit(Environment* env,
23+
const char* event,
24+
Local<Value> message) {
25+
// Send message to enable debug in cluster workers
26+
Local<Object> process = env->process_object();
27+
Isolate* isolate = env->isolate();
28+
Local<Value> argv[] = {OneByteString(isolate, event), message};
29+
30+
return MakeCallback(isolate, process, "emit", arraysize(argv), argv, {0, 0});
31+
}
32+
33+
Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
34+
const char* warning,
35+
const char* type,
36+
const char* code) {
37+
HandleScope handle_scope(env->isolate());
38+
Context::Scope context_scope(env->context());
39+
40+
Local<Object> process = env->process_object();
41+
Local<Value> emit_warning;
42+
if (!process->Get(env->context(), env->emit_warning_string())
43+
.ToLocal(&emit_warning)) {
44+
return Nothing<bool>();
45+
}
46+
47+
if (!emit_warning->IsFunction()) return Just(false);
48+
49+
int argc = 0;
50+
Local<Value> args[3]; // warning, type, code
51+
52+
// The caller has to be able to handle a failure anyway, so we might as well
53+
// do proper error checking for string creation.
54+
if (!String::NewFromUtf8(env->isolate(), warning, NewStringType::kNormal)
55+
.ToLocal(&args[argc++])) {
56+
return Nothing<bool>();
57+
}
58+
if (type != nullptr) {
59+
if (!String::NewFromOneByte(env->isolate(),
60+
reinterpret_cast<const uint8_t*>(type),
61+
NewStringType::kNormal)
62+
.ToLocal(&args[argc++])) {
63+
return Nothing<bool>();
64+
}
65+
if (code != nullptr &&
66+
!String::NewFromOneByte(env->isolate(),
67+
reinterpret_cast<const uint8_t*>(code),
68+
NewStringType::kNormal)
69+
.ToLocal(&args[argc++])) {
70+
return Nothing<bool>();
71+
}
72+
}
73+
74+
// MakeCallback() unneeded because emitWarning is internal code, it calls
75+
// process.emit('warning', ...), but does so on the nextTick.
76+
if (emit_warning.As<Function>()
77+
->Call(env->context(), process, argc, args)
78+
.IsEmpty()) {
79+
return Nothing<bool>();
80+
}
81+
return Just(true);
82+
}
83+
84+
// Call process.emitWarning(str), fmt is a snprintf() format string
85+
Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
86+
char warning[1024];
87+
va_list ap;
88+
89+
va_start(ap, fmt);
90+
vsnprintf(warning, sizeof(warning), fmt, ap);
91+
va_end(ap);
92+
93+
return ProcessEmitWarningGeneric(env, warning);
94+
}
95+
96+
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
97+
const char* warning,
98+
const char* deprecation_code) {
99+
return ProcessEmitWarningGeneric(
100+
env, warning, "DeprecationWarning", deprecation_code);
101+
}
102+
103+
} // namespace node

0 commit comments

Comments
 (0)