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