Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_builtins.h
1 #ifndef SRC_NODE_BUILTINS_H_ 2 #define SRC_NODE_BUILTINS_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include <list> 7 #include <map> 8 #include <memory> 9 #include <optional> 10 #include <string> 11 #include <unordered_set> 12 #include <vector> 13 #include "node_external_reference.h" 14 #include "node_mutex.h" 15 #include "node_threadsafe_cow.h" 16 #include "node_union_bytes.h" 17 #include "v8.h" 18 19 // Forward declare test fixture for `friend` declaration. 20 class PerProcessTest; 21 22 namespace node { 23 class SnapshotBuilder; 24 class ExternalReferenceRegistry; 25 class Realm; 26 27 namespace builtins { 28 29 class BuiltinCodeCacheData { 30 public: 31 BuiltinCodeCacheData() : data(nullptr), length(0), owning_ptr(nullptr) {} 32 33 explicit BuiltinCodeCacheData( 34 std::shared_ptr<v8::ScriptCompiler::CachedData> cached_data) 35 : data(cached_data->data), 36 length(cached_data->length), 37 owning_ptr(cached_data) {} 38 39 explicit BuiltinCodeCacheData( 40 std::shared_ptr<std::vector<uint8_t>> cached_data) 41 : data(cached_data->data()), 42 length(cached_data->size()), 43 owning_ptr(cached_data) {} 44 45 BuiltinCodeCacheData(const uint8_t* data, size_t length) 46 : data(data), length(length), owning_ptr(nullptr) {} 47 48 const uint8_t* data; 49 size_t length; 50 51 // Returns a v8::ScriptCompiler::CachedData corresponding to this 52 // BuiltinCodeCacheData. The lifetime of the returned 53 // v8::ScriptCompiler::CachedData must not outlive that of the data. 54 std::unique_ptr<v8::ScriptCompiler::CachedData> AsCachedData() { 55 return std::make_unique<v8::ScriptCompiler::CachedData>( 56 data, length, v8::ScriptCompiler::CachedData::BufferNotOwned); 57 } 58 59 private: 60 // If not null, represents a pointer which owns data. Otherwise indicates 61 // that data has static lifetime. 62 std::shared_ptr<void> owning_ptr; 63 }; 64 65 struct CodeCacheInfo { 66 std::string id; 67 BuiltinCodeCacheData data; 68 }; 69 70 using BuiltinSourceMap = std::map<std::string, UnionBytes>; 71 using BuiltinCodeCacheMap = 72 std::unordered_map<std::string, BuiltinCodeCacheData>; 73 74 // Generated by tools/js2c.cc as node_javascript.cc 75 void RegisterExternalReferencesForInternalizedBuiltinCode( 76 ExternalReferenceRegistry* registry); 77 78 // Handles compilation and caching of built-in JavaScript modules and 79 // bootstrap scripts, whose source are bundled into the binary as static data. 80 class NODE_EXTERN_PRIVATE BuiltinLoader { 81 public: 82 BuiltinLoader(); 83 BuiltinLoader(const BuiltinLoader&) = delete; 84 BuiltinLoader& operator=(const BuiltinLoader&) = delete; 85 86 static void RegisterExternalReferences(ExternalReferenceRegistry* registry); 87 static void CreatePerIsolateProperties(IsolateData* isolate_data, 88 v8::Local<v8::ObjectTemplate> target); 89 static void CreatePerContextProperties(v8::Local<v8::Object> target, 90 v8::Local<v8::Value> unused, 91 v8::Local<v8::Context> context, 92 void* priv); 93 94 // The parameters used to compile the scripts are detected based on 95 // the pattern of the id. 96 v8::MaybeLocal<v8::Function> LookupAndCompile(v8::Local<v8::Context> context, 97 const char* id, 98 Realm* optional_realm); 99 100 v8::MaybeLocal<v8::Function> LookupAndCompile( 101 v8::Local<v8::Context> context, 102 const char* id, 103 v8::LocalVector<v8::String>* parameters, 104 Realm* optional_realm); 105 106 v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context, 107 const char* id, 108 int argc, 109 v8::Local<v8::Value> argv[], 110 Realm* optional_realm); 111 112 v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context, 113 const char* id, 114 Realm* realm); 115 116 // Returns config.gypi as a JSON string 117 v8::Local<v8::String> GetConfigString(v8::Isolate* isolate); 118 bool Exists(const char* id); 119 bool Add(const char* id, const UnionBytes& source); 120 121 bool CompileAllBuiltinsAndCopyCodeCache( 122 v8::Local<v8::Context> context, 123 const std::vector<std::string>& lazy_builtins, 124 std::vector<CodeCacheInfo>* out); 125 void RefreshCodeCache(const std::vector<CodeCacheInfo>& in); 126 127 void CopySourceAndCodeCacheReferenceFrom(const BuiltinLoader* other); 128 129 std::vector<std::string_view> GetBuiltinIds() const; 130 131 void SetEagerCompile() { should_eager_compile_ = true; } 132 133 private: 134 // Only allow access from friends. 135 friend class CodeCacheBuilder; 136 137 // Generated by tools/js2c.cc as node_javascript.cc 138 void LoadJavaScriptSource(); // Loads data into source_ 139 UnionBytes GetConfig(); // Return data for config.gypi 140 141 struct BuiltinCategories { 142 std::set<std::string> can_be_required; 143 std::set<std::string> cannot_be_required; 144 }; 145 // This method builds `BuiltinCategories` from scratch every time, 146 // and is therefore somewhat expensive, but also currently only being 147 // used for testing, so that should not be an issue. 148 BuiltinCategories GetBuiltinCategories() const; 149 150 const v8::ScriptCompiler::CachedData* GetCodeCache(const char* id) const; 151 enum class Result { kWithCache, kWithoutCache }; 152 v8::MaybeLocal<v8::String> LoadBuiltinSource(v8::Isolate* isolate, 153 const char* id) const; 154 // If an exception is encountered (e.g. source code contains 155 // syntax error), the returned value is empty. 156 v8::MaybeLocal<v8::Function> LookupAndCompileInternal( 157 v8::Local<v8::Context> context, 158 const char* id, 159 v8::LocalVector<v8::String>* parameters, 160 Realm* optional_realm); 161 void SaveCodeCache(const char* id, v8::Local<v8::Function> fn); 162 163 static void RecordResult(const char* id, 164 BuiltinLoader::Result result, 165 Realm* realm); 166 static void GetBuiltinCategories( 167 v8::Local<v8::Name> property, 168 const v8::PropertyCallbackInfo<v8::Value>& info); 169 static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args); 170 // Passing ids of built-in source code into JS land as 171 // internalBinding('builtins').builtinIds 172 static void BuiltinIdsGetter(v8::Local<v8::Name> property, 173 const v8::PropertyCallbackInfo<v8::Value>& info); 174 // Passing config.gypi into JS land as internalBinding('builtins').config 175 static void ConfigStringGetter( 176 v8::Local<v8::Name> property, 177 const v8::PropertyCallbackInfo<v8::Value>& info); 178 // Compile a specific built-in as a function 179 static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args); 180 static void HasCachedBuiltins( 181 const v8::FunctionCallbackInfo<v8::Value>& args); 182 // For legacy process.binding('natives') 183 static void GetNatives(v8::Local<v8::Name> property, 184 const v8::PropertyCallbackInfo<v8::Value>& info); 185 186 void AddExternalizedBuiltin(const char* id, const char* filename); 187 188 ThreadsafeCopyOnWrite<BuiltinSourceMap> source_; 189 190 const UnionBytes config_; 191 192 // If any bulitins should be eagerly compiled i.e. with inner functions 193 // compiled too, either use should_eager_compile_ to compile all builtins 194 // eagerly, or use to_eager_compile_ to compile specific builtins eagerly. 195 // Currently we set should_eager_compile_ to true when compiling primordials, 196 // and use to_eager_compile_ to compile code cache that complements the 197 // snapshot, where builtins already loaded in the snapshot and a few extras 198 // are compiled eagerly (other less-essential built-ins are compiled lazily to 199 // avoid bloating the binary size). At runtime any additional compilation is 200 // done lazily. 201 bool should_eager_compile_ = false; 202 std::unordered_set<std::string> to_eager_compile_; 203 204 struct BuiltinCodeCache { 205 RwLock mutex; 206 BuiltinCodeCacheMap map; 207 bool has_code_cache = false; 208 }; 209 std::shared_ptr<BuiltinCodeCache> code_cache_; 210 211 friend class ::PerProcessTest; 212 }; 213 214 } // namespace builtins 215 216 } // namespace node 217 218 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 219 220 #endif // SRC_NODE_BUILTINS_H_