• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <set>
11 #include <string>
12 #include <vector>
13 #include "node_mutex.h"
14 #include "node_threadsafe_cow.h"
15 #include "node_union_bytes.h"
16 #include "v8.h"
17 
18 // Forward declare test fixture for `friend` declaration.
19 class PerProcessTest;
20 
21 namespace node {
22 class SnapshotBuilder;
23 class ExternalReferenceRegistry;
24 class Realm;
25 
26 namespace builtins {
27 
28 using BuiltinSourceMap = std::map<std::string, UnionBytes>;
29 using BuiltinCodeCacheMap =
30     std::unordered_map<std::string,
31                        std::unique_ptr<v8::ScriptCompiler::CachedData>>;
32 
33 struct CodeCacheInfo {
34   std::string id;
35   std::vector<uint8_t> data;
36 };
37 
38 // Handles compilation and caching of built-in JavaScript modules and
39 // bootstrap scripts, whose source are bundled into the binary as static data.
40 class NODE_EXTERN_PRIVATE BuiltinLoader {
41  public:
42   BuiltinLoader();
43   BuiltinLoader(const BuiltinLoader&) = delete;
44   BuiltinLoader& operator=(const BuiltinLoader&) = delete;
45 
46   static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
47   static void CreatePerIsolateProperties(
48       IsolateData* isolate_data, v8::Local<v8::FunctionTemplate> target);
49   static void CreatePerContextProperties(v8::Local<v8::Object> target,
50                                          v8::Local<v8::Value> unused,
51                                          v8::Local<v8::Context> context,
52                                          void* priv);
53 
54   // The parameters used to compile the scripts are detected based on
55   // the pattern of the id.
56   v8::MaybeLocal<v8::Function> LookupAndCompile(v8::Local<v8::Context> context,
57                                                 const char* id,
58                                                 Realm* optional_realm);
59 
60   v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context,
61                                            const char* id,
62                                            int argc,
63                                            v8::Local<v8::Value> argv[],
64                                            Realm* optional_realm);
65 
66   v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context,
67                                            const char* id,
68                                            Realm* realm);
69 
70   v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context);
71   // Returns config.gypi as a JSON string
72   v8::Local<v8::String> GetConfigString(v8::Isolate* isolate);
73   bool Exists(const char* id);
74   bool Add(const char* id, const UnionBytes& source);
75   bool Add(const char* id, std::string_view utf8source);
76 
77   bool CompileAllBuiltins(v8::Local<v8::Context> context);
78   void RefreshCodeCache(const std::vector<CodeCacheInfo>& in);
79   void CopyCodeCache(std::vector<CodeCacheInfo>* out) const;
80 
81   void CopySourceAndCodeCacheReferenceFrom(const BuiltinLoader* other);
82 
83  private:
84   // Only allow access from friends.
85   friend class CodeCacheBuilder;
86 
87   // Generated by tools/js2c.py as node_javascript.cc
88   void LoadJavaScriptSource();  // Loads data into source_
89   UnionBytes GetConfig();       // Return data for config.gypi
90 
91   std::vector<std::string> GetBuiltinIds() const;
92 
93   struct BuiltinCategories {
94     std::set<std::string> can_be_required;
95     std::set<std::string> cannot_be_required;
96   };
97   // This method builds `BuiltinCategories` from scratch every time,
98   // and is therefore somewhat expensive, but also currently only being
99   // used for testing, so that should not be an issue.
100   BuiltinCategories GetBuiltinCategories() const;
101 
102   const v8::ScriptCompiler::CachedData* GetCodeCache(const char* id) const;
103   enum class Result { kWithCache, kWithoutCache };
104   v8::MaybeLocal<v8::String> LoadBuiltinSource(v8::Isolate* isolate,
105                                                const char* id) const;
106   // If an exception is encountered (e.g. source code contains
107   // syntax error), the returned value is empty.
108   v8::MaybeLocal<v8::Function> LookupAndCompileInternal(
109       v8::Local<v8::Context> context,
110       const char* id,
111       std::vector<v8::Local<v8::String>>* parameters,
112       Result* result);
113 
114   static void RecordResult(const char* id,
115                            BuiltinLoader::Result result,
116                            Realm* realm);
117   static void GetBuiltinCategories(
118       v8::Local<v8::Name> property,
119       const v8::PropertyCallbackInfo<v8::Value>& info);
120   static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
121   // Passing ids of built-in source code into JS land as
122   // internalBinding('builtins').builtinIds
123   static void BuiltinIdsGetter(v8::Local<v8::Name> property,
124                                const v8::PropertyCallbackInfo<v8::Value>& info);
125   // Passing config.gypi into JS land as internalBinding('builtins').config
126   static void ConfigStringGetter(
127       v8::Local<v8::Name> property,
128       const v8::PropertyCallbackInfo<v8::Value>& info);
129   // Compile a specific built-in as a function
130   static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
131   static void HasCachedBuiltins(
132       const v8::FunctionCallbackInfo<v8::Value>& args);
133 
134   void AddExternalizedBuiltin(const char* id, const char* filename);
135 
136   ThreadsafeCopyOnWrite<BuiltinSourceMap> source_;
137 
138   const UnionBytes config_;
139 
140   struct BuiltinCodeCache {
141     RwLock mutex;
142     BuiltinCodeCacheMap map;
143     bool has_code_cache = false;
144   };
145   std::shared_ptr<BuiltinCodeCache> code_cache_;
146 
147   friend class ::PerProcessTest;
148 };
149 }  // namespace builtins
150 
151 }  // namespace node
152 
153 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
154 
155 #endif  // SRC_NODE_BUILTINS_H_
156