GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_native_module_env.cc Lines: 95 99 96.0 %
Date: 2020-08-07 22:13:19 Branches: 11 16 68.8 %

Line Branch Exec Source
1
#include "node_native_module_env.h"
2
#include "env-inl.h"
3
#include "node_external_reference.h"
4
5
namespace node {
6
namespace native_module {
7
8
using v8::Context;
9
using v8::DEFAULT;
10
using v8::Function;
11
using v8::FunctionCallbackInfo;
12
using v8::IntegrityLevel;
13
using v8::Isolate;
14
using v8::Local;
15
using v8::MaybeLocal;
16
using v8::Name;
17
using v8::None;
18
using v8::Object;
19
using v8::PropertyCallbackInfo;
20
using v8::Set;
21
using v8::SideEffectType;
22
using v8::String;
23
using v8::Value;
24
25
// TODO(joyeecheung): make these more general and put them into util.h
26
4
Local<Set> ToJsSet(Local<Context> context, const std::set<std::string>& in) {
27
4
  Isolate* isolate = context->GetIsolate();
28
4
  Local<Set> out = Set::New(isolate);
29
390
  for (auto const& x : in) {
30
1158
    out->Add(context, OneByteString(isolate, x.c_str(), x.size()))
31
        .ToLocalChecked();
32
  }
33
4
  return out;
34
}
35
36
13
bool NativeModuleEnv::Add(const char* id, const UnionBytes& source) {
37
13
  return NativeModuleLoader::GetInstance()->Add(id, source);
38
}
39
40
bool NativeModuleEnv::Exists(const char* id) {
41
  return NativeModuleLoader::GetInstance()->Exists(id);
42
}
43
44
6
Local<Object> NativeModuleEnv::GetSourceObject(Local<Context> context) {
45
6
  return NativeModuleLoader::GetInstance()->GetSourceObject(context);
46
}
47
48
394
Local<String> NativeModuleEnv::GetConfigString(Isolate* isolate) {
49
394
  return NativeModuleLoader::GetInstance()->GetConfigString(isolate);
50
}
51
52
1
void NativeModuleEnv::GetModuleCategories(
53
    Local<Name> property, const PropertyCallbackInfo<Value>& info) {
54
1
  Environment* env = Environment::GetCurrent(info);
55
1
  Isolate* isolate = env->isolate();
56
1
  Local<Context> context = env->context();
57
1
  Local<Object> result = Object::New(isolate);
58
59
  // Copy from the per-process categories
60
  std::set<std::string> cannot_be_required =
61
2
      NativeModuleLoader::GetInstance()->GetCannotBeRequired();
62
  std::set<std::string> can_be_required =
63
2
      NativeModuleLoader::GetInstance()->GetCanBeRequired();
64
65
1
  if (!env->owns_process_state()) {
66
    can_be_required.erase("trace_events");
67
    cannot_be_required.insert("trace_events");
68
  }
69
70
  result
71
2
      ->Set(context,
72
            OneByteString(isolate, "cannotBeRequired"),
73
4
            ToJsSet(context, cannot_be_required))
74
      .FromJust();
75
  result
76
2
      ->Set(context,
77
            OneByteString(isolate, "canBeRequired"),
78
4
            ToJsSet(context, can_be_required))
79
      .FromJust();
80
2
  info.GetReturnValue().Set(result);
81
1
}
82
83
1
void NativeModuleEnv::GetCacheUsage(const FunctionCallbackInfo<Value>& args) {
84
1
  Environment* env = Environment::GetCurrent(args);
85
1
  Isolate* isolate = env->isolate();
86
1
  Local<Context> context = env->context();
87
1
  Local<Object> result = Object::New(isolate);
88
  result
89
2
      ->Set(env->context(),
90
            OneByteString(isolate, "compiledWithCache"),
91
5
            ToJsSet(context, env->native_modules_with_cache))
92
      .FromJust();
93
  result
94
2
      ->Set(env->context(),
95
            OneByteString(isolate, "compiledWithoutCache"),
96
5
            ToJsSet(context, env->native_modules_without_cache))
97
      .FromJust();
98
99
  result
100
2
      ->Set(env->context(),
101
            OneByteString(isolate, "compiledInSnapshot"),
102
2
            ToV8Value(env->context(), env->native_modules_in_snapshot)
103
4
                .ToLocalChecked())
104
      .FromJust();
105
106
2
  args.GetReturnValue().Set(result);
107
1
}
108
109
389
void NativeModuleEnv::ModuleIdsGetter(Local<Name> property,
110
                                      const PropertyCallbackInfo<Value>& info) {
111
389
  Isolate* isolate = info.GetIsolate();
112
113
  std::vector<std::string> ids =
114
778
      NativeModuleLoader::GetInstance()->GetModuleIds();
115
778
  info.GetReturnValue().Set(
116
778
      ToV8Value(isolate->GetCurrentContext(), ids).ToLocalChecked());
117
389
}
118
119
388
void NativeModuleEnv::ConfigStringGetter(
120
    Local<Name> property, const PropertyCallbackInfo<Value>& info) {
121
1166
  info.GetReturnValue().Set(GetConfigString(info.GetIsolate()));
122
389
}
123
124
323667
void NativeModuleEnv::RecordResult(const char* id,
125
                                   NativeModuleLoader::Result result,
126
                                   Environment* env) {
127
323667
  if (result == NativeModuleLoader::Result::kWithCache) {
128
303209
    env->native_modules_with_cache.insert(id);
129
  } else {
130
20458
    env->native_modules_without_cache.insert(id);
131
  }
132
323667
}
133
317364
void NativeModuleEnv::CompileFunction(const FunctionCallbackInfo<Value>& args) {
134
317364
  Environment* env = Environment::GetCurrent(args);
135
952095
  CHECK(args[0]->IsString());
136
952096
  node::Utf8Value id_v(env->isolate(), args[0].As<String>());
137
317366
  const char* id = *id_v;
138
  NativeModuleLoader::Result result;
139
  MaybeLocal<Function> maybe =
140
      NativeModuleLoader::GetInstance()->CompileAsModule(
141
317362
          env->context(), id, &result);
142
317366
  RecordResult(id, result, env);
143
  Local<Function> fn;
144
317366
  if (maybe.ToLocal(&fn)) {
145
634732
    args.GetReturnValue().Set(fn);
146
  }
147
317366
}
148
149
// Returns Local<Function> of the compiled module if return_code_cache
150
// is false (we are only compiling the function).
151
// Otherwise return a Local<Object> containing the cache.
152
8659
MaybeLocal<Function> NativeModuleEnv::LookupAndCompile(
153
    Local<Context> context,
154
    const char* id,
155
    std::vector<Local<String>>* parameters,
156
    Environment* optional_env) {
157
  NativeModuleLoader::Result result;
158
  MaybeLocal<Function> maybe =
159
      NativeModuleLoader::GetInstance()->LookupAndCompile(
160
8659
          context, id, parameters, &result);
161
8660
  if (optional_env != nullptr) {
162
6301
    RecordResult(id, result, optional_env);
163
  }
164
8660
  return maybe;
165
}
166
167
4
void HasCachedBuiltins(const FunctionCallbackInfo<Value>& args) {
168
16
  args.GetReturnValue().Set(
169
      v8::Boolean::New(args.GetIsolate(), has_code_cache));
170
4
}
171
172
// TODO(joyeecheung): It is somewhat confusing that Class::Initialize
173
// is used to initialize to the binding, but it is the current convention.
174
// Rename this across the code base to something that makes more sense.
175
389
void NativeModuleEnv::Initialize(Local<Object> target,
176
                                 Local<Value> unused,
177
                                 Local<Context> context,
178
                                 void* priv) {
179
389
  Environment* env = Environment::GetCurrent(context);
180
181
  target
182
778
      ->SetAccessor(env->context(),
183
                    env->config_string(),
184
                    ConfigStringGetter,
185
                    nullptr,
186
                    MaybeLocal<Value>(),
187
                    DEFAULT,
188
                    None,
189
1556
                    SideEffectType::kHasNoSideEffect)
190
      .Check();
191
  target
192
778
      ->SetAccessor(env->context(),
193
                    FIXED_ONE_BYTE_STRING(env->isolate(), "moduleIds"),
194
                    ModuleIdsGetter,
195
                    nullptr,
196
                    MaybeLocal<Value>(),
197
                    DEFAULT,
198
                    None,
199
1556
                    SideEffectType::kHasNoSideEffect)
200
      .Check();
201
202
  target
203
778
      ->SetAccessor(env->context(),
204
                    FIXED_ONE_BYTE_STRING(env->isolate(), "moduleCategories"),
205
                    GetModuleCategories,
206
                    nullptr,
207
                    Local<Value>(),
208
                    DEFAULT,
209
                    None,
210
1556
                    SideEffectType::kHasNoSideEffect)
211
      .Check();
212
213
389
  env->SetMethod(target, "getCacheUsage", NativeModuleEnv::GetCacheUsage);
214
389
  env->SetMethod(target, "compileFunction", NativeModuleEnv::CompileFunction);
215
389
  env->SetMethod(target, "hasCachedBuiltins", HasCachedBuiltins);
216
  // internalBinding('native_module') should be frozen
217
778
  target->SetIntegrityLevel(context, IntegrityLevel::kFrozen).FromJust();
218
389
}
219
220
4371
void NativeModuleEnv::RegisterExternalReferences(
221
    ExternalReferenceRegistry* registry) {
222
4371
  registry->Register(ConfigStringGetter);
223
4371
  registry->Register(ModuleIdsGetter);
224
4371
  registry->Register(GetModuleCategories);
225
4371
  registry->Register(GetCacheUsage);
226
4371
  registry->Register(CompileFunction);
227
4371
  registry->Register(HasCachedBuiltins);
228
4371
}
229
230
}  // namespace native_module
231
}  // namespace node
232
233
4440
NODE_MODULE_CONTEXT_AWARE_INTERNAL(
234
    native_module, node::native_module::NativeModuleEnv::Initialize)
235

17694
NODE_MODULE_EXTERNAL_REFERENCE(
236
    native_module,
237
    node::native_module::NativeModuleEnv::RegisterExternalReferences)