Initialization.h (7908B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* SpiderMonkey initialization and shutdown APIs. */ 7 8 #ifndef js_Initialization_h 9 #define js_Initialization_h 10 11 #include "mozilla/Span.h" 12 13 #include "jstypes.h" 14 15 struct JS_PUBLIC_API JSContext; 16 17 namespace JS { 18 namespace detail { 19 20 enum class InitState { Uninitialized = 0, Initializing, Running, ShutDown }; 21 22 /** 23 * SpiderMonkey's initialization status is tracked here, and it controls things 24 * that should happen only once across all runtimes. It's an API requirement 25 * that JS_Init (and JS_ShutDown, if called) be called in a thread-aware 26 * manner, so this (internal -- embedders, don't use!) variable doesn't need to 27 * be atomic. 28 */ 29 extern JS_PUBLIC_DATA InitState libraryInitState; 30 31 enum class FrontendOnly { No, Yes }; 32 33 extern JS_PUBLIC_API const char* InitWithFailureDiagnostic( 34 bool isDebugBuild, FrontendOnly frontendOnly = FrontendOnly::No); 35 36 } // namespace detail 37 } // namespace JS 38 39 // These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and 40 // |UMemFreeFn| types. The first argument (called |context| in the ICU docs) 41 // will always be nullptr and should be ignored. 42 typedef void* (*JS_ICUAllocFn)(const void*, size_t size); 43 typedef void* (*JS_ICUReallocFn)(const void*, void* p, size_t size); 44 typedef void (*JS_ICUFreeFn)(const void*, void* p); 45 46 /** 47 * This function can be used to track memory used by ICU. If it is called, it 48 * *must* be called before JS_Init. Don't use it unless you know what you're 49 * doing! 50 */ 51 extern JS_PUBLIC_API bool JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, 52 JS_ICUReallocFn reallocFn, 53 JS_ICUFreeFn freeFn); 54 55 /** 56 * Initialize SpiderMonkey, returning true only if initialization succeeded. 57 * Once this method has succeeded, it is safe to call JS_NewContext and other 58 * JSAPI methods. 59 * 60 * This method must be called before any other JSAPI method is used on any 61 * thread. Once it has been used, it is safe to call any JSAPI method, and it 62 * remains safe to do so until JS_ShutDown is correctly called. 63 * 64 * It is currently not possible to initialize SpiderMonkey multiple times (that 65 * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so 66 * again). This restriction may eventually be lifted. 67 */ 68 inline bool JS_Init(void) { 69 #ifdef DEBUG 70 return !JS::detail::InitWithFailureDiagnostic(true); 71 #else 72 return !JS::detail::InitWithFailureDiagnostic(false); 73 #endif 74 } 75 76 /** 77 * A variant of JS_Init. On success it returns nullptr. On failure it returns a 78 * pointer to a string literal that describes how initialization failed, which 79 * can be useful for debugging purposes. 80 */ 81 inline const char* JS_InitWithFailureDiagnostic(void) { 82 #ifdef DEBUG 83 return JS::detail::InitWithFailureDiagnostic(true); 84 #else 85 return JS::detail::InitWithFailureDiagnostic(false); 86 #endif 87 } 88 89 /** 90 * A lightweight variant of JS_Init, which skips initializing runtime-specific 91 * part. 92 * Suitable for processes where only JSContext-free stencil-APIs are used. 93 */ 94 inline bool JS_FrontendOnlyInit(void) { 95 #ifdef DEBUG 96 return !JS::detail::InitWithFailureDiagnostic(true, 97 JS::detail::FrontendOnly::Yes); 98 #else 99 return !JS::detail::InitWithFailureDiagnostic(false, 100 JS::detail::FrontendOnly::Yes); 101 #endif 102 } 103 104 /* 105 * Returns true if SpiderMonkey has been initialized successfully, even if it 106 * has possibly been shut down. 107 * 108 * Note that it is the responsibility of the embedder to call JS_Init() and 109 * JS_ShutDown() at the correct times, and therefore this API should ideally not 110 * be necessary to use. This is only intended to be used in cases where the 111 * embedder isn't in full control of deciding whether to initialize SpiderMonkey 112 * or hand off the task to another consumer. 113 */ 114 inline bool JS_IsInitialized(void) { 115 return JS::detail::libraryInitState >= JS::detail::InitState::Running; 116 } 117 118 namespace JS { 119 120 // Reference to a sequence of bytes. 121 using SelfHostedCache = mozilla::Span<const uint8_t>; 122 123 // Callback function used to copy the SelfHosted content to memory or to disk. 124 using SelfHostedWriter = bool (*)(JSContext*, SelfHostedCache); 125 126 /* 127 * Initialize the runtime's self-hosted code. Embeddings should call this 128 * exactly once per runtime/context, before the first JS_NewGlobalObject 129 * call. 130 * 131 * This function parses the self-hosted code, except if the provided cache span 132 * is not empty, in which case the self-hosted content is decoded from the span. 133 * 134 * The cached content provided as argument, when non-empty, should come from the 135 * a previous execution of JS::InitSelfHostedCode where a writer was registered. 136 * The content should come from the same version of the binary, otherwise this 137 * would cause an error. 138 * 139 * The cached content provided with the Span should remain alive until 140 * JS_Shutdown is called. 141 * 142 * The writer callback given as argument would be called by when the result of 143 * the parser is ready to be cached. The writer is in charge of saving the 144 * content in memory or on disk. The span given as argument of the writer only 145 * last for the time of the call, and contains the content to be saved. 146 * 147 * The writer is not called if the cached content given as argument of 148 * InitSelfHostedCode is non-empty. 149 * 150 * Errors returned by the writer callback would bubble up through 151 * JS::InitSelfHostedCode. 152 * 153 * The cached content provided by the writer callback is safe to reuse across 154 * threads, and even across multiple executions as long as the executable is 155 * identical. 156 * 157 * NOTE: This may not set a pending exception in the case of OOM since this 158 * runs very early in startup. 159 */ 160 JS_PUBLIC_API bool InitSelfHostedCode(JSContext* cx, 161 SelfHostedCache cache = nullptr, 162 SelfHostedWriter writer = nullptr); 163 164 /* 165 * Permanently disable the JIT backend for this process. This disables the JS 166 * Baseline Interpreter, JIT compilers, regular expression JIT and support for 167 * WebAssembly. 168 * 169 * If called, this *must* be called before JS_Init. 170 */ 171 JS_PUBLIC_API void DisableJitBackend(); 172 173 } // namespace JS 174 175 /** 176 * Destroy free-standing resources allocated by SpiderMonkey, not associated 177 * with any runtime, context, or other structure. 178 * 179 * This method should be called after all other JSAPI data has been properly 180 * cleaned up: every new runtime must have been destroyed, every new context 181 * must have been destroyed, and so on. Calling this method before all other 182 * resources have been destroyed has undefined behavior. 183 * 184 * Failure to call this method, at present, has no adverse effects other than 185 * leaking memory. This may not always be the case; it's recommended that all 186 * embedders call this method when all other JSAPI operations have completed. 187 * 188 * It is currently not possible to initialize SpiderMonkey multiple times (that 189 * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so 190 * again). This restriction may eventually be lifted. 191 */ 192 extern JS_PUBLIC_API void JS_ShutDown(void); 193 194 /** 195 * A variant of JS_ShutDown for process which used JS_FrontendOnlyInit instead 196 * of JS_Init. 197 */ 198 extern JS_PUBLIC_API void JS_FrontendOnlyShutDown(void); 199 200 #if defined(ENABLE_WASM_SIMD) && \ 201 (defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)) 202 namespace JS { 203 // Enable support for AVX instructions in the JIT/Wasm backend on x86/x64 204 // platforms. Must be called before JS_Init*. 205 void SetAVXEnabled(bool enabled); 206 } // namespace JS 207 #endif 208 209 #endif /* js_Initialization_h */