#ifndef SRC_NODE_NATIVE_MODULE_H_ #define SRC_NODE_NATIVE_MODULE_H_ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include #include #include #include "env.h" #include "node_mutex.h" #include "node_union_bytes.h" #include "v8.h" namespace node { namespace native_module { using NativeModuleRecordMap = std::map; using NativeModuleCacheMap = std::unordered_map>; // The native (C++) side of the NativeModule in JS land, which // handles compilation and caching of builtin modules (NativeModule) // and bootstrappers, whose source are bundled into the binary // as static data. // This class should not depend on a particular isolate, context, or // environment. Rather it should take them as arguments when necessary. // The instances of this class are per-process. class NativeModuleLoader { public: NativeModuleLoader(); // TODO(joyeecheung): maybe we should make this a singleton, instead of // putting it in per_process. NativeModuleLoader(const NativeModuleLoader&) = delete; NativeModuleLoader& operator=(const NativeModuleLoader&) = delete; static void Initialize(v8::Local target, v8::Local unused, v8::Local context, void* priv); v8::Local GetSourceObject(v8::Local context) const; // Returns config.gypi as a JSON string v8::Local GetConfigString(v8::Isolate* isolate) const; bool Exists(const char* id); // For bootstrappers optional_env may be a nullptr. // If an exception is encountered (e.g. source code contains // syntax error), the returned value is empty. v8::MaybeLocal LookupAndCompile( v8::Local context, const char* id, std::vector>* parameters, Environment* optional_env); private: static void GetCacheUsage(const v8::FunctionCallbackInfo& args); // Passing ids of builtin module source code into JS land as // internalBinding('native_module').moduleIds static void ModuleIdsGetter(v8::Local property, const v8::PropertyCallbackInfo& info); // Passing config.gypi into JS land as internalBinding('native_module').config static void ConfigStringGetter( v8::Local property, const v8::PropertyCallbackInfo& info); // Get code cache for a specific native module static void GetCodeCache(const v8::FunctionCallbackInfo& args); v8::MaybeLocal GetCodeCache(v8::Isolate* isolate, const char* id) const; // Compile a specific native module as a function static void CompileFunction(const v8::FunctionCallbackInfo& args); // Generated by tools/js2c.py as node_javascript.cc void LoadJavaScriptSource(); // Loads data into source_ 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 // in node_code_cache_stub.cc void LoadCodeCache(); // Loads data into code_cache_ // Compile a script as a NativeModule that can be loaded via // NativeModule.p.require in JS land. static v8::MaybeLocal CompileAsModule(Environment* env, const char* id); NativeModuleRecordMap source_; NativeModuleCacheMap code_cache_; UnionBytes config_; // Used to synchronize access to the code cache map Mutex code_cache_mutex_; }; } // namespace native_module namespace per_process { extern native_module::NativeModuleLoader native_module_loader; } // namespace per_process } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #endif // SRC_NODE_NATIVE_MODULE_H_