diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2018-12-02 19:49:12 +0300 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2018-12-11 01:40:09 +0300 |
commit | 44a5fe145759a2fa43247da2f40a55df23572944 (patch) | |
tree | 74c346b396e14f5da4fbc85d4a48bd974b2a3432 /src | |
parent | 9fb4fa8ded0504f63c89ed969640e5a2df8d0d59 (diff) |
process: specialize building and storage of process.config
Instead of treating config.gypi as a JavaScript file, specialize
the processing in js2c and make the serialized result a real JSON
string (with 'true' and 'false' converted to boolean values) so
we don't have to use a custom deserializer during bootstrap.
In addition, store the JSON string separately in NativeModuleLoader,
and keep it separate from the map of the builtin source code, so
we don't have to put it onto `NativeModule._source` and delete it
later, though we still preserve it in `process.binding('natives')`,
which we don't use anymore.
This patch also makes the map of builtin source code and the
config.gypi string available through side-effect-free getters
in C++.
PR-URL: https://github.com/nodejs/node/pull/24816
Reviewed-By: Gus Caplan <me@gus.host>
Diffstat (limited to 'src')
-rw-r--r-- | src/env.h | 3 | ||||
-rw-r--r-- | src/node_binding.cc | 7 | ||||
-rw-r--r-- | src/node_native_module.cc | 48 | ||||
-rw-r--r-- | src/node_native_module.h | 18 | ||||
-rw-r--r-- | src/node_union_bytes.h | 10 |
5 files changed, 75 insertions, 11 deletions
diff --git a/src/env.h b/src/env.h index ec0368e040a..b46f45a0d2c 100644 --- a/src/env.h +++ b/src/env.h @@ -138,6 +138,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2; V(channel_string, "channel") \ V(chunks_sent_since_last_write_string, "chunksSentSinceLastWrite") \ V(code_string, "code") \ + V(config_string, "config") \ V(constants_string, "constants") \ V(cwd_string, "cwd") \ V(dest_string, "dest") \ @@ -307,7 +308,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2; V(write_host_object_string, "_writeHostObject") \ V(write_queue_size_string, "writeQueueSize") \ V(x_forwarded_string, "x-forwarded-for") \ - V(zero_return_string, "ZERO_RETURN") \ + V(zero_return_string, "ZERO_RETURN") #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \ V(as_external, v8::External) \ diff --git a/src/node_binding.cc b/src/node_binding.cc index 6d70d0a501e..bdfb74e2744 100644 --- a/src/node_binding.cc +++ b/src/node_binding.cc @@ -412,6 +412,13 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) { DefineConstants(env->isolate(), exports); } else if (!strcmp(*module_v, "natives")) { exports = per_process_loader.GetSourceObject(env->context()); + // Legacy feature: process.binding('natives').config contains stringified + // config.gypi + CHECK(exports + ->Set(env->context(), + env->config_string(), + per_process_loader.GetConfigString(env->isolate())) + .FromJust()); } else { return ThrowIfNoSuchModule(env, *module_v); } diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 6e5f08e3545..85f8d83d63a 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -9,6 +9,7 @@ using v8::Array; using v8::ArrayBuffer; using v8::ArrayBufferCreationMode; using v8::Context; +using v8::DEFAULT; using v8::EscapableHandleScope; using v8::Function; using v8::FunctionCallbackInfo; @@ -19,11 +20,15 @@ using v8::Isolate; using v8::Local; using v8::Maybe; using v8::MaybeLocal; +using v8::Name; +using v8::None; using v8::Object; +using v8::PropertyCallbackInfo; using v8::Script; using v8::ScriptCompiler; using v8::ScriptOrigin; using v8::Set; +using v8::SideEffectType; using v8::String; using v8::Uint8Array; using v8::Value; @@ -70,10 +75,16 @@ void NativeModuleLoader::GetCacheUsage( args.GetReturnValue().Set(result); } -void NativeModuleLoader::GetSourceObject( - const FunctionCallbackInfo<Value>& args) { - Environment* env = Environment::GetCurrent(args); - args.GetReturnValue().Set(per_process_loader.GetSourceObject(env->context())); +void NativeModuleLoader::SourceObjectGetter( + Local<Name> property, const PropertyCallbackInfo<Value>& info) { + Local<Context> context = info.GetIsolate()->GetCurrentContext(); + info.GetReturnValue().Set(per_process_loader.GetSourceObject(context)); +} + +void NativeModuleLoader::ConfigStringGetter( + Local<Name> property, const PropertyCallbackInfo<Value>& info) { + info.GetReturnValue().Set( + per_process_loader.GetConfigString(info.GetIsolate())); } Local<Object> NativeModuleLoader::GetSourceObject( @@ -81,6 +92,10 @@ Local<Object> NativeModuleLoader::GetSourceObject( return MapToObject(context, source_); } +Local<String> NativeModuleLoader::GetConfigString(Isolate* isolate) const { + return config_.ToStringChecked(isolate); +} + Local<String> NativeModuleLoader::GetSource(Isolate* isolate, const char* id) const { const auto it = source_.find(id); @@ -88,7 +103,7 @@ Local<String> NativeModuleLoader::GetSource(Isolate* isolate, return it->second.ToStringChecked(isolate); } -NativeModuleLoader::NativeModuleLoader() { +NativeModuleLoader::NativeModuleLoader() : config_(GetConfig()) { LoadJavaScriptSource(); LoadJavaScriptHash(); LoadCodeCache(); @@ -321,8 +336,27 @@ void NativeModuleLoader::Initialize(Local<Object> target, void* priv) { Environment* env = Environment::GetCurrent(context); - env->SetMethod( - target, "getSource", NativeModuleLoader::GetSourceObject); + CHECK(target + ->SetAccessor(env->context(), + env->config_string(), + ConfigStringGetter, + nullptr, + MaybeLocal<Value>(), + DEFAULT, + None, + SideEffectType::kHasNoSideEffect) + .FromJust()); + CHECK(target + ->SetAccessor(env->context(), + env->source_string(), + SourceObjectGetter, + nullptr, + MaybeLocal<Value>(), + DEFAULT, + None, + SideEffectType::kHasNoSideEffect) + .FromJust()); + env->SetMethod( target, "getCacheUsage", NativeModuleLoader::GetCacheUsage); env->SetMethod( diff --git a/src/node_native_module.h b/src/node_native_module.h index fc0e33c7350..02c769ef023 100644 --- a/src/node_native_module.h +++ b/src/node_native_module.h @@ -40,6 +40,9 @@ class NativeModuleLoader { v8::Local<v8::Context> context, void* priv); v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context) const; + // Returns config.gypi as a JSON string + v8::Local<v8::String> GetConfigString(v8::Isolate* isolate) const; + v8::Local<v8::String> GetSource(v8::Isolate* isolate, const char* id) const; // Run a script with JS source bundled inside the binary as if it's wrapped @@ -56,9 +59,15 @@ class NativeModuleLoader { private: static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args); - // For legacy process.binding('natives') which is mutable, and for - // internalBinding('native_module').source for internal use - static void GetSourceObject(const v8::FunctionCallbackInfo<v8::Value>& args); + // Passing map of builtin module source code into JS land as + // internalBinding('native_module').source + static void SourceObjectGetter( + v8::Local<v8::Name> property, + const v8::PropertyCallbackInfo<v8::Value>& info); + // Passing config.gypi into JS land as internalBinding('native_module').config + static void ConfigStringGetter( + v8::Local<v8::Name> property, + const v8::PropertyCallbackInfo<v8::Value>& info); // Compile code cache for a specific native module static void CompileCodeCache(const v8::FunctionCallbackInfo<v8::Value>& args); // Compile a specific native module as a function @@ -67,6 +76,7 @@ class NativeModuleLoader { // Generated by tools/js2c.py as node_javascript.cc void LoadJavaScriptSource(); // Loads data into source_ void LoadJavaScriptHash(); // Loads data into source_hash_ + UnionBytes GetConfig(); // Return data for config.gypi // Generated by tools/generate_code_cache.js as node_code_cache.cc when // the build is configured with --code-cache-path=.... They are noops @@ -94,6 +104,8 @@ class NativeModuleLoader { bool has_code_cache_ = false; NativeModuleRecordMap source_; NativeModuleRecordMap code_cache_; + UnionBytes config_; + NativeModuleHashMap source_hash_; NativeModuleHashMap code_cache_hash_; }; diff --git a/src/node_union_bytes.h b/src/node_union_bytes.h index 128bb11ed0d..66d8509beaf 100644 --- a/src/node_union_bytes.h +++ b/src/node_union_bytes.h @@ -55,21 +55,31 @@ class UnionBytes { : is_one_byte_(false), two_bytes_(data), length_(length) {} UnionBytes(const uint8_t* data, size_t length) : is_one_byte_(true), one_bytes_(data), length_(length) {} + + UnionBytes(const UnionBytes&) = default; + UnionBytes& operator=(const UnionBytes&) = default; + UnionBytes(UnionBytes&&) = default; + UnionBytes& operator=(UnionBytes&&) = default; + bool is_one_byte() const { return is_one_byte_; } const uint16_t* two_bytes_data() const { CHECK(!is_one_byte_); + CHECK_NE(two_bytes_, nullptr); return two_bytes_; } const uint8_t* one_bytes_data() const { CHECK(is_one_byte_); + CHECK_NE(one_bytes_, nullptr); return one_bytes_; } v8::Local<v8::String> ToStringChecked(v8::Isolate* isolate) const { if (is_one_byte_) { + CHECK_NE(one_bytes_, nullptr); NonOwningExternalOneByteResource* source = new NonOwningExternalOneByteResource(one_bytes_, length_); return v8::String::NewExternalOneByte(isolate, source).ToLocalChecked(); } else { + CHECK_NE(two_bytes_, nullptr); NonOwningExternalTwoByteResource* source = new NonOwningExternalTwoByteResource(two_bytes_, length_); return v8::String::NewExternalTwoByte(isolate, source).ToLocalChecked(); |