1 // Copyright 2016 the V8 project authors. All rights reserved. Use of 2 // this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_WASM_WASM_OBJECTS_H_ 6 #define V8_WASM_WASM_OBJECTS_H_ 7 8 #include "src/base/bits.h" 9 #include "src/debug/debug.h" 10 #include "src/debug/interface-types.h" 11 #include "src/heap/heap.h" 12 #include "src/objects.h" 13 #include "src/objects/script.h" 14 #include "src/signature.h" 15 #include "src/wasm/value-type.h" 16 17 // Has to be the last include (doesn't have include guards) 18 #include "src/objects/object-macros.h" 19 20 namespace v8 { 21 namespace internal { 22 namespace wasm { 23 class InterpretedFrame; 24 struct InterpretedFrameDeleter; 25 class NativeModule; 26 struct ModuleEnv; 27 class WasmCode; 28 struct WasmModule; 29 class SignatureMap; 30 class WireBytesRef; 31 class WasmInterpreter; 32 using FunctionSig = Signature<ValueType>; 33 struct WasmFeatures; 34 } // namespace wasm 35 36 class BreakPoint; 37 class JSArrayBuffer; 38 class SeqOneByteString; 39 class WasmDebugInfo; 40 class WasmInstanceObject; 41 42 template <class CppType> 43 class Managed; 44 45 #define DECL_OPTIONAL_ACCESSORS(name, type) \ 46 V8_INLINE bool has_##name(); \ 47 DECL_ACCESSORS(name, type) 48 49 // An entry in an indirect function table (IFT). 50 // Each entry in the IFT has the following fields: 51 // - instance = target instance 52 // - sig_id = signature id of function 53 // - target = entrypoint to wasm code for the function, or wasm-to-js wrapper 54 class IndirectFunctionTableEntry { 55 public: 56 inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int index); 57 58 void clear(); 59 void set(int sig_id, WasmInstanceObject* instance, Address call_target); 60 61 WasmInstanceObject* instance(); 62 int sig_id(); 63 Address target(); 64 65 private: 66 Handle<WasmInstanceObject> const instance_; 67 int const index_; 68 }; 69 70 // An entry for an imported function. 71 // (note this is not called a "table" since it is not dynamically indexed). 72 // The imported function entries are used to call imported functions. 73 // For each imported function there is an entry which is either: 74 // - an imported JSReceiver, which has fields 75 // - instance = importing instance 76 // - receiver = JSReceiver, either a JS function or other callable 77 // - target = pointer to wasm-to-js wrapper code entrypoint 78 // - an imported wasm function from another instance, which has fields 79 // - instance = target instance 80 // - target = entrypoint for the function 81 class ImportedFunctionEntry { 82 public: 83 inline ImportedFunctionEntry(Handle<WasmInstanceObject>, int index); 84 85 // Initialize this entry as a {JSReceiver} call. 86 void set_wasm_to_js(JSReceiver* callable, 87 const wasm::WasmCode* wasm_to_js_wrapper); 88 // Initialize this entry as a WASM to WASM call. 89 void set_wasm_to_wasm(WasmInstanceObject* target_instance, 90 Address call_target); 91 92 WasmInstanceObject* instance(); 93 JSReceiver* callable(); 94 Address target(); 95 bool is_js_receiver_entry(); 96 97 private: 98 Handle<WasmInstanceObject> const instance_; 99 int const index_; 100 }; 101 102 // Representation of a WebAssembly.Module JavaScript-level object. 103 class WasmModuleObject : public JSObject { 104 public: 105 DECL_CAST(WasmModuleObject) 106 107 DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>) 108 DECL_ACCESSORS(export_wrappers, FixedArray) 109 DECL_ACCESSORS(script, Script) 110 DECL_ACCESSORS(weak_instance_list, WeakArrayList) 111 DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray) 112 DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray) 113 inline wasm::NativeModule* native_module() const; 114 inline const wasm::WasmModule* module() const; 115 inline void reset_breakpoint_infos(); 116 117 // Dispatched behavior. 118 DECL_PRINTER(WasmModuleObject) 119 DECL_VERIFIER(WasmModuleObject) 120 121 // Layout description. 122 #define WASM_MODULE_OBJECT_FIELDS(V) \ 123 V(kNativeModuleOffset, kPointerSize) \ 124 V(kExportWrappersOffset, kPointerSize) \ 125 V(kScriptOffset, kPointerSize) \ 126 V(kWeakInstanceListOffset, kPointerSize) \ 127 V(kAsmJsOffsetTableOffset, kPointerSize) \ 128 V(kBreakPointInfosOffset, kPointerSize) \ 129 V(kSize, 0) 130 131 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 132 WASM_MODULE_OBJECT_FIELDS) 133 #undef WASM_MODULE_OBJECT_FIELDS 134 135 // Creates a new {WasmModuleObject} with a new {NativeModule} underneath. 136 static Handle<WasmModuleObject> New( 137 Isolate* isolate, const wasm::WasmFeatures& enabled, 138 std::shared_ptr<const wasm::WasmModule> module, wasm::ModuleEnv& env, 139 OwnedVector<const uint8_t> wire_bytes, Handle<Script> script, 140 Handle<ByteArray> asm_js_offset_table); 141 142 // Creates a new {WasmModuleObject} for an existing {NativeModule} that is 143 // reference counted and might be shared between multiple Isolates. 144 static Handle<WasmModuleObject> New( 145 Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module, 146 Handle<Script> script); 147 148 // Set a breakpoint on the given byte position inside the given module. 149 // This will affect all live and future instances of the module. 150 // The passed position might be modified to point to the next breakable 151 // location inside the same function. 152 // If it points outside a function, or behind the last breakable location, 153 // this function returns false and does not set any breakpoint. 154 static bool SetBreakPoint(Handle<WasmModuleObject>, int* position, 155 Handle<BreakPoint> break_point); 156 157 // Check whether this module was generated from asm.js source. 158 inline bool is_asm_js(); 159 160 static void AddBreakpoint(Handle<WasmModuleObject>, int position, 161 Handle<BreakPoint> break_point); 162 163 static void SetBreakpointsOnNewInstance(Handle<WasmModuleObject>, 164 Handle<WasmInstanceObject>); 165 166 // Get the module name, if set. Returns an empty handle otherwise. 167 static MaybeHandle<String> GetModuleNameOrNull(Isolate*, 168 Handle<WasmModuleObject>); 169 170 // Get the function name of the function identified by the given index. 171 // Returns a null handle if the function is unnamed or the name is not a valid 172 // UTF-8 string. 173 static MaybeHandle<String> GetFunctionNameOrNull(Isolate*, 174 Handle<WasmModuleObject>, 175 uint32_t func_index); 176 177 // Get the function name of the function identified by the given index. 178 // Returns "wasm-function[func_index]" if the function is unnamed or the 179 // name is not a valid UTF-8 string. 180 static Handle<String> GetFunctionName(Isolate*, Handle<WasmModuleObject>, 181 uint32_t func_index); 182 183 // Get the raw bytes of the function name of the function identified by the 184 // given index. 185 // Meant to be used for debugging or frame printing. 186 // Does not allocate, hence gc-safe. 187 Vector<const uint8_t> GetRawFunctionName(uint32_t func_index); 188 189 // Return the byte offset of the function identified by the given index. 190 // The offset will be relative to the start of the module bytes. 191 // Returns -1 if the function index is invalid. 192 int GetFunctionOffset(uint32_t func_index); 193 194 // Returns the function containing the given byte offset. 195 // Returns -1 if the byte offset is not contained in any function of this 196 // module. 197 int GetContainingFunction(uint32_t byte_offset); 198 199 // Translate from byte offset in the module to function number and byte offset 200 // within that function, encoded as line and column in the position info. 201 // Returns true if the position is valid inside this module, false otherwise. 202 bool GetPositionInfo(uint32_t position, Script::PositionInfo* info); 203 204 // Get the source position from a given function index and byte offset, 205 // for either asm.js or pure WASM modules. 206 static int GetSourcePosition(Handle<WasmModuleObject>, uint32_t func_index, 207 uint32_t byte_offset, 208 bool is_at_number_conversion); 209 210 // Compute the disassembly of a wasm function. 211 // Returns the disassembly string and a list of <byte_offset, line, column> 212 // entries, mapping wasm byte offsets to line and column in the disassembly. 213 // The list is guaranteed to be ordered by the byte_offset. 214 // Returns an empty string and empty vector if the function index is invalid. 215 debug::WasmDisassembly DisassembleFunction(int func_index); 216 217 // Extract a portion of the wire bytes as UTF-8 string. 218 // Returns a null handle if the respective bytes do not form a valid UTF-8 219 // string. 220 static MaybeHandle<String> ExtractUtf8StringFromModuleBytes( 221 Isolate* isolate, Handle<WasmModuleObject>, wasm::WireBytesRef ref); 222 static MaybeHandle<String> ExtractUtf8StringFromModuleBytes( 223 Isolate* isolate, Vector<const uint8_t> wire_byte, 224 wasm::WireBytesRef ref); 225 226 // Get a list of all possible breakpoints within a given range of this module. 227 bool GetPossibleBreakpoints(const debug::Location& start, 228 const debug::Location& end, 229 std::vector<debug::BreakLocation>* locations); 230 231 // Return an empty handle if no breakpoint is hit at that location, or a 232 // FixedArray with all hit breakpoint objects. 233 static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, 234 Handle<WasmModuleObject>, 235 int position); 236 }; 237 238 // Representation of a WebAssembly.Table JavaScript-level object. 239 class WasmTableObject : public JSObject { 240 public: 241 DECL_CAST(WasmTableObject) 242 243 DECL_ACCESSORS(functions, FixedArray) 244 // TODO(titzer): introduce DECL_I64_ACCESSORS macro 245 DECL_ACCESSORS(maximum_length, Object) 246 DECL_ACCESSORS(dispatch_tables, FixedArray) 247 248 // Layout description. 249 #define WASM_TABLE_OBJECT_FIELDS(V) \ 250 V(kFunctionsOffset, kPointerSize) \ 251 V(kMaximumLengthOffset, kPointerSize) \ 252 V(kDispatchTablesOffset, kPointerSize) \ 253 V(kSize, 0) 254 255 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, WASM_TABLE_OBJECT_FIELDS) 256 #undef WASM_TABLE_OBJECT_FIELDS 257 258 inline uint32_t current_length(); 259 void Grow(Isolate* isolate, uint32_t count); 260 261 static Handle<WasmTableObject> New(Isolate* isolate, uint32_t initial, 262 int64_t maximum, 263 Handle<FixedArray>* js_functions); 264 static void AddDispatchTable(Isolate* isolate, Handle<WasmTableObject> table, 265 Handle<WasmInstanceObject> instance, 266 int table_index); 267 268 static void Set(Isolate* isolate, Handle<WasmTableObject> table, 269 int32_t index, Handle<JSFunction> function); 270 271 static void UpdateDispatchTables(Isolate* isolate, 272 Handle<WasmTableObject> table, 273 int table_index, wasm::FunctionSig* sig, 274 Handle<WasmInstanceObject> from_instance, 275 Address call_target); 276 277 static void ClearDispatchTables(Isolate* isolate, 278 Handle<WasmTableObject> table, int index); 279 }; 280 281 // Representation of a WebAssembly.Memory JavaScript-level object. 282 class WasmMemoryObject : public JSObject { 283 public: 284 DECL_CAST(WasmMemoryObject) 285 286 DECL_ACCESSORS(array_buffer, JSArrayBuffer) 287 DECL_INT_ACCESSORS(maximum_pages) 288 DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList) 289 290 // Layout description. 291 #define WASM_MEMORY_OBJECT_FIELDS(V) \ 292 V(kArrayBufferOffset, kPointerSize) \ 293 V(kMaximumPagesOffset, kPointerSize) \ 294 V(kInstancesOffset, kPointerSize) \ 295 V(kSize, 0) 296 297 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 298 WASM_MEMORY_OBJECT_FIELDS) 299 #undef WASM_MEMORY_OBJECT_FIELDS 300 301 // Add an instance to the internal (weak) list. 302 static void AddInstance(Isolate* isolate, Handle<WasmMemoryObject> memory, 303 Handle<WasmInstanceObject> object); 304 // Remove an instance from the internal (weak) list. 305 static void RemoveInstance(Handle<WasmMemoryObject> memory, 306 Handle<WasmInstanceObject> object); 307 uint32_t current_pages(); 308 inline bool has_maximum_pages(); 309 310 // Return whether the underlying backing store has guard regions large enough 311 // to be used with trap handlers. 312 bool has_full_guard_region(Isolate* isolate); 313 314 V8_EXPORT_PRIVATE static Handle<WasmMemoryObject> New( 315 Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, int32_t maximum); 316 317 static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, uint32_t pages); 318 }; 319 320 // Representation of a WebAssembly.Global JavaScript-level object. 321 class WasmGlobalObject : public JSObject { 322 public: 323 DECL_CAST(WasmGlobalObject) 324 325 DECL_ACCESSORS(array_buffer, JSArrayBuffer) 326 DECL_INT32_ACCESSORS(offset) 327 DECL_INT_ACCESSORS(flags) 328 DECL_PRIMITIVE_ACCESSORS(type, wasm::ValueType) 329 DECL_BOOLEAN_ACCESSORS(is_mutable) 330 331 #define WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS(V, _) \ 332 V(TypeBits, wasm::ValueType, 8, _) \ 333 V(IsMutableBit, bool, 1, _) 334 335 DEFINE_BIT_FIELDS(WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS) 336 337 #undef WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS 338 339 // Layout description. 340 #define WASM_GLOBAL_OBJECT_FIELDS(V) \ 341 V(kArrayBufferOffset, kPointerSize) \ 342 V(kOffsetOffset, kPointerSize) \ 343 V(kFlagsOffset, kPointerSize) \ 344 V(kSize, 0) 345 346 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 347 WASM_GLOBAL_OBJECT_FIELDS) 348 #undef WASM_GLOBAL_OBJECT_FIELDS 349 350 V8_EXPORT_PRIVATE static MaybeHandle<WasmGlobalObject> New( 351 Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, wasm::ValueType type, 352 int32_t offset, bool is_mutable); 353 354 inline int type_size() const; 355 356 inline int32_t GetI32(); 357 inline int64_t GetI64(); 358 inline float GetF32(); 359 inline double GetF64(); 360 361 inline void SetI32(int32_t value); 362 inline void SetI64(int64_t value); 363 inline void SetF32(float value); 364 inline void SetF64(double value); 365 366 private: 367 // This function returns the address of the global's data in the 368 // JSArrayBuffer. This buffer may be allocated on-heap, in which case it may 369 // not have a fixed address. 370 inline Address address() const; 371 }; 372 373 // Representation of a WebAssembly.Instance JavaScript-level object. 374 class WasmInstanceObject : public JSObject { 375 public: 376 DECL_CAST(WasmInstanceObject) 377 378 DECL_ACCESSORS(module_object, WasmModuleObject) 379 DECL_ACCESSORS(exports_object, JSObject) 380 DECL_ACCESSORS(native_context, Context) 381 DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject) 382 DECL_OPTIONAL_ACCESSORS(globals_buffer, JSArrayBuffer) 383 DECL_OPTIONAL_ACCESSORS(imported_mutable_globals_buffers, FixedArray) 384 DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo) 385 DECL_OPTIONAL_ACCESSORS(table_object, WasmTableObject) 386 DECL_ACCESSORS(imported_function_instances, FixedArray) 387 DECL_ACCESSORS(imported_function_callables, FixedArray) 388 DECL_OPTIONAL_ACCESSORS(indirect_function_table_instances, FixedArray) 389 DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign) 390 DECL_ACCESSORS(undefined_value, Oddball) 391 DECL_ACCESSORS(null_value, Oddball) 392 DECL_ACCESSORS(centry_stub, Code) 393 DECL_PRIMITIVE_ACCESSORS(memory_start, byte*) 394 DECL_PRIMITIVE_ACCESSORS(memory_size, size_t) 395 DECL_PRIMITIVE_ACCESSORS(memory_mask, size_t) 396 DECL_PRIMITIVE_ACCESSORS(roots_array_address, Address) 397 DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address) 398 DECL_PRIMITIVE_ACCESSORS(real_stack_limit_address, Address) 399 DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*) 400 DECL_PRIMITIVE_ACCESSORS(globals_start, byte*) 401 DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*) 402 DECL_PRIMITIVE_ACCESSORS(indirect_function_table_size, uint32_t) 403 DECL_PRIMITIVE_ACCESSORS(indirect_function_table_sig_ids, uint32_t*) 404 DECL_PRIMITIVE_ACCESSORS(indirect_function_table_targets, Address*) 405 DECL_PRIMITIVE_ACCESSORS(jump_table_start, Address) 406 407 // Dispatched behavior. 408 DECL_PRINTER(WasmInstanceObject) 409 DECL_VERIFIER(WasmInstanceObject) 410 411 // Layout description. 412 #define WASM_INSTANCE_OBJECT_FIELDS(V) \ 413 V(kModuleObjectOffset, kPointerSize) \ 414 V(kExportsObjectOffset, kPointerSize) \ 415 V(kNativeContextOffset, kPointerSize) \ 416 V(kMemoryObjectOffset, kPointerSize) \ 417 V(kGlobalsBufferOffset, kPointerSize) \ 418 V(kImportedMutableGlobalsBuffersOffset, kPointerSize) \ 419 V(kDebugInfoOffset, kPointerSize) \ 420 V(kTableObjectOffset, kPointerSize) \ 421 V(kImportedFunctionInstancesOffset, kPointerSize) \ 422 V(kImportedFunctionCallablesOffset, kPointerSize) \ 423 V(kIndirectFunctionTableInstancesOffset, kPointerSize) \ 424 V(kManagedNativeAllocationsOffset, kPointerSize) \ 425 V(kUndefinedValueOffset, kPointerSize) \ 426 V(kNullValueOffset, kPointerSize) \ 427 V(kCEntryStubOffset, kPointerSize) \ 428 V(kFirstUntaggedOffset, 0) /* marker */ \ 429 V(kMemoryStartOffset, kPointerSize) /* untagged */ \ 430 V(kMemorySizeOffset, kSizetSize) /* untagged */ \ 431 V(kMemoryMaskOffset, kSizetSize) /* untagged */ \ 432 V(kRootsArrayAddressOffset, kPointerSize) /* untagged */ \ 433 V(kStackLimitAddressOffset, kPointerSize) /* untagged */ \ 434 V(kRealStackLimitAddressOffset, kPointerSize) /* untagged */ \ 435 V(kImportedFunctionTargetsOffset, kPointerSize) /* untagged */ \ 436 V(kGlobalsStartOffset, kPointerSize) /* untagged */ \ 437 V(kImportedMutableGlobalsOffset, kPointerSize) /* untagged */ \ 438 V(kIndirectFunctionTableSigIdsOffset, kPointerSize) /* untagged */ \ 439 V(kIndirectFunctionTableTargetsOffset, kPointerSize) /* untagged */ \ 440 V(kJumpTableStartOffset, kPointerSize) /* untagged */ \ 441 V(kIndirectFunctionTableSizeOffset, kUInt32Size) /* untagged */ \ 442 V(k64BitArchPaddingOffset, kPointerSize - kUInt32Size) /* padding */ \ 443 V(kSize, 0) 444 445 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 446 WASM_INSTANCE_OBJECT_FIELDS) 447 #undef WASM_INSTANCE_OBJECT_FIELDS 448 449 V8_EXPORT_PRIVATE const wasm::WasmModule* module(); 450 451 static bool EnsureIndirectFunctionTableWithMinimumSize( 452 Handle<WasmInstanceObject> instance, uint32_t minimum_size); 453 454 bool has_indirect_function_table(); 455 456 void SetRawMemory(byte* mem_start, size_t mem_size); 457 458 // Get the debug info associated with the given wasm object. 459 // If no debug info exists yet, it is created automatically. 460 static Handle<WasmDebugInfo> GetOrCreateDebugInfo(Handle<WasmInstanceObject>); 461 462 static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmModuleObject>); 463 464 static void InstallFinalizer(Isolate* isolate, 465 Handle<WasmInstanceObject> instance); 466 467 Address GetCallTarget(uint32_t func_index); 468 469 // Iterates all fields in the object except the untagged fields. 470 class BodyDescriptor; 471 // No weak fields. 472 typedef BodyDescriptor BodyDescriptorWeak; 473 }; 474 475 // A WASM function that is wrapped and exported to JavaScript. 476 class WasmExportedFunction : public JSFunction { 477 public: 478 WasmInstanceObject* instance(); 479 V8_EXPORT_PRIVATE int function_index(); 480 481 V8_EXPORT_PRIVATE static WasmExportedFunction* cast(Object* object); 482 static bool IsWasmExportedFunction(Object* object); 483 484 static Handle<WasmExportedFunction> New(Isolate* isolate, 485 Handle<WasmInstanceObject> instance, 486 MaybeHandle<String> maybe_name, 487 int func_index, int arity, 488 Handle<Code> export_wrapper); 489 490 Address GetWasmCallTarget(); 491 }; 492 493 // Information for a WasmExportedFunction which is referenced as the function 494 // data of the SharedFunctionInfo underlying the function. For details please 495 // see the {SharedFunctionInfo::HasWasmExportedFunctionData} predicate. 496 class WasmExportedFunctionData : public Struct { 497 public: 498 DECL_ACCESSORS(wrapper_code, Code); 499 DECL_ACCESSORS(instance, WasmInstanceObject) 500 DECL_INT_ACCESSORS(jump_table_offset); 501 DECL_INT_ACCESSORS(function_index); 502 503 DECL_CAST(WasmExportedFunctionData) 504 505 // Dispatched behavior. 506 DECL_PRINTER(WasmExportedFunctionData) 507 DECL_VERIFIER(WasmExportedFunctionData) 508 509 // Layout description. 510 #define WASM_EXPORTED_FUNCTION_DATA_FIELDS(V) \ 511 V(kWrapperCodeOffset, kPointerSize) \ 512 V(kInstanceOffset, kPointerSize) \ 513 V(kJumpTableOffsetOffset, kPointerSize) /* Smi */ \ 514 V(kFunctionIndexOffset, kPointerSize) /* Smi */ \ 515 V(kSize, 0) 516 517 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, 518 WASM_EXPORTED_FUNCTION_DATA_FIELDS) 519 #undef WASM_EXPORTED_FUNCTION_DATA_FIELDS 520 }; 521 522 class WasmDebugInfo : public Struct, public NeverReadOnlySpaceObject { 523 public: 524 using NeverReadOnlySpaceObject::GetHeap; 525 using NeverReadOnlySpaceObject::GetIsolate; 526 527 DECL_ACCESSORS(wasm_instance, WasmInstanceObject) 528 DECL_ACCESSORS(interpreter_handle, Object); 529 DECL_ACCESSORS(interpreted_functions, Object); 530 DECL_OPTIONAL_ACCESSORS(locals_names, FixedArray) 531 DECL_OPTIONAL_ACCESSORS(c_wasm_entries, FixedArray) 532 DECL_OPTIONAL_ACCESSORS(c_wasm_entry_map, Managed<wasm::SignatureMap>) 533 534 DECL_CAST(WasmDebugInfo) 535 536 // Dispatched behavior. 537 DECL_PRINTER(WasmDebugInfo) 538 DECL_VERIFIER(WasmDebugInfo) 539 540 // Layout description. 541 #define WASM_DEBUG_INFO_FIELDS(V) \ 542 V(kInstanceOffset, kPointerSize) \ 543 V(kInterpreterHandleOffset, kPointerSize) \ 544 V(kInterpretedFunctionsOffset, kPointerSize) \ 545 V(kLocalsNamesOffset, kPointerSize) \ 546 V(kCWasmEntriesOffset, kPointerSize) \ 547 V(kCWasmEntryMapOffset, kPointerSize) \ 548 V(kSize, 0) 549 550 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WASM_DEBUG_INFO_FIELDS) 551 #undef WASM_DEBUG_INFO_FIELDS 552 553 static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>); 554 555 // Setup a WasmDebugInfo with an existing WasmInstance struct. 556 // Returns a pointer to the interpreter instantiated inside this 557 // WasmDebugInfo. 558 // Use for testing only. 559 V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting( 560 Handle<WasmInstanceObject>); 561 562 // Set a breakpoint in the given function at the given byte offset within that 563 // function. This will redirect all future calls to this function to the 564 // interpreter and will always pause at the given offset. 565 static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset); 566 567 // Make a set of functions always execute in the interpreter without setting 568 // breakpoints. 569 static void RedirectToInterpreter(Handle<WasmDebugInfo>, 570 Vector<int> func_indexes); 571 572 void PrepareStep(StepAction); 573 574 // Execute the specified function in the interpreter. Read arguments from 575 // arg_buffer. 576 // The frame_pointer will be used to identify the new activation of the 577 // interpreter for unwinding and frame inspection. 578 // Returns true if exited regularly, false if a trap occurred. In the latter 579 // case, a pending exception will have been set on the isolate. 580 static bool RunInterpreter(Isolate* isolate, Handle<WasmDebugInfo>, 581 Address frame_pointer, int func_index, 582 Address arg_buffer); 583 584 // Get the stack of the wasm interpreter as pairs of <function index, byte 585 // offset>. The list is ordered bottom-to-top, i.e. caller before callee. 586 std::vector<std::pair<uint32_t, int>> GetInterpretedStack( 587 Address frame_pointer); 588 589 std::unique_ptr<wasm::InterpretedFrame, wasm::InterpretedFrameDeleter> 590 GetInterpretedFrame(Address frame_pointer, int frame_index); 591 592 // Unwind the interpreted stack belonging to the passed interpreter entry 593 // frame. 594 void Unwind(Address frame_pointer); 595 596 // Returns the number of calls / function frames executed in the interpreter. 597 uint64_t NumInterpretedCalls(); 598 599 // Get scope details for a specific interpreted frame. 600 // This returns a JSArray of length two: One entry for the global scope, one 601 // for the local scope. Both elements are JSArrays of size 602 // ScopeIterator::kScopeDetailsSize and layout as described in debug-scopes.h. 603 // The global scope contains information about globals and the memory. 604 // The local scope contains information about parameters, locals, and stack 605 // values. 606 static Handle<JSObject> GetScopeDetails(Handle<WasmDebugInfo>, 607 Address frame_pointer, 608 int frame_index); 609 static Handle<JSObject> GetGlobalScopeObject(Handle<WasmDebugInfo>, 610 Address frame_pointer, 611 int frame_index); 612 static Handle<JSObject> GetLocalScopeObject(Handle<WasmDebugInfo>, 613 Address frame_pointer, 614 int frame_index); 615 616 static Handle<JSFunction> GetCWasmEntry(Handle<WasmDebugInfo>, 617 wasm::FunctionSig*); 618 }; 619 620 #undef DECL_OPTIONAL_ACCESSORS 621 622 } // namespace internal 623 } // namespace v8 624 625 #include "src/objects/object-macros-undef.h" 626 627 #endif // V8_WASM_WASM_OBJECTS_H_ 628