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