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: https://github.com/nodejs/node/pull/25397 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
7824280b58
commit
84f0581d36
1
node.gyp
1
node.gyp
@ -370,6 +370,7 @@
|
||||
'src/node_perf.cc',
|
||||
'src/node_platform.cc',
|
||||
'src/node_postmortem_metadata.cc',
|
||||
'src/node_process_events.cc',
|
||||
'src/node_process_methods.cc',
|
||||
'src/node_process_object.cc',
|
||||
'src/node_serdes.cc',
|
||||
|
@ -370,26 +370,13 @@ class SameThreadInspectorSession : public InspectorSession {
|
||||
void NotifyClusterWorkersDebugEnabled(Environment* env) {
|
||||
Isolate* isolate = env->isolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
auto context = env->context();
|
||||
Local<Context> context = env->context();
|
||||
|
||||
// Send message to enable debug in cluster workers
|
||||
Local<Object> process_object = env->process_object();
|
||||
Local<Value> emit_fn =
|
||||
process_object->Get(context, FIXED_ONE_BYTE_STRING(isolate, "emit"))
|
||||
.ToLocalChecked();
|
||||
// In case the thread started early during the startup
|
||||
if (!emit_fn->IsFunction())
|
||||
return;
|
||||
|
||||
Local<Object> message = Object::New(isolate);
|
||||
message->Set(context, FIXED_ONE_BYTE_STRING(isolate, "cmd"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "NODE_DEBUG_ENABLED")).FromJust();
|
||||
Local<Value> argv[] = {
|
||||
FIXED_ONE_BYTE_STRING(isolate, "internalMessage"),
|
||||
message
|
||||
};
|
||||
MakeCallback(env->isolate(), process_object, emit_fn.As<Function>(),
|
||||
arraysize(argv), argv, {0, 0});
|
||||
ProcessEmit(env, "internalMessage", message);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
105
src/node.cc
105
src/node.cc
@ -124,8 +124,6 @@ using v8::Maybe;
|
||||
using v8::MaybeLocal;
|
||||
using v8::Message;
|
||||
using v8::MicrotasksPolicy;
|
||||
using v8::NewStringType;
|
||||
using v8::Nothing;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::Script;
|
||||
@ -582,82 +580,6 @@ void Exit(const FunctionCallbackInfo<Value>& args) {
|
||||
env->Exit(code);
|
||||
}
|
||||
|
||||
static Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
|
||||
const char* warning,
|
||||
const char* type = nullptr,
|
||||
const char* code = nullptr) {
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
|
||||
Local<Object> process = env->process_object();
|
||||
Local<Value> emit_warning;
|
||||
if (!process->Get(env->context(),
|
||||
env->emit_warning_string()).ToLocal(&emit_warning)) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
|
||||
if (!emit_warning->IsFunction()) return Just(false);
|
||||
|
||||
int argc = 0;
|
||||
Local<Value> args[3]; // warning, type, code
|
||||
|
||||
// The caller has to be able to handle a failure anyway, so we might as well
|
||||
// do proper error checking for string creation.
|
||||
if (!String::NewFromUtf8(env->isolate(),
|
||||
warning,
|
||||
NewStringType::kNormal).ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
if (type != nullptr) {
|
||||
if (!String::NewFromOneByte(env->isolate(),
|
||||
reinterpret_cast<const uint8_t*>(type),
|
||||
NewStringType::kNormal)
|
||||
.ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
if (code != nullptr &&
|
||||
!String::NewFromOneByte(env->isolate(),
|
||||
reinterpret_cast<const uint8_t*>(code),
|
||||
NewStringType::kNormal)
|
||||
.ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
// MakeCallback() unneeded because emitWarning is internal code, it calls
|
||||
// process.emit('warning', ...), but does so on the nextTick.
|
||||
if (emit_warning.As<Function>()->Call(env->context(),
|
||||
process,
|
||||
argc,
|
||||
args).IsEmpty()) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
|
||||
// Call process.emitWarning(str), fmt is a snprintf() format string
|
||||
Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
|
||||
char warning[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(warning, sizeof(warning), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ProcessEmitWarningGeneric(env, warning);
|
||||
}
|
||||
|
||||
|
||||
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
|
||||
const char* warning,
|
||||
const char* deprecation_code) {
|
||||
return ProcessEmitWarningGeneric(env,
|
||||
warning,
|
||||
"DeprecationWarning",
|
||||
deprecation_code);
|
||||
}
|
||||
|
||||
static void OnMessage(Local<Message> message, Local<Value> error) {
|
||||
Isolate* isolate = message->GetIsolate();
|
||||
switch (message->ErrorLevel()) {
|
||||
@ -1160,19 +1082,14 @@ void RunBeforeExit(Environment* env) {
|
||||
void EmitBeforeExit(Environment* env) {
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
Local<Object> process_object = env->process_object();
|
||||
Local<String> exit_code = env->exit_code_string();
|
||||
Local<Value> args[] = {
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
|
||||
process_object->Get(env->context(), exit_code).ToLocalChecked()
|
||||
->ToInteger(env->context()).ToLocalChecked()
|
||||
};
|
||||
MakeCallback(env->isolate(),
|
||||
process_object, "emit", arraysize(args), args,
|
||||
{0, 0}).ToLocalChecked();
|
||||
Local<Value> exit_code = env->process_object()
|
||||
->Get(env->context(), env->exit_code_string())
|
||||
.ToLocalChecked()
|
||||
->ToInteger(env->context())
|
||||
.ToLocalChecked();
|
||||
ProcessEmit(env, "beforeExit", exit_code).ToLocalChecked();
|
||||
}
|
||||
|
||||
|
||||
int EmitExit(Environment* env) {
|
||||
// process.emit('exit')
|
||||
HandleScope handle_scope(env->isolate());
|
||||
@ -1185,15 +1102,7 @@ int EmitExit(Environment* env) {
|
||||
Local<String> exit_code = env->exit_code_string();
|
||||
int code = process_object->Get(env->context(), exit_code).ToLocalChecked()
|
||||
->Int32Value(env->context()).ToChecked();
|
||||
|
||||
Local<Value> args[] = {
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), "exit"),
|
||||
Integer::New(env->isolate(), code)
|
||||
};
|
||||
|
||||
MakeCallback(env->isolate(),
|
||||
process_object, "emit", arraysize(args), args,
|
||||
{0, 0}).ToLocalChecked();
|
||||
ProcessEmit(env, "exit", Integer::New(env->isolate(), code));
|
||||
|
||||
// Reload exit code, it may be changed by `emit('exit')`
|
||||
return process_object->Get(env->context(), exit_code).ToLocalChecked()
|
||||
|
@ -17,6 +17,15 @@ v8::Local<v8::Object> CreateEnvVarProxy(v8::Local<v8::Context> context,
|
||||
// function, it is useful to bypass JavaScript entirely.
|
||||
void RawDebug(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
v8::MaybeLocal<v8::Value> ProcessEmit(Environment* env,
|
||||
const char* event,
|
||||
v8::Local<v8::Value> message);
|
||||
|
||||
v8::Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
|
||||
const char* warning,
|
||||
const char* type = nullptr,
|
||||
const char* code = nullptr);
|
||||
|
||||
v8::Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...);
|
||||
v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
|
||||
const char* warning,
|
||||
|
103
src/node_process_events.cc
Normal file
103
src/node_process_events.cc
Normal file
@ -0,0 +1,103 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "env.h"
|
||||
#include "node_internals.h"
|
||||
#include "node_process.h"
|
||||
|
||||
namespace node {
|
||||
using v8::Context;
|
||||
using v8::Function;
|
||||
using v8::HandleScope;
|
||||
using v8::Isolate;
|
||||
using v8::Just;
|
||||
using v8::Local;
|
||||
using v8::Maybe;
|
||||
using v8::MaybeLocal;
|
||||
using v8::NewStringType;
|
||||
using v8::Nothing;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
MaybeLocal<Value> ProcessEmit(Environment* env,
|
||||
const char* event,
|
||||
Local<Value> message) {
|
||||
// Send message to enable debug in cluster workers
|
||||
Local<Object> process = env->process_object();
|
||||
Isolate* isolate = env->isolate();
|
||||
Local<Value> argv[] = {OneByteString(isolate, event), message};
|
||||
|
||||
return MakeCallback(isolate, process, "emit", arraysize(argv), argv, {0, 0});
|
||||
}
|
||||
|
||||
Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
|
||||
const char* warning,
|
||||
const char* type,
|
||||
const char* code) {
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
|
||||
Local<Object> process = env->process_object();
|
||||
Local<Value> emit_warning;
|
||||
if (!process->Get(env->context(), env->emit_warning_string())
|
||||
.ToLocal(&emit_warning)) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
|
||||
if (!emit_warning->IsFunction()) return Just(false);
|
||||
|
||||
int argc = 0;
|
||||
Local<Value> args[3]; // warning, type, code
|
||||
|
||||
// The caller has to be able to handle a failure anyway, so we might as well
|
||||
// do proper error checking for string creation.
|
||||
if (!String::NewFromUtf8(env->isolate(), warning, NewStringType::kNormal)
|
||||
.ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
if (type != nullptr) {
|
||||
if (!String::NewFromOneByte(env->isolate(),
|
||||
reinterpret_cast<const uint8_t*>(type),
|
||||
NewStringType::kNormal)
|
||||
.ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
if (code != nullptr &&
|
||||
!String::NewFromOneByte(env->isolate(),
|
||||
reinterpret_cast<const uint8_t*>(code),
|
||||
NewStringType::kNormal)
|
||||
.ToLocal(&args[argc++])) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
// MakeCallback() unneeded because emitWarning is internal code, it calls
|
||||
// process.emit('warning', ...), but does so on the nextTick.
|
||||
if (emit_warning.As<Function>()
|
||||
->Call(env->context(), process, argc, args)
|
||||
.IsEmpty()) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
// Call process.emitWarning(str), fmt is a snprintf() format string
|
||||
Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
|
||||
char warning[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(warning, sizeof(warning), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ProcessEmitWarningGeneric(env, warning);
|
||||
}
|
||||
|
||||
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
|
||||
const char* warning,
|
||||
const char* deprecation_code) {
|
||||
return ProcessEmitWarningGeneric(
|
||||
env, warning, "DeprecationWarning", deprecation_code);
|
||||
}
|
||||
|
||||
} // namespace node
|
Loading…
x
Reference in New Issue
Block a user