11cb0ef41Sopenharmony_ci#ifndef SRC_NODE_BUILTINS_H_
21cb0ef41Sopenharmony_ci#define SRC_NODE_BUILTINS_H_
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci#include <list>
71cb0ef41Sopenharmony_ci#include <map>
81cb0ef41Sopenharmony_ci#include <memory>
91cb0ef41Sopenharmony_ci#include <optional>
101cb0ef41Sopenharmony_ci#include <set>
111cb0ef41Sopenharmony_ci#include <string>
121cb0ef41Sopenharmony_ci#include <vector>
131cb0ef41Sopenharmony_ci#include "node_mutex.h"
141cb0ef41Sopenharmony_ci#include "node_threadsafe_cow.h"
151cb0ef41Sopenharmony_ci#include "node_union_bytes.h"
161cb0ef41Sopenharmony_ci#include "v8.h"
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci// Forward declare test fixture for `friend` declaration.
191cb0ef41Sopenharmony_ciclass PerProcessTest;
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cinamespace node {
221cb0ef41Sopenharmony_ciclass SnapshotBuilder;
231cb0ef41Sopenharmony_ciclass ExternalReferenceRegistry;
241cb0ef41Sopenharmony_ciclass Realm;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace builtins {
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciusing BuiltinSourceMap = std::map<std::string, UnionBytes>;
291cb0ef41Sopenharmony_ciusing BuiltinCodeCacheMap =
301cb0ef41Sopenharmony_ci    std::unordered_map<std::string,
311cb0ef41Sopenharmony_ci                       std::unique_ptr<v8::ScriptCompiler::CachedData>>;
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cistruct CodeCacheInfo {
341cb0ef41Sopenharmony_ci  std::string id;
351cb0ef41Sopenharmony_ci  std::vector<uint8_t> data;
361cb0ef41Sopenharmony_ci};
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// Handles compilation and caching of built-in JavaScript modules and
391cb0ef41Sopenharmony_ci// bootstrap scripts, whose source are bundled into the binary as static data.
401cb0ef41Sopenharmony_ciclass NODE_EXTERN_PRIVATE BuiltinLoader {
411cb0ef41Sopenharmony_ci public:
421cb0ef41Sopenharmony_ci  BuiltinLoader();
431cb0ef41Sopenharmony_ci  BuiltinLoader(const BuiltinLoader&) = delete;
441cb0ef41Sopenharmony_ci  BuiltinLoader& operator=(const BuiltinLoader&) = delete;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
471cb0ef41Sopenharmony_ci  static void CreatePerIsolateProperties(
481cb0ef41Sopenharmony_ci      IsolateData* isolate_data, v8::Local<v8::FunctionTemplate> target);
491cb0ef41Sopenharmony_ci  static void CreatePerContextProperties(v8::Local<v8::Object> target,
501cb0ef41Sopenharmony_ci                                         v8::Local<v8::Value> unused,
511cb0ef41Sopenharmony_ci                                         v8::Local<v8::Context> context,
521cb0ef41Sopenharmony_ci                                         void* priv);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  // The parameters used to compile the scripts are detected based on
551cb0ef41Sopenharmony_ci  // the pattern of the id.
561cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Function> LookupAndCompile(v8::Local<v8::Context> context,
571cb0ef41Sopenharmony_ci                                                const char* id,
581cb0ef41Sopenharmony_ci                                                Realm* optional_realm);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context,
611cb0ef41Sopenharmony_ci                                           const char* id,
621cb0ef41Sopenharmony_ci                                           int argc,
631cb0ef41Sopenharmony_ci                                           v8::Local<v8::Value> argv[],
641cb0ef41Sopenharmony_ci                                           Realm* optional_realm);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> CompileAndCall(v8::Local<v8::Context> context,
671cb0ef41Sopenharmony_ci                                           const char* id,
681cb0ef41Sopenharmony_ci                                           Realm* realm);
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context);
711cb0ef41Sopenharmony_ci  // Returns config.gypi as a JSON string
721cb0ef41Sopenharmony_ci  v8::Local<v8::String> GetConfigString(v8::Isolate* isolate);
731cb0ef41Sopenharmony_ci  bool Exists(const char* id);
741cb0ef41Sopenharmony_ci  bool Add(const char* id, const UnionBytes& source);
751cb0ef41Sopenharmony_ci  bool Add(const char* id, std::string_view utf8source);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  bool CompileAllBuiltins(v8::Local<v8::Context> context);
781cb0ef41Sopenharmony_ci  void RefreshCodeCache(const std::vector<CodeCacheInfo>& in);
791cb0ef41Sopenharmony_ci  void CopyCodeCache(std::vector<CodeCacheInfo>* out) const;
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  void CopySourceAndCodeCacheReferenceFrom(const BuiltinLoader* other);
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci private:
841cb0ef41Sopenharmony_ci  // Only allow access from friends.
851cb0ef41Sopenharmony_ci  friend class CodeCacheBuilder;
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  // Generated by tools/js2c.py as node_javascript.cc
881cb0ef41Sopenharmony_ci  void LoadJavaScriptSource();  // Loads data into source_
891cb0ef41Sopenharmony_ci  UnionBytes GetConfig();       // Return data for config.gypi
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  std::vector<std::string> GetBuiltinIds() const;
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  struct BuiltinCategories {
941cb0ef41Sopenharmony_ci    std::set<std::string> can_be_required;
951cb0ef41Sopenharmony_ci    std::set<std::string> cannot_be_required;
961cb0ef41Sopenharmony_ci  };
971cb0ef41Sopenharmony_ci  // This method builds `BuiltinCategories` from scratch every time,
981cb0ef41Sopenharmony_ci  // and is therefore somewhat expensive, but also currently only being
991cb0ef41Sopenharmony_ci  // used for testing, so that should not be an issue.
1001cb0ef41Sopenharmony_ci  BuiltinCategories GetBuiltinCategories() const;
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  const v8::ScriptCompiler::CachedData* GetCodeCache(const char* id) const;
1031cb0ef41Sopenharmony_ci  enum class Result { kWithCache, kWithoutCache };
1041cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::String> LoadBuiltinSource(v8::Isolate* isolate,
1051cb0ef41Sopenharmony_ci                                               const char* id) const;
1061cb0ef41Sopenharmony_ci  // If an exception is encountered (e.g. source code contains
1071cb0ef41Sopenharmony_ci  // syntax error), the returned value is empty.
1081cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Function> LookupAndCompileInternal(
1091cb0ef41Sopenharmony_ci      v8::Local<v8::Context> context,
1101cb0ef41Sopenharmony_ci      const char* id,
1111cb0ef41Sopenharmony_ci      std::vector<v8::Local<v8::String>>* parameters,
1121cb0ef41Sopenharmony_ci      Result* result);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  static void RecordResult(const char* id,
1151cb0ef41Sopenharmony_ci                           BuiltinLoader::Result result,
1161cb0ef41Sopenharmony_ci                           Realm* realm);
1171cb0ef41Sopenharmony_ci  static void GetBuiltinCategories(
1181cb0ef41Sopenharmony_ci      v8::Local<v8::Name> property,
1191cb0ef41Sopenharmony_ci      const v8::PropertyCallbackInfo<v8::Value>& info);
1201cb0ef41Sopenharmony_ci  static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
1211cb0ef41Sopenharmony_ci  // Passing ids of built-in source code into JS land as
1221cb0ef41Sopenharmony_ci  // internalBinding('builtins').builtinIds
1231cb0ef41Sopenharmony_ci  static void BuiltinIdsGetter(v8::Local<v8::Name> property,
1241cb0ef41Sopenharmony_ci                               const v8::PropertyCallbackInfo<v8::Value>& info);
1251cb0ef41Sopenharmony_ci  // Passing config.gypi into JS land as internalBinding('builtins').config
1261cb0ef41Sopenharmony_ci  static void ConfigStringGetter(
1271cb0ef41Sopenharmony_ci      v8::Local<v8::Name> property,
1281cb0ef41Sopenharmony_ci      const v8::PropertyCallbackInfo<v8::Value>& info);
1291cb0ef41Sopenharmony_ci  // Compile a specific built-in as a function
1301cb0ef41Sopenharmony_ci  static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
1311cb0ef41Sopenharmony_ci  static void HasCachedBuiltins(
1321cb0ef41Sopenharmony_ci      const v8::FunctionCallbackInfo<v8::Value>& args);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  void AddExternalizedBuiltin(const char* id, const char* filename);
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  ThreadsafeCopyOnWrite<BuiltinSourceMap> source_;
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  const UnionBytes config_;
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  struct BuiltinCodeCache {
1411cb0ef41Sopenharmony_ci    RwLock mutex;
1421cb0ef41Sopenharmony_ci    BuiltinCodeCacheMap map;
1431cb0ef41Sopenharmony_ci    bool has_code_cache = false;
1441cb0ef41Sopenharmony_ci  };
1451cb0ef41Sopenharmony_ci  std::shared_ptr<BuiltinCodeCache> code_cache_;
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  friend class ::PerProcessTest;
1481cb0ef41Sopenharmony_ci};
1491cb0ef41Sopenharmony_ci}  // namespace builtins
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci}  // namespace node
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci#endif  // SRC_NODE_BUILTINS_H_
156