From e1d55a0cbc9cd921f8403a550cbfae8497d70d1d Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 2 Apr 2019 06:04:05 +0800 Subject: src: port bootstrap/cache.js to C++ This allows us to query the categories of modules in C++ so we can implement the code cache generator in C++ that does not depend on a Node.js binary. PR-URL: https://github.com/nodejs/node/pull/27046 Refs: https://github.com/nodejs/node/issues/21563 Reviewed-By: Anna Henningsen Reviewed-By: Benjamin Gruenbaum --- src/node_native_module.cc | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'src/node_native_module.cc') diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 41f1588c4d..08c0ab16e3 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -36,6 +36,75 @@ using v8::String; using v8::Uint8Array; using v8::Value; +void NativeModuleLoader::InitializeModuleCategories() { + if (module_categories_.is_initialized) { + DCHECK(!module_categories_.can_be_required.empty()); + return; + } + + std::vector prefixes = { +#if !HAVE_OPENSSL + "internal/crypto/", +#endif // !HAVE_OPENSSL + + "internal/bootstrap/", + "internal/per_context/", + "internal/deps/", + "internal/main/" + }; + + module_categories_.cannot_be_required = std::set { +#if !HAVE_INSPECTOR + "inspector", + "internal/util/inspector", +#endif // !HAVE_INSPECTOR + +#if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT) + "trace_events", +#endif // !NODE_USE_V8_PLATFORM + +#if !HAVE_OPENSSL + "crypto", + "https", + "http2", + "tls", + "_tls_common", + "_tls_wrap", + "internal/http2/core", + "internal/http2/compat", + "internal/policy/manifest", + "internal/process/policy", + "internal/streams/lazy_transform", +#endif // !HAVE_OPENSSL + + "sys", // Deprecated. + "internal/test/binding", + "internal/v8_prof_polyfill", + "internal/v8_prof_processor", + }; + + for (auto const& x : source_) { + const std::string& id = x.first; + for (auto const& prefix : prefixes) { + if (prefix.length() > id.length()) { + continue; + } + if (id.find(prefix) == 0) { + module_categories_.cannot_be_required.emplace(id); + } + } + } + + for (auto const& x : source_) { + const std::string& id = x.first; + if (0 == module_categories_.cannot_be_required.count(id)) { + module_categories_.can_be_required.emplace(id); + } + } + + module_categories_.is_initialized = true; +} + // TODO(joyeecheung): make these more general and put them into util.h Local MapToObject(Local context, const NativeModuleRecordMap& in) { @@ -63,6 +132,39 @@ bool NativeModuleLoader::Exists(const char* id) { return source_.find(id) != source_.end(); } +void NativeModuleLoader::GetModuleCategories( + Local property, const PropertyCallbackInfo& info) { + per_process::native_module_loader.InitializeModuleCategories(); + + Environment* env = Environment::GetCurrent(info); + Isolate* isolate = env->isolate(); + Local context = env->context(); + Local result = Object::New(isolate); + + // Copy from the per-process categories + std::set cannot_be_required = + per_process::native_module_loader.module_categories_.cannot_be_required; + std::set can_be_required = + per_process::native_module_loader.module_categories_.can_be_required; + + if (!env->owns_process_state()) { + can_be_required.erase("trace_events"); + cannot_be_required.insert("trace_events"); + } + + result + ->Set(context, + OneByteString(isolate, "cannotBeRequired"), + ToJsSet(context, cannot_be_required)) + .FromJust(); + result + ->Set(context, + OneByteString(isolate, "canBeRequired"), + ToJsSet(context, can_be_required)) + .FromJust(); + info.GetReturnValue().Set(result); +} + void NativeModuleLoader::GetCacheUsage( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -298,6 +400,18 @@ void NativeModuleLoader::Initialize(Local target, SideEffectType::kHasNoSideEffect) .FromJust()); + CHECK(target + ->SetAccessor( + env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "moduleCategories"), + GetModuleCategories, + nullptr, + env->as_callback_data(), + DEFAULT, + None, + SideEffectType::kHasNoSideEffect) + .FromJust()); + env->SetMethod( target, "getCacheUsage", NativeModuleLoader::GetCacheUsage); env->SetMethod( -- cgit v1.2.3