-
Notifications
You must be signed in to change notification settings - Fork 30.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src: make a Environment-independent proxy class for NativeModuleLoader
This patch splits `NativeModuleLoader` into two parts - a singleton that only relies on v8 and `node::Mutex` and a proxy class for the singleton (`NativeModuleEnv`) that provides limited access to the singleton as well as C++ bindings for the Node.js binary. `NativeModuleLoader` is then no longer aware of `Environment`. PR-URL: #27160 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Richard Lau <[email protected]>
- v23.9.0
- v23.8.0
- v23.7.0
- v23.6.1
- v23.6.0
- v23.5.0
- v23.4.0
- v23.3.0
- v23.2.0
- v23.1.0
- v23.0.0
- v22.14.0
- v22.13.1
- v22.13.0
- v22.12.0
- v22.11.0
- v22.10.0
- v22.9.0
- v22.8.0
- v22.7.0
- v22.6.0
- v22.5.1
- v22.5.0
- v22.4.1
- v22.4.0
- v22.3.0
- v22.2.0
- v22.1.0
- v22.0.0
- v21.7.3
- v21.7.2
- v21.7.1
- v21.7.0
- v21.6.2
- v21.6.1
- v21.6.0
- v21.5.0
- v21.4.0
- v21.3.0
- v21.2.0
- v21.1.0
- v21.0.0
- v20.18.3
- v20.18.2
- v20.18.1
- v20.18.0
- v20.17.0
- v20.16.0
- v20.15.1
- v20.15.0
- v20.14.0
- v20.13.1
- v20.13.0
- v20.12.2
- v20.12.1
- v20.12.0
- v20.11.1
- v20.11.0
- v20.10.0
- v20.9.0
- v20.8.1
- v20.8.0
- v20.7.0
- v20.6.1
- v20.6.0
- v20.5.1
- v20.5.0
- v20.4.0
- v20.3.1
- v20.3.0
- v20.2.0
- v20.1.0
- v20.0.0
- v19.9.0
- v19.8.1
- v19.8.0
- v19.7.0
- v19.6.1
- v19.6.0
- v19.5.0
- v19.4.0
- v19.3.0
- v19.2.0
- v19.1.0
- v19.0.1
- v19.0.0
- v18.20.7
- v18.20.6
- v18.20.5
- v18.20.4
- v18.20.3
- v18.20.2
- v18.20.1
- v18.20.0
- v18.19.1
- v18.19.0
- v18.18.2
- v18.18.1
- v18.18.0
- v18.17.1
- v18.17.0
- v18.16.1
- v18.16.0
- v18.15.0
- v18.14.2
- v18.14.1
- v18.14.0
- v18.13.0
- v18.12.1
- v18.12.0
- v18.11.0
- v18.10.0
- v18.9.1
- v18.9.0
- v18.8.0
- v18.7.0
- v18.6.0
- v18.5.0
- v18.4.0
- v18.3.0
- v18.2.0
- v18.1.0
- v18.0.0
- v17.9.1
- v17.9.0
- v17.8.0
- v17.7.2
- v17.7.1
- v17.7.0
- v17.6.0
- v17.5.0
- v17.4.0
- v17.3.1
- v17.3.0
- v17.2.0
- v17.1.0
- v17.0.1
- v17.0.0
- v16.20.2
- v16.20.1
- v16.20.0
- v16.19.1
- v16.19.0
- v16.18.1
- v16.18.0
- v16.17.1
- v16.17.0
- v16.16.0
- v16.15.1
- v16.15.0
- v16.14.2
- v16.14.1
- v16.14.0
- v16.13.2
- v16.13.1
- v16.13.0
- v16.12.0
- v16.11.1
- v16.11.0
- v16.10.0
- v16.9.1
- v16.9.0
- v16.8.0
- v16.7.0
- v16.6.2
- v16.6.1
- v16.6.0
- v16.5.0
- v16.4.2
- v16.4.1
- v16.4.0
- v16.3.0
- v16.2.0
- v16.1.0
- v16.0.0
- v15.14.0
- v15.13.0
- v15.12.0
- v15.11.0
- v15.10.0
- v15.9.0
- v15.8.0
- v15.7.0
- v15.6.0
- v15.5.1
- v15.5.0
- v15.4.0
- v15.3.0
- v15.2.1
- v15.2.0
- v15.1.0
- v15.0.1
- v15.0.0
- v14.21.3
- v14.21.2
- v14.21.1
- v14.21.0
- v14.20.1
- v14.20.0
- v14.19.3
- v14.19.2
- v14.19.1
- v14.19.0
- v14.18.3
- v14.18.2
- v14.18.1
- v14.18.0
- v14.17.6
- v14.17.5
- v14.17.4
- v14.17.3
- v14.17.2
- v14.17.1
- v14.17.0
- v14.16.1
- v14.16.0
- v14.15.5
- v14.15.4
- v14.15.3
- v14.15.2
- v14.15.1
- v14.15.0
- v14.14.0
- v14.13.1
- v14.13.0
- v14.12.0
- v14.11.0
- v14.10.1
- v14.10.0
- v14.9.0
- v14.8.0
- v14.7.0
- v14.6.0
- v14.5.0
- v14.4.0
- v14.3.0
- v14.2.0
- v14.1.0
- v14.0.0
- v13.14.0
- v13.13.0
- v13.12.0
- v13.11.0
- v13.10.1
- v13.10.0
- v13.9.0
- v13.8.0
- v13.7.0
- v13.6.0
- v13.5.0
- v13.4.0
- v13.3.0
- v13.2.0
- v13.1.0
- v13.0.1
- v13.0.0
- v12.22.12
- v12.22.11
- v12.22.10
- v12.22.9
- v12.22.8
- v12.22.7
- v12.22.6
- v12.22.5
- v12.22.4
- v12.22.3
- v12.22.2
- v12.22.1
- v12.22.0
- v12.21.0
- v12.20.2
- v12.20.1
- v12.20.0
- v12.19.1
- v12.19.0
- v12.18.4
- v12.18.3
- v12.18.2
- v12.18.1
- v12.18.0
- v12.17.0
- v12.16.3
- v12.16.2
- v12.16.1
- v12.16.0
- v12.15.0
- v12.14.1
- v12.14.0
- v12.13.1
- v12.13.0
- v12.12.0
- v12.11.1
- v12.11.0
- v12.10.0
- v12.9.1
- v12.9.0
- v12.8.1
- v12.8.0
- v12.7.0
- v12.6.0
- v12.5.0
- v12.4.0
- v12.3.1
- v12.3.0
- v12.2.0
- v12.1.0
- v12.0.0
1 parent
9b6b567
commit dfd7e99
Showing
12 changed files
with
431 additions
and
329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
#include "node_native_module_env.h" | ||
#include "env-inl.h" | ||
|
||
namespace node { | ||
namespace native_module { | ||
|
||
using v8::ArrayBuffer; | ||
using v8::Context; | ||
using v8::DEFAULT; | ||
using v8::Function; | ||
using v8::FunctionCallbackInfo; | ||
using v8::IntegrityLevel; | ||
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::ScriptCompiler; | ||
using v8::Set; | ||
using v8::SideEffectType; | ||
using v8::String; | ||
using v8::Uint8Array; | ||
using v8::Value; | ||
|
||
// TODO(joyeecheung): make these more general and put them into util.h | ||
Local<Set> ToJsSet(Local<Context> context, const std::set<std::string>& in) { | ||
Isolate* isolate = context->GetIsolate(); | ||
Local<Set> out = Set::New(isolate); | ||
for (auto const& x : in) { | ||
out->Add(context, OneByteString(isolate, x.c_str(), x.size())) | ||
.ToLocalChecked(); | ||
} | ||
return out; | ||
} | ||
|
||
bool NativeModuleEnv::Exists(const char* id) { | ||
return NativeModuleLoader::GetInstance()->Exists(id); | ||
} | ||
|
||
Local<Object> NativeModuleEnv::GetSourceObject(Local<Context> context) { | ||
return NativeModuleLoader::GetInstance()->GetSourceObject(context); | ||
} | ||
|
||
Local<String> NativeModuleEnv::GetConfigString(Isolate* isolate) { | ||
return NativeModuleLoader::GetInstance()->GetConfigString(isolate); | ||
} | ||
|
||
void NativeModuleEnv::GetModuleCategories( | ||
Local<Name> property, const PropertyCallbackInfo<Value>& info) { | ||
Environment* env = Environment::GetCurrent(info); | ||
Isolate* isolate = env->isolate(); | ||
Local<Context> context = env->context(); | ||
Local<Object> result = Object::New(isolate); | ||
|
||
// Copy from the per-process categories | ||
std::set<std::string> cannot_be_required = | ||
NativeModuleLoader::GetInstance()->GetCannotBeRequired(); | ||
std::set<std::string> can_be_required = | ||
NativeModuleLoader::GetInstance()->GetCanBeRequired(); | ||
|
||
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 NativeModuleEnv::GetCacheUsage(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
Isolate* isolate = env->isolate(); | ||
Local<Context> context = env->context(); | ||
Local<Object> result = Object::New(isolate); | ||
result | ||
->Set(env->context(), | ||
OneByteString(isolate, "compiledWithCache"), | ||
ToJsSet(context, env->native_modules_with_cache)) | ||
.FromJust(); | ||
result | ||
->Set(env->context(), | ||
OneByteString(isolate, "compiledWithoutCache"), | ||
ToJsSet(context, env->native_modules_without_cache)) | ||
.FromJust(); | ||
args.GetReturnValue().Set(result); | ||
} | ||
|
||
void NativeModuleEnv::ModuleIdsGetter(Local<Name> property, | ||
const PropertyCallbackInfo<Value>& info) { | ||
Isolate* isolate = info.GetIsolate(); | ||
|
||
std::vector<std::string> ids = | ||
NativeModuleLoader::GetInstance()->GetModuleIds(); | ||
info.GetReturnValue().Set( | ||
ToV8Value(isolate->GetCurrentContext(), ids).ToLocalChecked()); | ||
} | ||
|
||
void NativeModuleEnv::ConfigStringGetter( | ||
Local<Name> property, const PropertyCallbackInfo<Value>& info) { | ||
info.GetReturnValue().Set(GetConfigString(info.GetIsolate())); | ||
} | ||
|
||
void NativeModuleEnv::RecordResult(const char* id, | ||
NativeModuleLoader::Result result, | ||
Environment* env) { | ||
if (result == NativeModuleLoader::Result::kWithCache) { | ||
env->native_modules_with_cache.insert(id); | ||
} else { | ||
env->native_modules_without_cache.insert(id); | ||
} | ||
} | ||
void NativeModuleEnv::CompileFunction(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
CHECK(args[0]->IsString()); | ||
node::Utf8Value id_v(env->isolate(), args[0].As<String>()); | ||
const char* id = *id_v; | ||
NativeModuleLoader::Result result; | ||
MaybeLocal<Function> maybe = | ||
NativeModuleLoader::GetInstance()->CompileAsModule( | ||
env->context(), id, &result); | ||
RecordResult(id, result, env); | ||
if (!maybe.IsEmpty()) { | ||
args.GetReturnValue().Set(maybe.ToLocalChecked()); | ||
} | ||
} | ||
|
||
// Returns Local<Function> of the compiled module if return_code_cache | ||
// is false (we are only compiling the function). | ||
// Otherwise return a Local<Object> containing the cache. | ||
MaybeLocal<Function> NativeModuleEnv::LookupAndCompile( | ||
Local<Context> context, | ||
const char* id, | ||
std::vector<Local<String>>* parameters, | ||
Environment* optional_env) { | ||
NativeModuleLoader::Result result; | ||
MaybeLocal<Function> maybe = | ||
NativeModuleLoader::GetInstance()->LookupAndCompile( | ||
context, id, parameters, &result); | ||
if (optional_env != nullptr) { | ||
RecordResult(id, result, optional_env); | ||
} | ||
return maybe; | ||
} | ||
|
||
// This is supposed to be run only by the main thread in | ||
// tools/generate_code_cache.js | ||
void NativeModuleEnv::GetCodeCache(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
Isolate* isolate = env->isolate(); | ||
CHECK(env->is_main_thread()); | ||
|
||
CHECK(args[0]->IsString()); | ||
node::Utf8Value id_v(isolate, args[0].As<String>()); | ||
const char* id = *id_v; | ||
|
||
ScriptCompiler::CachedData* cached_data = | ||
NativeModuleLoader::GetInstance()->GetCodeCache(id); | ||
if (cached_data != nullptr) { | ||
Local<ArrayBuffer> buf = ArrayBuffer::New(isolate, cached_data->length); | ||
memcpy(buf->GetContents().Data(), cached_data->data, cached_data->length); | ||
args.GetReturnValue().Set(Uint8Array::New(buf, 0, cached_data->length)); | ||
} | ||
} | ||
|
||
// TODO(joyeecheung): It is somewhat confusing that Class::Initialize | ||
// is used to initilaize to the binding, but it is the current convention. | ||
// Rename this across the code base to something that makes more sense. | ||
void NativeModuleEnv::Initialize(Local<Object> target, | ||
Local<Value> unused, | ||
Local<Context> context, | ||
void* priv) { | ||
Environment* env = Environment::GetCurrent(context); | ||
|
||
target | ||
->SetAccessor(env->context(), | ||
env->config_string(), | ||
ConfigStringGetter, | ||
nullptr, | ||
MaybeLocal<Value>(), | ||
DEFAULT, | ||
None, | ||
SideEffectType::kHasNoSideEffect) | ||
.Check(); | ||
target | ||
->SetAccessor(env->context(), | ||
FIXED_ONE_BYTE_STRING(env->isolate(), "moduleIds"), | ||
ModuleIdsGetter, | ||
nullptr, | ||
MaybeLocal<Value>(), | ||
DEFAULT, | ||
None, | ||
SideEffectType::kHasNoSideEffect) | ||
.Check(); | ||
|
||
target | ||
->SetAccessor(env->context(), | ||
FIXED_ONE_BYTE_STRING(env->isolate(), "moduleCategories"), | ||
GetModuleCategories, | ||
nullptr, | ||
env->as_callback_data(), | ||
DEFAULT, | ||
None, | ||
SideEffectType::kHasNoSideEffect) | ||
.Check(); | ||
|
||
env->SetMethod(target, "getCacheUsage", NativeModuleEnv::GetCacheUsage); | ||
env->SetMethod(target, "getCodeCache", NativeModuleEnv::GetCodeCache); | ||
env->SetMethod(target, "compileFunction", NativeModuleEnv::CompileFunction); | ||
// internalBinding('native_module') should be frozen | ||
target->SetIntegrityLevel(context, IntegrityLevel::kFrozen).FromJust(); | ||
} | ||
|
||
} // namespace native_module | ||
} // namespace node | ||
|
||
NODE_MODULE_CONTEXT_AWARE_INTERNAL( | ||
native_module, node::native_module::NativeModuleEnv::Initialize) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#ifndef SRC_NODE_NATIVE_MODULE_ENV_H_ | ||
#define SRC_NODE_NATIVE_MODULE_ENV_H_ | ||
|
||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#include "node_native_module.h" | ||
|
||
namespace node { | ||
class Environment; | ||
|
||
namespace native_module { | ||
|
||
class NativeModuleEnv { | ||
public: | ||
static void Initialize(v8::Local<v8::Object> target, | ||
v8::Local<v8::Value> unused, | ||
v8::Local<v8::Context> context, | ||
void* priv); | ||
|
||
static v8::MaybeLocal<v8::Function> LookupAndCompile( | ||
v8::Local<v8::Context> context, | ||
const char* id, | ||
std::vector<v8::Local<v8::String>>* parameters, | ||
Environment* optional_env); | ||
|
||
static v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context); | ||
// Returns config.gypi as a JSON string | ||
static v8::Local<v8::String> GetConfigString(v8::Isolate* isolate); | ||
static bool Exists(const char* id); | ||
|
||
// Loads data into NativeModuleLoader::.instance.code_cache_ | ||
// Generated by mkcodecache as node_code_cache.cc when | ||
// the build is configured with --code-cache-path=.... They are noops | ||
// in node_code_cache_stub.cc | ||
static void InitializeCodeCache(); | ||
|
||
private: | ||
static void RecordResult(const char* id, | ||
NativeModuleLoader::Result result, | ||
Environment* env); | ||
static void GetModuleCategories( | ||
v8::Local<v8::Name> property, | ||
const v8::PropertyCallbackInfo<v8::Value>& info); | ||
static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
// Passing ids of builtin module source code into JS land as | ||
// internalBinding('native_module').moduleIds | ||
static void ModuleIdsGetter(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 a specific native module as a function | ||
static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
static void GetCodeCache(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
}; | ||
|
||
} // namespace native_module | ||
|
||
} // namespace node | ||
|
||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#endif // SRC_NODE_NATIVE_MODULE_ENV_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters