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
|
#include <cstdarg>
#include <set>
#include "env-inl.h"
#include "node_process.h"
#include "util.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
Isolate* isolate = env->isolate();
Local<String> event_string;
if (!String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(event))
.ToLocal(&event_string)) return MaybeLocal<Value>();
Local<Object> process = env->process_object();
Local<Value> argv[] = {event_string, 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) {
if (!env->can_call_into_js()) return Just(false);
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);
}
std::set<std::string> experimental_warnings;
Maybe<bool> ProcessEmitExperimentalWarning(Environment* env,
const char* warning) {
if (experimental_warnings.find(warning) != experimental_warnings.end())
return Nothing<bool>();
experimental_warnings.insert(warning);
std::string message(warning);
message.append(
" is an experimental feature. This feature could change at any time");
return ProcessEmitWarningGeneric(env, message.c_str(), "ExperimentalWarning");
}
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
const char* warning,
const char* deprecation_code) {
return ProcessEmitWarningGeneric(
env, warning, "DeprecationWarning", deprecation_code);
}
} // namespace node
|