1 // Copyright 2021 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef INCLUDE_V8_INITIALIZATION_H_ 6 #define INCLUDE_V8_INITIALIZATION_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include "v8-internal.h" // NOLINT(build/include_directory) 12 #include "v8-isolate.h" // NOLINT(build/include_directory) 13 #include "v8-platform.h" // NOLINT(build/include_directory) 14 #include "v8config.h" // NOLINT(build/include_directory) 15 16 // We reserve the V8_* prefix for macros defined in V8 public API and 17 // assume there are no name conflicts with the embedder's code. 18 19 /** 20 * The v8 JavaScript engine. 21 */ 22 namespace v8 { 23 24 class PageAllocator; 25 class Platform; 26 template <class K, class V, class T> 27 class PersistentValueMapBase; 28 29 /** 30 * EntropySource is used as a callback function when v8 needs a source 31 * of entropy. 32 */ 33 using EntropySource = bool (*)(unsigned char* buffer, size_t length); 34 35 /** 36 * ReturnAddressLocationResolver is used as a callback function when v8 is 37 * resolving the location of a return address on the stack. Profilers that 38 * change the return address on the stack can use this to resolve the stack 39 * location to wherever the profiler stashed the original return address. 40 * 41 * \param return_addr_location A location on stack where a machine 42 * return address resides. 43 * \returns Either return_addr_location, or else a pointer to the profiler's 44 * copy of the original return address. 45 * 46 * \note The resolver function must not cause garbage collection. 47 */ 48 using ReturnAddressLocationResolver = 49 uintptr_t (*)(uintptr_t return_addr_location); 50 51 using DcheckErrorCallback = void (*)(const char* file, int line, 52 const char* message); 53 54 /** 55 * Container class for static utility functions. 56 */ 57 class V8_EXPORT V8 { 58 public: 59 /** 60 * Hand startup data to V8, in case the embedder has chosen to build 61 * V8 with external startup data. 62 * 63 * Note: 64 * - By default the startup data is linked into the V8 library, in which 65 * case this function is not meaningful. 66 * - If this needs to be called, it needs to be called before V8 67 * tries to make use of its built-ins. 68 * - To avoid unnecessary copies of data, V8 will point directly into the 69 * given data blob, so pretty please keep it around until V8 exit. 70 * - Compression of the startup blob might be useful, but needs to 71 * handled entirely on the embedders' side. 72 * - The call will abort if the data is invalid. 73 */ 74 static void SetSnapshotDataBlob(StartupData* startup_blob); 75 76 /** Set the callback to invoke in case of Dcheck failures. */ 77 static void SetDcheckErrorHandler(DcheckErrorCallback that); 78 79 /** 80 * Sets V8 flags from a string. 81 */ 82 static void SetFlagsFromString(const char* str); 83 static void SetFlagsFromString(const char* str, size_t length); 84 85 /** 86 * Sets V8 flags from the command line. 87 */ 88 static void SetFlagsFromCommandLine(int* argc, char** argv, 89 bool remove_flags); 90 91 /** Get the version string. */ 92 static const char* GetVersion(); 93 94 /** 95 * Initializes V8. This function needs to be called before the first Isolate 96 * is created. It always returns true. 97 */ Initialize()98 V8_INLINE static bool Initialize() { 99 const int kBuildConfiguration = 100 (internal::PointerCompressionIsEnabled() ? kPointerCompression : 0) | 101 (internal::SmiValuesAre31Bits() ? k31BitSmis : 0) | 102 (internal::HeapSandboxIsEnabled() ? kHeapSandbox : 0) | 103 (internal::VirtualMemoryCageIsEnabled() ? kVirtualMemoryCage : 0); 104 return Initialize(kBuildConfiguration); 105 } 106 107 /** 108 * Allows the host application to provide a callback which can be used 109 * as a source of entropy for random number generators. 110 */ 111 static void SetEntropySource(EntropySource source); 112 113 /** 114 * Allows the host application to provide a callback that allows v8 to 115 * cooperate with a profiler that rewrites return addresses on stack. 116 */ 117 static void SetReturnAddressLocationResolver( 118 ReturnAddressLocationResolver return_address_resolver); 119 120 /** 121 * Releases any resources used by v8 and stops any utility threads 122 * that may be running. Note that disposing v8 is permanent, it 123 * cannot be reinitialized. 124 * 125 * It should generally not be necessary to dispose v8 before exiting 126 * a process, this should happen automatically. It is only necessary 127 * to use if the process needs the resources taken up by v8. 128 */ 129 static bool Dispose(); 130 131 /** 132 * Initialize the ICU library bundled with V8. The embedder should only 133 * invoke this method when using the bundled ICU. Returns true on success. 134 * 135 * If V8 was compiled with the ICU data in an external file, the location 136 * of the data file has to be provided. 137 */ 138 static bool InitializeICU(const char* icu_data_file = nullptr); 139 140 /** 141 * Initialize the ICU library bundled with V8. The embedder should only 142 * invoke this method when using the bundled ICU. If V8 was compiled with 143 * the ICU data in an external file and when the default location of that 144 * file should be used, a path to the executable must be provided. 145 * Returns true on success. 146 * 147 * The default is a file called icudtl.dat side-by-side with the executable. 148 * 149 * Optionally, the location of the data file can be provided to override the 150 * default. 151 */ 152 static bool InitializeICUDefaultLocation(const char* exec_path, 153 const char* icu_data_file = nullptr); 154 155 /** 156 * Initialize the external startup data. The embedder only needs to 157 * invoke this method when external startup data was enabled in a build. 158 * 159 * If V8 was compiled with the startup data in an external file, then 160 * V8 needs to be given those external files during startup. There are 161 * three ways to do this: 162 * - InitializeExternalStartupData(const char*) 163 * This will look in the given directory for the file "snapshot_blob.bin". 164 * - InitializeExternalStartupDataFromFile(const char*) 165 * As above, but will directly use the given file name. 166 * - Call SetSnapshotDataBlob. 167 * This will read the blobs from the given data structure and will 168 * not perform any file IO. 169 */ 170 static void InitializeExternalStartupData(const char* directory_path); 171 static void InitializeExternalStartupDataFromFile(const char* snapshot_blob); 172 173 /** 174 * Sets the v8::Platform to use. This should be invoked before V8 is 175 * initialized. 176 */ 177 static void InitializePlatform(Platform* platform); 178 179 /** 180 * Clears all references to the v8::Platform. This should be invoked after 181 * V8 was disposed. 182 */ 183 static void ShutdownPlatform(); 184 185 #ifdef V8_VIRTUAL_MEMORY_CAGE 186 // 187 // Virtual Memory Cage related API. 188 // 189 // This API is not yet stable and subject to changes in the future. 190 // 191 192 /** 193 * Initializes the virtual memory cage for V8. 194 * 195 * This must be invoked after the platform was initialized but before V8 is 196 * initialized. The virtual memory cage is torn down during platform shutdown. 197 * Returns true on success, false otherwise. 198 * 199 * TODO(saelo) Once it is no longer optional to create the virtual memory 200 * cage when compiling with V8_VIRTUAL_MEMORY_CAGE, the cage initialization 201 * will likely happen as part of V8::Initialize, at which point this function 202 * should be removed. 203 */ 204 static bool InitializeVirtualMemoryCage(); 205 206 /** 207 * Provides access to the virtual memory cage page allocator. 208 * 209 * This allocator allocates pages inside the virtual memory cage. It can for 210 * example be used to obtain virtual memory for ArrayBuffer backing stores, 211 * which must be located inside the cage. 212 * 213 * It should be assumed that an attacker can corrupt data inside the cage, 214 * and so in particular the contents of pages returned by this allocator, 215 * arbitrarily and concurrently. Due to this, it is recommended to to only 216 * place pure data buffers in pages obtained through this allocator. 217 * 218 * This function must only be called after initializing the virtual memory 219 * cage and V8. 220 */ 221 static PageAllocator* GetVirtualMemoryCagePageAllocator(); 222 223 /** 224 * Returns the size of the virtual memory cage in bytes. 225 * 226 * If the cage has not been initialized, or if the initialization failed, 227 * this returns zero. 228 */ 229 static size_t GetVirtualMemoryCageSizeInBytes(); 230 #endif 231 232 /** 233 * Activate trap-based bounds checking for WebAssembly. 234 * 235 * \param use_v8_signal_handler Whether V8 should install its own signal 236 * handler or rely on the embedder's. 237 */ 238 static bool EnableWebAssemblyTrapHandler(bool use_v8_signal_handler); 239 240 #if defined(V8_OS_WIN) 241 /** 242 * On Win64, by default V8 does not emit unwinding data for jitted code, 243 * which means the OS cannot walk the stack frames and the system Structured 244 * Exception Handling (SEH) cannot unwind through V8-generated code: 245 * https://code.google.com/p/v8/issues/detail?id=3598. 246 * 247 * This function allows embedders to register a custom exception handler for 248 * exceptions in V8-generated code. 249 */ 250 static void SetUnhandledExceptionCallback( 251 UnhandledExceptionCallback unhandled_exception_callback); 252 #endif 253 254 /** 255 * Get statistics about the shared memory usage. 256 */ 257 static void GetSharedMemoryStatistics(SharedMemoryStatistics* statistics); 258 259 private: 260 V8(); 261 262 enum BuildConfigurationFeatures { 263 kPointerCompression = 1 << 0, 264 k31BitSmis = 1 << 1, 265 kHeapSandbox = 1 << 2, 266 kVirtualMemoryCage = 1 << 3, 267 }; 268 269 /** 270 * Checks that the embedder build configuration is compatible with 271 * the V8 binary and if so initializes V8. 272 */ 273 static bool Initialize(int build_config); 274 275 friend class Context; 276 template <class K, class V, class T> 277 friend class PersistentValueMapBase; 278 }; 279 280 } // namespace v8 281 282 #endif // INCLUDE_V8_INITIALIZATION_H_ 283