Line data Source code
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 : struct CompilationEnv;
24 : class InterpretedFrame;
25 : struct InterpretedFrameDeleter;
26 : class NativeModule;
27 : class SignatureMap;
28 : class WasmCode;
29 : struct WasmException;
30 : struct WasmFeatures;
31 : class WasmInterpreter;
32 : struct WasmModule;
33 : class WireBytesRef;
34 : } // namespace wasm
35 :
36 : class BreakPoint;
37 : class JSArrayBuffer;
38 : class SeqOneByteString;
39 : class WasmDebugInfo;
40 : class WasmExceptionTag;
41 : class WasmInstanceObject;
42 : class WasmModuleObject;
43 : class WasmExportedFunction;
44 :
45 : template <class CppType>
46 : class Managed;
47 :
48 : #define DECL_OPTIONAL_ACCESSORS(name, type) \
49 : V8_INLINE bool has_##name(); \
50 : DECL_ACCESSORS(name, type)
51 :
52 : // A helper for an entry in an indirect function table (IFT).
53 : // The underlying storage in the instance is used by generated code to
54 : // call functions indirectly at runtime.
55 : // Each entry has the following fields:
56 : // - object = target instance, if a Wasm function, tuple if imported
57 : // - sig_id = signature id of function
58 : // - target = entrypoint to Wasm code or import wrapper code
59 : class IndirectFunctionTableEntry {
60 : public:
61 : inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int index);
62 :
63 : void clear();
64 : void Set(int sig_id, Handle<WasmInstanceObject> target_instance,
65 : int target_func_index);
66 :
67 : void CopyFrom(const IndirectFunctionTableEntry& that);
68 :
69 : Object object_ref();
70 : int sig_id();
71 : Address target();
72 :
73 : private:
74 : Handle<WasmInstanceObject> const instance_;
75 : int const index_;
76 : };
77 :
78 : // A helper for an entry for an imported function, indexed statically.
79 : // The underlying storage in the instance is used by generated code to
80 : // call imported functions at runtime.
81 : // Each entry is either:
82 : // - WASM to JS, which has fields
83 : // - object = a Tuple2 of the importing instance and the callable
84 : // - target = entrypoint to import wrapper code
85 : // - WASM to WASM, which has fields
86 : // - object = target instance
87 : // - target = entrypoint for the function
88 : class ImportedFunctionEntry {
89 : public:
90 : inline ImportedFunctionEntry(Handle<WasmInstanceObject>, int index);
91 :
92 : // Initialize this entry as a WASM to JS call. This accepts the isolate as a
93 : // parameter, since it must allocate a tuple.
94 : void SetWasmToJs(Isolate*, Handle<JSReceiver> callable,
95 : const wasm::WasmCode* wasm_to_js_wrapper);
96 : // Initialize this entry as a WASM to WASM call.
97 : void SetWasmToWasm(WasmInstanceObject target_instance, Address call_target);
98 :
99 : WasmInstanceObject instance();
100 : JSReceiver callable();
101 : Object object_ref();
102 : Address target();
103 :
104 : private:
105 : Handle<WasmInstanceObject> const instance_;
106 : int const index_;
107 : };
108 :
109 : // Representation of a WebAssembly.Module JavaScript-level object.
110 : class WasmModuleObject : public JSObject {
111 : public:
112 : DECL_CAST(WasmModuleObject)
113 :
114 : DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>)
115 : DECL_ACCESSORS(export_wrappers, FixedArray)
116 : DECL_ACCESSORS(script, Script)
117 : DECL_ACCESSORS(weak_instance_list, WeakArrayList)
118 : DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray)
119 : DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray)
120 : inline wasm::NativeModule* native_module() const;
121 : inline std::shared_ptr<wasm::NativeModule> shared_native_module() const;
122 : inline const wasm::WasmModule* module() const;
123 : inline void reset_breakpoint_infos();
124 :
125 : // Dispatched behavior.
126 : DECL_PRINTER(WasmModuleObject)
127 : DECL_VERIFIER(WasmModuleObject)
128 :
129 : // Layout description.
130 : #define WASM_MODULE_OBJECT_FIELDS(V) \
131 : V(kNativeModuleOffset, kTaggedSize) \
132 : V(kExportWrappersOffset, kTaggedSize) \
133 : V(kScriptOffset, kTaggedSize) \
134 : V(kWeakInstanceListOffset, kTaggedSize) \
135 : V(kAsmJsOffsetTableOffset, kTaggedSize) \
136 : V(kBreakPointInfosOffset, kTaggedSize) \
137 : V(kSize, 0)
138 :
139 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
140 : WASM_MODULE_OBJECT_FIELDS)
141 : #undef WASM_MODULE_OBJECT_FIELDS
142 :
143 : // Creates a new {WasmModuleObject} with a new {NativeModule} underneath.
144 : static Handle<WasmModuleObject> New(
145 : Isolate* isolate, const wasm::WasmFeatures& enabled,
146 : std::shared_ptr<const wasm::WasmModule> module,
147 : OwnedVector<const uint8_t> wire_bytes, Handle<Script> script,
148 : Handle<ByteArray> asm_js_offset_table);
149 :
150 : // Creates a new {WasmModuleObject} for an existing {NativeModule} that is
151 : // reference counted and might be shared between multiple Isolates.
152 : static Handle<WasmModuleObject> New(
153 : Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
154 : Handle<Script> script, size_t code_size_estimate);
155 : static Handle<WasmModuleObject> New(
156 : Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
157 : Handle<Script> script, Handle<FixedArray> export_wrappers,
158 : size_t code_size_estimate);
159 :
160 : // Set a breakpoint on the given byte position inside the given module.
161 : // This will affect all live and future instances of the module.
162 : // The passed position might be modified to point to the next breakable
163 : // location inside the same function.
164 : // If it points outside a function, or behind the last breakable location,
165 : // this function returns false and does not set any breakpoint.
166 : static bool SetBreakPoint(Handle<WasmModuleObject>, int* position,
167 : Handle<BreakPoint> break_point);
168 :
169 : // Check whether this module was generated from asm.js source.
170 : inline bool is_asm_js();
171 :
172 : static void AddBreakpoint(Handle<WasmModuleObject>, int position,
173 : Handle<BreakPoint> break_point);
174 :
175 : static void SetBreakpointsOnNewInstance(Handle<WasmModuleObject>,
176 : Handle<WasmInstanceObject>);
177 :
178 : // Get the module name, if set. Returns an empty handle otherwise.
179 : static MaybeHandle<String> GetModuleNameOrNull(Isolate*,
180 : Handle<WasmModuleObject>);
181 :
182 : // Get the function name of the function identified by the given index.
183 : // Returns a null handle if the function is unnamed or the name is not a valid
184 : // UTF-8 string.
185 : static MaybeHandle<String> GetFunctionNameOrNull(Isolate*,
186 : Handle<WasmModuleObject>,
187 : uint32_t func_index);
188 :
189 : // Get the function name of the function identified by the given index.
190 : // Returns "wasm-function[func_index]" if the function is unnamed or the
191 : // name is not a valid UTF-8 string.
192 : static Handle<String> GetFunctionName(Isolate*, Handle<WasmModuleObject>,
193 : uint32_t func_index);
194 :
195 : // Get the raw bytes of the function name of the function identified by the
196 : // given index.
197 : // Meant to be used for debugging or frame printing.
198 : // Does not allocate, hence gc-safe.
199 : Vector<const uint8_t> GetRawFunctionName(uint32_t func_index);
200 :
201 : // Return the byte offset of the function identified by the given index.
202 : // The offset will be relative to the start of the module bytes.
203 : // Returns -1 if the function index is invalid.
204 : int GetFunctionOffset(uint32_t func_index);
205 :
206 : // Returns the function containing the given byte offset.
207 : // Returns -1 if the byte offset is not contained in any function of this
208 : // module.
209 : int GetContainingFunction(uint32_t byte_offset);
210 :
211 : // Translate from byte offset in the module to function number and byte offset
212 : // within that function, encoded as line and column in the position info.
213 : // Returns true if the position is valid inside this module, false otherwise.
214 : bool GetPositionInfo(uint32_t position, Script::PositionInfo* info);
215 :
216 : // Get the source position from a given function index and byte offset,
217 : // for either asm.js or pure Wasm modules.
218 : static int GetSourcePosition(Handle<WasmModuleObject>, uint32_t func_index,
219 : uint32_t byte_offset,
220 : bool is_at_number_conversion);
221 :
222 : // Compute the disassembly of a wasm function.
223 : // Returns the disassembly string and a list of <byte_offset, line, column>
224 : // entries, mapping wasm byte offsets to line and column in the disassembly.
225 : // The list is guaranteed to be ordered by the byte_offset.
226 : // Returns an empty string and empty vector if the function index is invalid.
227 : debug::WasmDisassembly DisassembleFunction(int func_index);
228 :
229 : // Extract a portion of the wire bytes as UTF-8 string.
230 : // Returns a null handle if the respective bytes do not form a valid UTF-8
231 : // string.
232 : static MaybeHandle<String> ExtractUtf8StringFromModuleBytes(
233 : Isolate* isolate, Handle<WasmModuleObject>, wasm::WireBytesRef ref);
234 : static MaybeHandle<String> ExtractUtf8StringFromModuleBytes(
235 : Isolate* isolate, Vector<const uint8_t> wire_byte,
236 : wasm::WireBytesRef ref);
237 :
238 : // Get a list of all possible breakpoints within a given range of this module.
239 : bool GetPossibleBreakpoints(const debug::Location& start,
240 : const debug::Location& end,
241 : std::vector<debug::BreakLocation>* locations);
242 :
243 : // Return an empty handle if no breakpoint is hit at that location, or a
244 : // FixedArray with all hit breakpoint objects.
245 : static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*,
246 : Handle<WasmModuleObject>,
247 : int position);
248 :
249 8432 : OBJECT_CONSTRUCTORS(WasmModuleObject, JSObject);
250 : };
251 :
252 : // Representation of a WebAssembly.Table JavaScript-level object.
253 : class WasmTableObject : public JSObject {
254 : public:
255 : DECL_CAST(WasmTableObject)
256 :
257 : DECL_ACCESSORS(elements, FixedArray)
258 : // TODO(titzer): introduce DECL_I64_ACCESSORS macro
259 : DECL_ACCESSORS(maximum_length, Object)
260 : DECL_ACCESSORS(dispatch_tables, FixedArray)
261 :
262 : // Layout description.
263 : #define WASM_TABLE_OBJECT_FIELDS(V) \
264 : V(kElementsOffset, kTaggedSize) \
265 : V(kMaximumLengthOffset, kTaggedSize) \
266 : V(kDispatchTablesOffset, kTaggedSize) \
267 : V(kSize, 0)
268 :
269 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, WASM_TABLE_OBJECT_FIELDS)
270 : #undef WASM_TABLE_OBJECT_FIELDS
271 :
272 : inline uint32_t current_length();
273 : void Grow(Isolate* isolate, uint32_t count);
274 :
275 : static Handle<WasmTableObject> New(Isolate* isolate, uint32_t initial,
276 : uint32_t maximum,
277 : Handle<FixedArray>* js_functions);
278 : static void AddDispatchTable(Isolate* isolate, Handle<WasmTableObject> table,
279 : Handle<WasmInstanceObject> instance,
280 : int table_index);
281 :
282 : static void Set(Isolate* isolate, Handle<WasmTableObject> table,
283 : uint32_t index, Handle<JSFunction> function);
284 :
285 : static void UpdateDispatchTables(Isolate* isolate,
286 : Handle<WasmTableObject> table,
287 : int table_index, wasm::FunctionSig* sig,
288 : Handle<WasmInstanceObject> target_instance,
289 : int target_func_index);
290 :
291 : static void ClearDispatchTables(Isolate* isolate,
292 : Handle<WasmTableObject> table, int index);
293 :
294 : OBJECT_CONSTRUCTORS(WasmTableObject, JSObject);
295 : };
296 :
297 : // Representation of a WebAssembly.Memory JavaScript-level object.
298 : class WasmMemoryObject : public JSObject {
299 : public:
300 : DECL_CAST(WasmMemoryObject)
301 :
302 : DECL_ACCESSORS(array_buffer, JSArrayBuffer)
303 : DECL_INT_ACCESSORS(maximum_pages)
304 : DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList)
305 :
306 : // Layout description.
307 : #define WASM_MEMORY_OBJECT_FIELDS(V) \
308 : V(kArrayBufferOffset, kTaggedSize) \
309 : V(kMaximumPagesOffset, kTaggedSize) \
310 : V(kInstancesOffset, kTaggedSize) \
311 : V(kSize, 0)
312 :
313 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
314 : WASM_MEMORY_OBJECT_FIELDS)
315 : #undef WASM_MEMORY_OBJECT_FIELDS
316 :
317 : // Add an instance to the internal (weak) list.
318 : static void AddInstance(Isolate* isolate, Handle<WasmMemoryObject> memory,
319 : Handle<WasmInstanceObject> object);
320 : inline bool has_maximum_pages();
321 :
322 : // Return whether the underlying backing store has guard regions large enough
323 : // to be used with trap handlers.
324 : bool has_full_guard_region(Isolate* isolate);
325 :
326 : V8_EXPORT_PRIVATE static Handle<WasmMemoryObject> New(
327 : Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, uint32_t maximum);
328 :
329 : static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, uint32_t pages);
330 :
331 1278 : OBJECT_CONSTRUCTORS(WasmMemoryObject, JSObject);
332 : };
333 :
334 : // Representation of a WebAssembly.Global JavaScript-level object.
335 : class WasmGlobalObject : public JSObject {
336 : public:
337 : DECL_CAST(WasmGlobalObject)
338 :
339 : DECL_ACCESSORS(untagged_buffer, JSArrayBuffer)
340 : DECL_ACCESSORS(tagged_buffer, FixedArray)
341 : DECL_INT32_ACCESSORS(offset)
342 : DECL_INT_ACCESSORS(flags)
343 : DECL_PRIMITIVE_ACCESSORS(type, wasm::ValueType)
344 : DECL_BOOLEAN_ACCESSORS(is_mutable)
345 :
346 : #define WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS(V, _) \
347 : V(TypeBits, wasm::ValueType, 8, _) \
348 : V(IsMutableBit, bool, 1, _)
349 :
350 : DEFINE_BIT_FIELDS(WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS)
351 :
352 : #undef WASM_GLOBAL_OBJECT_FLAGS_BIT_FIELDS
353 :
354 : // Layout description.
355 : #define WASM_GLOBAL_OBJECT_FIELDS(V) \
356 : V(kUntaggedBufferOffset, kTaggedSize) \
357 : V(kTaggedBufferOffset, kTaggedSize) \
358 : V(kOffsetOffset, kTaggedSize) \
359 : V(kFlagsOffset, kTaggedSize) \
360 : V(kSize, 0)
361 :
362 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
363 : WASM_GLOBAL_OBJECT_FIELDS)
364 : #undef WASM_GLOBAL_OBJECT_FIELDS
365 :
366 : V8_EXPORT_PRIVATE static MaybeHandle<WasmGlobalObject> New(
367 : Isolate* isolate, MaybeHandle<JSArrayBuffer> maybe_untagged_buffer,
368 : MaybeHandle<FixedArray> maybe_tagged_buffer, wasm::ValueType type,
369 : int32_t offset, bool is_mutable);
370 :
371 : inline int type_size() const;
372 :
373 : inline int32_t GetI32();
374 : inline int64_t GetI64();
375 : inline float GetF32();
376 : inline double GetF64();
377 : inline Handle<Object> GetAnyRef();
378 :
379 : inline void SetI32(int32_t value);
380 : inline void SetI64(int64_t value);
381 : inline void SetF32(float value);
382 : inline void SetF64(double value);
383 : inline void SetAnyRef(Handle<Object> value);
384 :
385 : private:
386 : // This function returns the address of the global's data in the
387 : // JSArrayBuffer. This buffer may be allocated on-heap, in which case it may
388 : // not have a fixed address.
389 : inline Address address() const;
390 :
391 : OBJECT_CONSTRUCTORS(WasmGlobalObject, JSObject);
392 : };
393 :
394 : // Representation of a WebAssembly.Instance JavaScript-level object.
395 : class WasmInstanceObject : public JSObject {
396 : public:
397 : DECL_CAST(WasmInstanceObject)
398 :
399 : DECL_ACCESSORS(module_object, WasmModuleObject)
400 : DECL_ACCESSORS(exports_object, JSObject)
401 : DECL_ACCESSORS(native_context, Context)
402 : DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject)
403 : DECL_OPTIONAL_ACCESSORS(untagged_globals_buffer, JSArrayBuffer)
404 : DECL_OPTIONAL_ACCESSORS(tagged_globals_buffer, FixedArray)
405 : DECL_OPTIONAL_ACCESSORS(imported_mutable_globals_buffers, FixedArray)
406 : DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo)
407 : DECL_OPTIONAL_ACCESSORS(table_object, WasmTableObject)
408 : DECL_OPTIONAL_ACCESSORS(tables, FixedArray)
409 : DECL_ACCESSORS(imported_function_refs, FixedArray)
410 : DECL_OPTIONAL_ACCESSORS(indirect_function_table_refs, FixedArray)
411 : DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign)
412 : DECL_OPTIONAL_ACCESSORS(exceptions_table, FixedArray)
413 : DECL_ACCESSORS(undefined_value, Oddball)
414 : DECL_ACCESSORS(null_value, Oddball)
415 : DECL_ACCESSORS(centry_stub, Code)
416 : DECL_OPTIONAL_ACCESSORS(wasm_exported_functions, FixedArray)
417 : DECL_PRIMITIVE_ACCESSORS(memory_start, byte*)
418 : DECL_PRIMITIVE_ACCESSORS(memory_size, size_t)
419 : DECL_PRIMITIVE_ACCESSORS(memory_mask, size_t)
420 : DECL_PRIMITIVE_ACCESSORS(isolate_root, Address)
421 : DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address)
422 : DECL_PRIMITIVE_ACCESSORS(real_stack_limit_address, Address)
423 : DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*)
424 : DECL_PRIMITIVE_ACCESSORS(globals_start, byte*)
425 : DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*)
426 : DECL_PRIMITIVE_ACCESSORS(indirect_function_table_size, uint32_t)
427 : DECL_PRIMITIVE_ACCESSORS(indirect_function_table_sig_ids, uint32_t*)
428 : DECL_PRIMITIVE_ACCESSORS(indirect_function_table_targets, Address*)
429 : DECL_PRIMITIVE_ACCESSORS(jump_table_start, Address)
430 : DECL_PRIMITIVE_ACCESSORS(data_segment_starts, Address*)
431 : DECL_PRIMITIVE_ACCESSORS(data_segment_sizes, uint32_t*)
432 : DECL_PRIMITIVE_ACCESSORS(dropped_data_segments, byte*)
433 : DECL_PRIMITIVE_ACCESSORS(dropped_elem_segments, byte*)
434 :
435 : V8_INLINE void clear_padding();
436 :
437 : // Dispatched behavior.
438 : DECL_PRINTER(WasmInstanceObject)
439 : DECL_VERIFIER(WasmInstanceObject)
440 :
441 : // Layout description.
442 : #define WASM_INSTANCE_OBJECT_FIELDS(V) \
443 : /* Tagged values. */ \
444 : V(kModuleObjectOffset, kTaggedSize) \
445 : V(kExportsObjectOffset, kTaggedSize) \
446 : V(kNativeContextOffset, kTaggedSize) \
447 : V(kMemoryObjectOffset, kTaggedSize) \
448 : V(kUntaggedGlobalsBufferOffset, kTaggedSize) \
449 : V(kTaggedGlobalsBufferOffset, kTaggedSize) \
450 : V(kImportedMutableGlobalsBuffersOffset, kTaggedSize) \
451 : V(kDebugInfoOffset, kTaggedSize) \
452 : V(kTableObjectOffset, kTaggedSize) \
453 : V(kTablesOffset, kTaggedSize) \
454 : V(kImportedFunctionRefsOffset, kTaggedSize) \
455 : V(kIndirectFunctionTableRefsOffset, kTaggedSize) \
456 : V(kManagedNativeAllocationsOffset, kTaggedSize) \
457 : V(kExceptionsTableOffset, kTaggedSize) \
458 : V(kUndefinedValueOffset, kTaggedSize) \
459 : V(kNullValueOffset, kTaggedSize) \
460 : V(kCEntryStubOffset, kTaggedSize) \
461 : V(kWasmExportedFunctionsOffset, kTaggedSize) \
462 : V(kEndOfTaggedFieldsOffset, 0) \
463 : /* Raw data. */ \
464 : V(kIndirectFunctionTableSizeOffset, kUInt32Size) \
465 : /* Optional padding to align system pointer size fields */ \
466 : V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \
467 : V(kFirstSystemPointerFieldOffset, 0) \
468 : V(kMemoryStartOffset, kSystemPointerSize) \
469 : V(kMemorySizeOffset, kSizetSize) \
470 : V(kMemoryMaskOffset, kSizetSize) \
471 : V(kIsolateRootOffset, kSystemPointerSize) \
472 : V(kStackLimitAddressOffset, kSystemPointerSize) \
473 : V(kRealStackLimitAddressOffset, kSystemPointerSize) \
474 : V(kImportedFunctionTargetsOffset, kSystemPointerSize) \
475 : V(kGlobalsStartOffset, kSystemPointerSize) \
476 : V(kImportedMutableGlobalsOffset, kSystemPointerSize) \
477 : V(kIndirectFunctionTableSigIdsOffset, kSystemPointerSize) \
478 : V(kIndirectFunctionTableTargetsOffset, kSystemPointerSize) \
479 : V(kJumpTableStartOffset, kSystemPointerSize) \
480 : V(kDataSegmentStartsOffset, kSystemPointerSize) \
481 : V(kDataSegmentSizesOffset, kSystemPointerSize) \
482 : V(kDroppedDataSegmentsOffset, kSystemPointerSize) \
483 : V(kDroppedElemSegmentsOffset, kSystemPointerSize) \
484 : /* Header size. */ \
485 : V(kSize, 0)
486 :
487 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
488 : WASM_INSTANCE_OBJECT_FIELDS)
489 : #undef WASM_INSTANCE_OBJECT_FIELDS
490 :
491 : STATIC_ASSERT(IsAligned(kFirstSystemPointerFieldOffset, kSystemPointerSize));
492 : STATIC_ASSERT(IsAligned(kSize, kTaggedSize));
493 :
494 : V8_EXPORT_PRIVATE const wasm::WasmModule* module();
495 :
496 : static bool EnsureIndirectFunctionTableWithMinimumSize(
497 : Handle<WasmInstanceObject> instance, uint32_t minimum_size);
498 :
499 : bool has_indirect_function_table();
500 :
501 : void SetRawMemory(byte* mem_start, size_t mem_size);
502 :
503 : // Get the debug info associated with the given wasm object.
504 : // If no debug info exists yet, it is created automatically.
505 : static Handle<WasmDebugInfo> GetOrCreateDebugInfo(Handle<WasmInstanceObject>);
506 :
507 : static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmModuleObject>);
508 :
509 : Address GetCallTarget(uint32_t func_index);
510 :
511 : // Copies table entries. Returns {false} if the ranges are out-of-bounds.
512 : static bool CopyTableEntries(Isolate* isolate,
513 : Handle<WasmInstanceObject> instance,
514 : uint32_t table_src_index,
515 : uint32_t table_dst_index, uint32_t dst,
516 : uint32_t src,
517 : uint32_t count) V8_WARN_UNUSED_RESULT;
518 :
519 : // Copy table entries from an element segment. Returns {false} if the ranges
520 : // are out-of-bounds.
521 : static bool InitTableEntries(Isolate* isolate,
522 : Handle<WasmInstanceObject> instance,
523 : uint32_t table_index, uint32_t segment_index,
524 : uint32_t dst, uint32_t src,
525 : uint32_t count) V8_WARN_UNUSED_RESULT;
526 :
527 : // Iterates all fields in the object except the untagged fields.
528 : class BodyDescriptor;
529 :
530 : static MaybeHandle<WasmExportedFunction> GetWasmExportedFunction(
531 : Isolate* isolate, Handle<WasmInstanceObject> instance, int index);
532 : static void SetWasmExportedFunction(Isolate* isolate,
533 : Handle<WasmInstanceObject> instance,
534 : int index,
535 : Handle<WasmExportedFunction> val);
536 :
537 44956 : OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
538 :
539 : private:
540 : static void InitDataSegmentArrays(Handle<WasmInstanceObject>,
541 : Handle<WasmModuleObject>);
542 : static void InitElemSegmentArrays(Handle<WasmInstanceObject>,
543 : Handle<WasmModuleObject>);
544 : };
545 :
546 : // Representation of WebAssembly.Exception JavaScript-level object.
547 : class WasmExceptionObject : public JSObject {
548 : public:
549 : DECL_CAST(WasmExceptionObject)
550 :
551 : DECL_ACCESSORS(serialized_signature, PodArray<wasm::ValueType>)
552 : DECL_ACCESSORS(exception_tag, HeapObject)
553 :
554 : // Layout description.
555 : #define WASM_EXCEPTION_OBJECT_FIELDS(V) \
556 : V(kSerializedSignatureOffset, kTaggedSize) \
557 : V(kExceptionTagOffset, kTaggedSize) \
558 : V(kSize, 0)
559 :
560 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
561 : WASM_EXCEPTION_OBJECT_FIELDS)
562 : #undef WASM_EXCEPTION_OBJECT_FIELDS
563 :
564 : // Checks whether the given {sig} has the same parameter types as the
565 : // serialized signature stored within this exception object.
566 : bool IsSignatureEqual(const wasm::FunctionSig* sig);
567 :
568 : static Handle<WasmExceptionObject> New(Isolate* isolate,
569 : const wasm::FunctionSig* sig,
570 : Handle<HeapObject> exception_tag);
571 :
572 : OBJECT_CONSTRUCTORS(WasmExceptionObject, JSObject);
573 : };
574 :
575 : // A Wasm exception that has been thrown out of Wasm code.
576 : class WasmExceptionPackage : public JSReceiver {
577 : public:
578 : // TODO(mstarzinger): Ideally this interface would use {WasmExceptionPackage}
579 : // instead of {JSReceiver} throughout. For now a type-check implies doing a
580 : // property lookup however, which would result in casts being handlified.
581 : static Handle<JSReceiver> New(Isolate* isolate,
582 : Handle<WasmExceptionTag> exception_tag,
583 : int encoded_size);
584 :
585 : // The below getters return {undefined} in case the given exception package
586 : // does not carry the requested values (i.e. is of a different type).
587 : static Handle<Object> GetExceptionTag(Isolate*, Handle<Object> exception);
588 : static Handle<Object> GetExceptionValues(Isolate*, Handle<Object> exception);
589 :
590 : // Determines the size of the array holding all encoded exception values.
591 : static uint32_t GetEncodedSize(const wasm::WasmException* exception);
592 : };
593 :
594 : // A Wasm function that is wrapped and exported to JavaScript.
595 : class WasmExportedFunction : public JSFunction {
596 : public:
597 : WasmInstanceObject instance();
598 : V8_EXPORT_PRIVATE int function_index();
599 :
600 : V8_EXPORT_PRIVATE static bool IsWasmExportedFunction(Object object);
601 :
602 : static Handle<WasmExportedFunction> New(Isolate* isolate,
603 : Handle<WasmInstanceObject> instance,
604 : MaybeHandle<String> maybe_name,
605 : int func_index, int arity,
606 : Handle<Code> export_wrapper);
607 :
608 : Address GetWasmCallTarget();
609 :
610 : wasm::FunctionSig* sig();
611 :
612 : DECL_CAST(WasmExportedFunction)
613 224 : OBJECT_CONSTRUCTORS(WasmExportedFunction, JSFunction);
614 : };
615 :
616 : // Information for a WasmExportedFunction which is referenced as the function
617 : // data of the SharedFunctionInfo underlying the function. For details please
618 : // see the {SharedFunctionInfo::HasWasmExportedFunctionData} predicate.
619 : class WasmExportedFunctionData : public Struct {
620 : public:
621 : DECL_ACCESSORS(wrapper_code, Code)
622 : DECL_ACCESSORS(instance, WasmInstanceObject)
623 : DECL_INT_ACCESSORS(jump_table_offset)
624 : DECL_INT_ACCESSORS(function_index)
625 :
626 : DECL_CAST(WasmExportedFunctionData)
627 :
628 : // Dispatched behavior.
629 : DECL_PRINTER(WasmExportedFunctionData)
630 : DECL_VERIFIER(WasmExportedFunctionData)
631 :
632 : // Layout description.
633 : #define WASM_EXPORTED_FUNCTION_DATA_FIELDS(V) \
634 : V(kWrapperCodeOffset, kTaggedSize) \
635 : V(kInstanceOffset, kTaggedSize) \
636 : V(kJumpTableOffsetOffset, kTaggedSize) /* Smi */ \
637 : V(kFunctionIndexOffset, kTaggedSize) /* Smi */ \
638 : V(kSize, 0)
639 :
640 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
641 : WASM_EXPORTED_FUNCTION_DATA_FIELDS)
642 : #undef WASM_EXPORTED_FUNCTION_DATA_FIELDS
643 :
644 : OBJECT_CONSTRUCTORS(WasmExportedFunctionData, Struct);
645 : };
646 :
647 : class WasmDebugInfo : public Struct {
648 : public:
649 : NEVER_READ_ONLY_SPACE
650 : DECL_ACCESSORS(wasm_instance, WasmInstanceObject)
651 : DECL_ACCESSORS(interpreter_handle, Object) // Foreign or undefined
652 : DECL_ACCESSORS(interpreted_functions, FixedArray)
653 : DECL_OPTIONAL_ACCESSORS(locals_names, FixedArray)
654 : DECL_OPTIONAL_ACCESSORS(c_wasm_entries, FixedArray)
655 : DECL_OPTIONAL_ACCESSORS(c_wasm_entry_map, Managed<wasm::SignatureMap>)
656 :
657 : DECL_CAST(WasmDebugInfo)
658 :
659 : // Dispatched behavior.
660 : DECL_PRINTER(WasmDebugInfo)
661 : DECL_VERIFIER(WasmDebugInfo)
662 :
663 : // Layout description.
664 : #define WASM_DEBUG_INFO_FIELDS(V) \
665 : V(kInstanceOffset, kTaggedSize) \
666 : V(kInterpreterHandleOffset, kTaggedSize) \
667 : V(kInterpretedFunctionsOffset, kTaggedSize) \
668 : V(kLocalsNamesOffset, kTaggedSize) \
669 : V(kCWasmEntriesOffset, kTaggedSize) \
670 : V(kCWasmEntryMapOffset, kTaggedSize) \
671 : V(kSize, 0)
672 :
673 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WASM_DEBUG_INFO_FIELDS)
674 : #undef WASM_DEBUG_INFO_FIELDS
675 :
676 : static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>);
677 :
678 : // Setup a WasmDebugInfo with an existing WasmInstance struct.
679 : // Returns a pointer to the interpreter instantiated inside this
680 : // WasmDebugInfo.
681 : // Use for testing only.
682 : V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting(
683 : Handle<WasmInstanceObject>);
684 :
685 : // Set a breakpoint in the given function at the given byte offset within that
686 : // function. This will redirect all future calls to this function to the
687 : // interpreter and will always pause at the given offset.
688 : static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset);
689 :
690 : // Make a set of functions always execute in the interpreter without setting
691 : // breakpoints.
692 : static void RedirectToInterpreter(Handle<WasmDebugInfo>,
693 : Vector<int> func_indexes);
694 :
695 : void PrepareStep(StepAction);
696 :
697 : // Execute the specified function in the interpreter. Read arguments from
698 : // arg_buffer.
699 : // The frame_pointer will be used to identify the new activation of the
700 : // interpreter for unwinding and frame inspection.
701 : // Returns true if exited regularly, false if a trap occurred. In the latter
702 : // case, a pending exception will have been set on the isolate.
703 : static bool RunInterpreter(Isolate* isolate, Handle<WasmDebugInfo>,
704 : Address frame_pointer, int func_index,
705 : Address arg_buffer);
706 :
707 : // Get the stack of the wasm interpreter as pairs of <function index, byte
708 : // offset>. The list is ordered bottom-to-top, i.e. caller before callee.
709 : std::vector<std::pair<uint32_t, int>> GetInterpretedStack(
710 : Address frame_pointer);
711 :
712 : std::unique_ptr<wasm::InterpretedFrame, wasm::InterpretedFrameDeleter>
713 : GetInterpretedFrame(Address frame_pointer, int frame_index);
714 :
715 : // Returns the number of calls / function frames executed in the interpreter.
716 : uint64_t NumInterpretedCalls();
717 :
718 : // Get scope details for a specific interpreted frame.
719 : // Both of these methods return a JSArrays (for the global scope and local
720 : // scope respectively) of size {ScopeIterator::kScopeDetailsSize} and layout
721 : // as described in debug-scopes.h.
722 : // - The global scope contains information about globals and the memory.
723 : // - The local scope contains information about parameters, locals, and
724 : // stack values.
725 : static Handle<JSObject> GetGlobalScopeObject(Handle<WasmDebugInfo>,
726 : Address frame_pointer,
727 : int frame_index);
728 : static Handle<JSObject> GetLocalScopeObject(Handle<WasmDebugInfo>,
729 : Address frame_pointer,
730 : int frame_index);
731 :
732 : static Handle<JSFunction> GetCWasmEntry(Handle<WasmDebugInfo>,
733 : wasm::FunctionSig*);
734 :
735 336 : OBJECT_CONSTRUCTORS(WasmDebugInfo, Struct);
736 : };
737 :
738 : // Tags provide an object identity for each exception defined in a wasm module
739 : // header. They are referenced by the following fields:
740 : // - {WasmExceptionObject::exception_tag} : The tag of the exception object.
741 : // - {WasmInstanceObject::exceptions_table}: List of tags used by an instance.
742 : class WasmExceptionTag : public Struct {
743 : public:
744 : static Handle<WasmExceptionTag> New(Isolate* isolate, int index);
745 :
746 : // Note that this index is only useful for debugging purposes and it is not
747 : // unique across modules. The GC however does not allow objects without at
748 : // least one field, hence this also serves as a padding field for now.
749 : DECL_INT_ACCESSORS(index)
750 :
751 : DECL_CAST(WasmExceptionTag)
752 : DECL_PRINTER(WasmExceptionTag)
753 : DECL_VERIFIER(WasmExceptionTag)
754 :
755 : // Layout description.
756 : #define WASM_EXCEPTION_TAG_FIELDS(V) \
757 : V(kIndexOffset, kTaggedSize) \
758 : /* Total size. */ \
759 : V(kSize, 0)
760 :
761 : DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, WASM_EXCEPTION_TAG_FIELDS)
762 : #undef WASM_EXCEPTION_TAG_FIELDS
763 :
764 : OBJECT_CONSTRUCTORS(WasmExceptionTag, Struct);
765 : };
766 :
767 : class AsmWasmData : public Struct {
768 : public:
769 : static Handle<AsmWasmData> New(
770 : Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
771 : Handle<FixedArray> export_wrappers, Handle<ByteArray> asm_js_offset_table,
772 : Handle<HeapNumber> uses_bitset);
773 :
774 : DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>)
775 : DECL_ACCESSORS(export_wrappers, FixedArray)
776 : DECL_ACCESSORS(asm_js_offset_table, ByteArray)
777 : DECL_ACCESSORS(uses_bitset, HeapNumber)
778 :
779 : DECL_CAST(AsmWasmData)
780 : DECL_PRINTER(AsmWasmData)
781 : DECL_VERIFIER(AsmWasmData)
782 :
783 : // Layout description.
784 : #define ASM_WASM_DATA_FIELDS(V) \
785 : V(kManagedNativeModuleOffset, kTaggedSize) \
786 : V(kExportWrappersOffset, kTaggedSize) \
787 : V(kAsmJsOffsetTableOffset, kTaggedSize) \
788 : V(kUsesBitsetOffset, kTaggedSize) \
789 : /* Total size. */ \
790 : V(kSize, 0)
791 :
792 : DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, ASM_WASM_DATA_FIELDS)
793 : #undef ASM_WASM_DATA_FIELDS
794 :
795 : OBJECT_CONSTRUCTORS(AsmWasmData, Struct);
796 : };
797 :
798 : #undef DECL_OPTIONAL_ACCESSORS
799 :
800 : } // namespace internal
801 : } // namespace v8
802 :
803 : #include "src/objects/object-macros-undef.h"
804 :
805 : #endif // V8_WASM_WASM_OBJECTS_H_
|