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_ISOLATE_CALLBACKS_H_ 6 #define INCLUDE_V8_ISOLATE_CALLBACKS_H_ 7 8 #include <stddef.h> 9 10 #include <string> 11 12 #include "cppgc/common.h" 13 #include "v8-data.h" // NOLINT(build/include_directory) 14 #include "v8-local-handle.h" // NOLINT(build/include_directory) 15 #include "v8config.h" // NOLINT(build/include_directory) 16 17 #if defined(V8_OS_WIN) 18 struct _EXCEPTION_POINTERS; 19 #endif 20 21 namespace v8 { 22 23 template <typename T> 24 class FunctionCallbackInfo; 25 class Isolate; 26 class Message; 27 class Module; 28 class Object; 29 class Promise; 30 class ScriptOrModule; 31 class String; 32 class UnboundScript; 33 class Value; 34 35 /** 36 * A JIT code event is issued each time code is added, moved or removed. 37 * 38 * \note removal events are not currently issued. 39 */ 40 struct JitCodeEvent { 41 enum EventType { 42 CODE_ADDED, 43 CODE_MOVED, 44 CODE_REMOVED, 45 CODE_ADD_LINE_POS_INFO, 46 CODE_START_LINE_INFO_RECORDING, 47 CODE_END_LINE_INFO_RECORDING 48 }; 49 // Definition of the code position type. The "POSITION" type means the place 50 // in the source code which are of interest when making stack traces to 51 // pin-point the source location of a stack frame as close as possible. 52 // The "STATEMENT_POSITION" means the place at the beginning of each 53 // statement, and is used to indicate possible break locations. 54 enum PositionType { POSITION, STATEMENT_POSITION }; 55 56 // There are three different kinds of CodeType, one for JIT code generated 57 // by the optimizing compiler, one for byte code generated for the 58 // interpreter, and one for code generated from Wasm. For JIT_CODE and 59 // WASM_CODE, |code_start| points to the beginning of jitted assembly code, 60 // while for BYTE_CODE events, |code_start| points to the first bytecode of 61 // the interpreted function. 62 enum CodeType { BYTE_CODE, JIT_CODE, WASM_CODE }; 63 64 // Type of event. 65 EventType type; 66 CodeType code_type; 67 // Start of the instructions. 68 void* code_start; 69 // Size of the instructions. 70 size_t code_len; 71 // Script info for CODE_ADDED event. 72 Local<UnboundScript> script; 73 // User-defined data for *_LINE_INFO_* event. It's used to hold the source 74 // code line information which is returned from the 75 // CODE_START_LINE_INFO_RECORDING event. And it's passed to subsequent 76 // CODE_ADD_LINE_POS_INFO and CODE_END_LINE_INFO_RECORDING events. 77 void* user_data; 78 79 struct name_t { 80 // Name of the object associated with the code, note that the string is not 81 // zero-terminated. 82 const char* str; 83 // Number of chars in str. 84 size_t len; 85 }; 86 87 struct line_info_t { 88 // PC offset 89 size_t offset; 90 // Code position 91 size_t pos; 92 // The position type. 93 PositionType position_type; 94 }; 95 96 struct wasm_source_info_t { 97 // Source file name. 98 const char* filename; 99 // Length of filename. 100 size_t filename_size; 101 // Line number table, which maps offsets of JITted code to line numbers of 102 // source file. 103 const line_info_t* line_number_table; 104 // Number of entries in the line number table. 105 size_t line_number_table_size; 106 }; 107 108 wasm_source_info_t* wasm_source_info; 109 110 union { 111 // Only valid for CODE_ADDED. 112 struct name_t name; 113 114 // Only valid for CODE_ADD_LINE_POS_INFO 115 struct line_info_t line_info; 116 117 // New location of instructions. Only valid for CODE_MOVED. 118 void* new_code_start; 119 }; 120 121 Isolate* isolate; 122 }; 123 124 /** 125 * Option flags passed to the SetJitCodeEventHandler function. 126 */ 127 enum JitCodeEventOptions { 128 kJitCodeEventDefault = 0, 129 // Generate callbacks for already existent code. 130 kJitCodeEventEnumExisting = 1 131 }; 132 133 /** 134 * Callback function passed to SetJitCodeEventHandler. 135 * 136 * \param event code add, move or removal event. 137 */ 138 using JitCodeEventHandler = void (*)(const JitCodeEvent* event); 139 140 // --- Garbage Collection Callbacks --- 141 142 /** 143 * Applications can register callback functions which will be called before and 144 * after certain garbage collection operations. Allocations are not allowed in 145 * the callback functions, you therefore cannot manipulate objects (set or 146 * delete properties for example) since it is possible such operations will 147 * result in the allocation of objects. 148 */ 149 enum GCType { 150 kGCTypeScavenge = 1 << 0, 151 kGCTypeMinorMarkCompact = 1 << 1, 152 kGCTypeMarkSweepCompact = 1 << 2, 153 kGCTypeIncrementalMarking = 1 << 3, 154 kGCTypeProcessWeakCallbacks = 1 << 4, 155 kGCTypeAll = kGCTypeScavenge | kGCTypeMinorMarkCompact | 156 kGCTypeMarkSweepCompact | kGCTypeIncrementalMarking | 157 kGCTypeProcessWeakCallbacks 158 }; 159 160 /** 161 * GCCallbackFlags is used to notify additional information about the GC 162 * callback. 163 * - kGCCallbackFlagConstructRetainedObjectInfos: The GC callback is for 164 * constructing retained object infos. 165 * - kGCCallbackFlagForced: The GC callback is for a forced GC for testing. 166 * - kGCCallbackFlagSynchronousPhantomCallbackProcessing: The GC callback 167 * is called synchronously without getting posted to an idle task. 168 * - kGCCallbackFlagCollectAllAvailableGarbage: The GC callback is called 169 * in a phase where V8 is trying to collect all available garbage 170 * (e.g., handling a low memory notification). 171 * - kGCCallbackScheduleIdleGarbageCollection: The GC callback is called to 172 * trigger an idle garbage collection. 173 */ 174 enum GCCallbackFlags { 175 kNoGCCallbackFlags = 0, 176 kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1, 177 kGCCallbackFlagForced = 1 << 2, 178 kGCCallbackFlagSynchronousPhantomCallbackProcessing = 1 << 3, 179 kGCCallbackFlagCollectAllAvailableGarbage = 1 << 4, 180 kGCCallbackFlagCollectAllExternalMemory = 1 << 5, 181 kGCCallbackScheduleIdleGarbageCollection = 1 << 6, 182 }; 183 184 using GCCallback = void (*)(GCType type, GCCallbackFlags flags); 185 186 using InterruptCallback = void (*)(Isolate* isolate, void* data); 187 188 /** 189 * This callback is invoked when the heap size is close to the heap limit and 190 * V8 is likely to abort with out-of-memory error. 191 * The callback can extend the heap limit by returning a value that is greater 192 * than the current_heap_limit. The initial heap limit is the limit that was 193 * set after heap setup. 194 */ 195 using NearHeapLimitCallback = size_t (*)(void* data, size_t current_heap_limit, 196 size_t initial_heap_limit); 197 198 /** 199 * Callback function passed to SetUnhandledExceptionCallback. 200 */ 201 #if defined(V8_OS_WIN) 202 using UnhandledExceptionCallback = 203 int (*)(_EXCEPTION_POINTERS* exception_pointers); 204 #endif 205 206 // --- Counters Callbacks --- 207 208 using CounterLookupCallback = int* (*)(const char* name); 209 210 using CreateHistogramCallback = void* (*)(const char* name, int min, int max, 211 size_t buckets); 212 213 using AddHistogramSampleCallback = void (*)(void* histogram, int sample); 214 215 // --- Exceptions --- 216 217 using FatalErrorCallback = void (*)(const char* location, const char* message); 218 219 220 struct OOMDetails { 221 bool is_heap_oom = false; 222 const char* detail = nullptr; 223 }; 224 225 using OOMErrorCallback = void (*)(const char* location, bool is_heap_oom); 226 227 using MessageCallback = void (*)(Local<Message> message, Local<Value> data); 228 229 // --- Tracing --- 230 231 enum LogEventStatus : int { kStart = 0, kEnd = 1, kStamp = 2 }; 232 using LogEventCallback = void (*)(const char* name, 233 int /* LogEventStatus */ status); 234 235 // --- Crashkeys Callback --- 236 enum class CrashKeyId { 237 kIsolateAddress, 238 kReadonlySpaceFirstPageAddress, 239 kMapSpaceFirstPageAddress, 240 kCodeSpaceFirstPageAddress, 241 kDumpType, 242 }; 243 244 using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value); 245 246 // --- Enter/Leave Script Callback --- 247 using BeforeCallEnteredCallback = void (*)(Isolate*); 248 using CallCompletedCallback = void (*)(Isolate*); 249 250 // --- AllowCodeGenerationFromStrings callbacks --- 251 252 /** 253 * Callback to check if code generation from strings is allowed. See 254 * Context::AllowCodeGenerationFromStrings. 255 */ 256 using AllowCodeGenerationFromStringsCallback = bool (*)(Local<Context> context, 257 Local<String> source); 258 259 struct ModifyCodeGenerationFromStringsResult { 260 // If true, proceed with the codegen algorithm. Otherwise, block it. 261 bool codegen_allowed = false; 262 // Overwrite the original source with this string, if present. 263 // Use the original source if empty. 264 // This field is considered only if codegen_allowed is true. 265 MaybeLocal<String> modified_source; 266 }; 267 268 /** 269 * Access type specification. 270 */ 271 enum AccessType { 272 ACCESS_GET, 273 ACCESS_SET, 274 ACCESS_HAS, 275 ACCESS_DELETE, 276 ACCESS_KEYS 277 }; 278 279 // --- Failed Access Check Callback --- 280 281 using FailedAccessCheckCallback = void (*)(Local<Object> target, 282 AccessType type, Local<Value> data); 283 284 /** 285 * Callback to check if codegen is allowed from a source object, and convert 286 * the source to string if necessary. See: ModifyCodeGenerationFromStrings. 287 */ 288 using ModifyCodeGenerationFromStringsCallback = 289 ModifyCodeGenerationFromStringsResult (*)(Local<Context> context, 290 Local<Value> source); 291 using ModifyCodeGenerationFromStringsCallback2 = 292 ModifyCodeGenerationFromStringsResult (*)(Local<Context> context, 293 Local<Value> source, 294 bool is_code_like); 295 296 // --- WebAssembly compilation callbacks --- 297 using ExtensionCallback = bool (*)(const FunctionCallbackInfo<Value>&); 298 299 using AllowWasmCodeGenerationCallback = bool (*)(Local<Context> context, 300 Local<String> source); 301 302 // --- Callback for APIs defined on v8-supported objects, but implemented 303 // by the embedder. Example: WebAssembly.{compile|instantiate}Streaming --- 304 using ApiImplementationCallback = void (*)(const FunctionCallbackInfo<Value>&); 305 306 // --- Callback for WebAssembly.compileStreaming --- 307 using WasmStreamingCallback = void (*)(const FunctionCallbackInfo<Value>&); 308 309 // --- Callback for loading source map file for Wasm profiling support 310 using WasmLoadSourceMapCallback = Local<String> (*)(Isolate* isolate, 311 const char* name); 312 313 // --- Callback for checking if WebAssembly Simd is enabled --- 314 using WasmSimdEnabledCallback = bool (*)(Local<Context> context); 315 316 // --- Callback for checking if WebAssembly exceptions are enabled --- 317 using WasmExceptionsEnabledCallback = bool (*)(Local<Context> context); 318 319 // --- Callback for checking if WebAssembly dynamic tiering is enabled --- 320 using WasmDynamicTieringEnabledCallback = bool (*)(Local<Context> context); 321 322 // --- Callback for checking if the SharedArrayBuffer constructor is enabled --- 323 using SharedArrayBufferConstructorEnabledCallback = 324 bool (*)(Local<Context> context); 325 326 /** 327 * HostImportModuleDynamicallyCallback is called when we 328 * require the embedder to load a module. This is used as part of the dynamic 329 * import syntax. 330 * 331 * The referrer contains metadata about the script/module that calls 332 * import. 333 * 334 * The specifier is the name of the module that should be imported. 335 * 336 * The import_assertions are import assertions for this request in the form: 337 * [key1, value1, key2, value2, ...] where the keys and values are of type 338 * v8::String. Note, unlike the FixedArray passed to ResolveModuleCallback and 339 * returned from ModuleRequest::GetImportAssertions(), this array does not 340 * contain the source Locations of the assertions. 341 * 342 * The embedder must compile, instantiate, evaluate the Module, and 343 * obtain its namespace object. 344 * 345 * The Promise returned from this function is forwarded to userland 346 * JavaScript. The embedder must resolve this promise with the module 347 * namespace object. In case of an exception, the embedder must reject 348 * this promise with the exception. If the promise creation itself 349 * fails (e.g. due to stack overflow), the embedder must propagate 350 * that exception by returning an empty MaybeLocal. 351 */ 352 using HostImportModuleDynamicallyWithImportAssertionsCallback = 353 MaybeLocal<Promise> (*)(Local<Context> context, 354 Local<ScriptOrModule> referrer, 355 Local<String> specifier, 356 Local<FixedArray> import_assertions); 357 using HostImportModuleDynamicallyCallback = MaybeLocal<Promise> (*)( 358 Local<Context> context, Local<Data> host_defined_options, 359 Local<Value> resource_name, Local<String> specifier, 360 Local<FixedArray> import_assertions); 361 362 /** 363 * HostInitializeImportMetaObjectCallback is called the first time import.meta 364 * is accessed for a module. Subsequent access will reuse the same value. 365 * 366 * The method combines two implementation-defined abstract operations into one: 367 * HostGetImportMetaProperties and HostFinalizeImportMeta. 368 * 369 * The embedder should use v8::Object::CreateDataProperty to add properties on 370 * the meta object. 371 */ 372 using HostInitializeImportMetaObjectCallback = void (*)(Local<Context> context, 373 Local<Module> module, 374 Local<Object> meta); 375 376 /** 377 * HostCreateShadowRealmContextCallback is called each time a ShadowRealm is 378 * being constructed in the initiator_context. 379 * 380 * The method combines Context creation and implementation defined abstract 381 * operation HostInitializeShadowRealm into one. 382 * 383 * The embedder should use v8::Context::New or v8::Context:NewFromSnapshot to 384 * create a new context. If the creation fails, the embedder must propagate 385 * that exception by returning an empty MaybeLocal. 386 */ 387 using HostCreateShadowRealmContextCallback = 388 MaybeLocal<Context> (*)(Local<Context> initiator_context); 389 390 /** 391 * PrepareStackTraceCallback is called when the stack property of an error is 392 * first accessed. The return value will be used as the stack value. If this 393 * callback is registed, the |Error.prepareStackTrace| API will be disabled. 394 * |sites| is an array of call sites, specified in 395 * https://v8.dev/docs/stack-trace-api 396 */ 397 using PrepareStackTraceCallback = MaybeLocal<Value> (*)(Local<Context> context, 398 Local<Value> error, 399 Local<Array> sites); 400 401 } // namespace v8 402 403 #endif // INCLUDE_V8_ISOLATE_CALLBACKS_H_ 404