1 #include <set>
2
3 #include "env-inl.h"
4 #include "node_process-inl.h"
5 #include "util.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::Nothing;
17 using v8::Object;
18 using v8::String;
19 using v8::Value;
20
ProcessEmit(Environment * env,const char * event,Local<Value> message)21 MaybeLocal<Value> ProcessEmit(Environment* env,
22 const char* event,
23 Local<Value> message) {
24 // Send message to enable debug in cluster workers
25 Isolate* isolate = env->isolate();
26
27 Local<String> event_string;
28 if (!String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(event))
29 .ToLocal(&event_string)) return MaybeLocal<Value>();
30
31 Local<Object> process = env->process_object();
32 Local<Value> argv[] = {event_string, message};
33 return MakeCallback(isolate, process, "emit", arraysize(argv), argv, {0, 0});
34 }
35
ProcessEmitWarningGeneric(Environment * env,const char * warning,const char * type,const char * code)36 Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
37 const char* warning,
38 const char* type,
39 const char* code) {
40 if (!env->can_call_into_js()) return Just(false);
41
42 HandleScope handle_scope(env->isolate());
43 Context::Scope context_scope(env->context());
44
45 Local<Object> process = env->process_object();
46 Local<Value> emit_warning;
47 if (!process->Get(env->context(), env->emit_warning_string())
48 .ToLocal(&emit_warning)) {
49 return Nothing<bool>();
50 }
51
52 if (!emit_warning->IsFunction()) return Just(false);
53
54 int argc = 0;
55 Local<Value> args[3]; // warning, type, code
56
57 // The caller has to be able to handle a failure anyway, so we might as well
58 // do proper error checking for string creation.
59 if (!String::NewFromUtf8(env->isolate(), warning).ToLocal(&args[argc++]))
60 return Nothing<bool>();
61
62 if (type != nullptr) {
63 if (!String::NewFromOneByte(env->isolate(),
64 reinterpret_cast<const uint8_t*>(type))
65 .ToLocal(&args[argc++])) {
66 return Nothing<bool>();
67 }
68 if (code != nullptr &&
69 !String::NewFromOneByte(env->isolate(),
70 reinterpret_cast<const uint8_t*>(code))
71 .ToLocal(&args[argc++])) {
72 return Nothing<bool>();
73 }
74 }
75
76 // MakeCallback() unneeded because emitWarning is internal code, it calls
77 // process.emit('warning', ...), but does so on the nextTick.
78 if (emit_warning.As<Function>()
79 ->Call(env->context(), process, argc, args)
80 .IsEmpty()) {
81 return Nothing<bool>();
82 }
83 return Just(true);
84 }
85
86
87 std::set<std::string> experimental_warnings;
88
ProcessEmitExperimentalWarning(Environment * env,const char * warning)89 Maybe<bool> ProcessEmitExperimentalWarning(Environment* env,
90 const char* warning) {
91 if (experimental_warnings.find(warning) != experimental_warnings.end())
92 return Nothing<bool>();
93
94 experimental_warnings.insert(warning);
95 std::string message(warning);
96 message.append(
97 " is an experimental feature. This feature could change at any time");
98 return ProcessEmitWarningGeneric(env, message.c_str(), "ExperimentalWarning");
99 }
100
ProcessEmitDeprecationWarning(Environment * env,const char * warning,const char * deprecation_code)101 Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
102 const char* warning,
103 const char* deprecation_code) {
104 return ProcessEmitWarningGeneric(
105 env, warning, "DeprecationWarning", deprecation_code);
106 }
107
108 } // namespace node
109