xref: /third_party/node/deps/v8/src/wasm/wasm-objects.h (revision 1cb0ef41)
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#if !V8_ENABLE_WEBASSEMBLY
6#error This header should only be included if WebAssembly is enabled.
7#endif  // !V8_ENABLE_WEBASSEMBLY
8
9#ifndef V8_WASM_WASM_OBJECTS_H_
10#define V8_WASM_WASM_OBJECTS_H_
11
12#include <memory>
13
14#include "src/base/bit-field.h"
15#include "src/base/bits.h"
16#include "src/codegen/signature.h"
17#include "src/debug/debug.h"
18#include "src/heap/heap.h"
19#include "src/objects/js-function.h"
20#include "src/objects/js-objects.h"
21#include "src/objects/objects.h"
22#include "src/wasm/stacks.h"
23#include "src/wasm/struct-types.h"
24#include "src/wasm/value-type.h"
25
26// Has to be the last include (doesn't have include guards)
27#include "src/objects/object-macros.h"
28
29namespace v8 {
30namespace internal {
31namespace wasm {
32class InterpretedFrame;
33class NativeModule;
34class WasmCode;
35struct WasmFunction;
36struct WasmGlobal;
37struct WasmModule;
38struct WasmTag;
39class WasmValue;
40class WireBytesRef;
41}  // namespace wasm
42
43class BreakPoint;
44class JSArrayBuffer;
45class SeqOneByteString;
46class StructBodyDescriptor;
47class WasmCapiFunction;
48class WasmExceptionTag;
49class WasmExportedFunction;
50class WasmExternalFunction;
51class WasmInstanceObject;
52class WasmJSFunction;
53class WasmModuleObject;
54
55enum class SharedFlag : uint8_t;
56
57template <class CppType>
58class Managed;
59
60#include "torque-generated/src/wasm/wasm-objects-tq.inc"
61
62#define DECL_OPTIONAL_ACCESSORS(name, type) \
63  DECL_GETTER(has_##name, bool)             \
64  DECL_ACCESSORS(name, type)
65
66class V8_EXPORT_PRIVATE FunctionTargetAndRef {
67 public:
68  FunctionTargetAndRef(Handle<WasmInstanceObject> target_instance,
69                       int target_func_index);
70  Handle<Object> ref() { return ref_; }
71  Address call_target() { return call_target_; }
72
73 private:
74  Handle<Object> ref_;
75  Address call_target_;
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 WasmApiFunctionRef
84//      - target = entrypoint to import wrapper code
85//   - Wasm to Wasm, which has fields
86//      - object = target instance
87//      - target = entrypoint for the function
88class 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  V8_EXPORT_PRIVATE void SetWasmToJs(Isolate*, Handle<JSReceiver> callable,
95                                     const wasm::WasmCode* wasm_to_js_wrapper,
96                                     Handle<HeapObject> suspender);
97  // Initialize this entry as a Wasm to Wasm call.
98  void SetWasmToWasm(WasmInstanceObject target_instance, Address call_target);
99
100  JSReceiver callable();
101  Object maybe_callable();
102  Object object_ref();
103  Address target();
104
105 private:
106  Handle<WasmInstanceObject> const instance_;
107  int const index_;
108};
109
110enum InternalizeString : bool { kInternalize = true, kNoInternalize = false };
111
112// Representation of a WebAssembly.Module JavaScript-level object.
113class WasmModuleObject
114    : public TorqueGeneratedWasmModuleObject<WasmModuleObject, JSObject> {
115 public:
116  inline wasm::NativeModule* native_module() const;
117  inline const std::shared_ptr<wasm::NativeModule>& shared_native_module()
118      const;
119  inline const wasm::WasmModule* module() const;
120
121  // Dispatched behavior.
122  DECL_PRINTER(WasmModuleObject)
123
124  // Creates a new {WasmModuleObject} for an existing {NativeModule} that is
125  // reference counted and might be shared between multiple Isolates.
126  V8_EXPORT_PRIVATE static Handle<WasmModuleObject> New(
127      Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
128      Handle<Script> script);
129  V8_EXPORT_PRIVATE static Handle<WasmModuleObject> New(
130      Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
131      Handle<Script> script, Handle<FixedArray> export_wrappers);
132
133  // Check whether this module was generated from asm.js source.
134  inline bool is_asm_js();
135
136  // Get the module name, if set. Returns an empty handle otherwise.
137  static MaybeHandle<String> GetModuleNameOrNull(Isolate*,
138                                                 Handle<WasmModuleObject>);
139
140  // Get the function name of the function identified by the given index.
141  // Returns a null handle if the function is unnamed or the name is not a valid
142  // UTF-8 string.
143  static MaybeHandle<String> GetFunctionNameOrNull(Isolate*,
144                                                   Handle<WasmModuleObject>,
145                                                   uint32_t func_index);
146
147  // Get the raw bytes of the function name of the function identified by the
148  // given index.
149  // Meant to be used for debugging or frame printing.
150  // Does not allocate, hence gc-safe.
151  base::Vector<const uint8_t> GetRawFunctionName(int func_index);
152
153  // Extract a portion of the wire bytes as UTF-8 string, optionally
154  // internalized. (Prefer to internalize early if the string will be used for a
155  // property lookup anyway.)
156  static Handle<String> ExtractUtf8StringFromModuleBytes(
157      Isolate*, Handle<WasmModuleObject>, wasm::WireBytesRef,
158      InternalizeString);
159  static Handle<String> ExtractUtf8StringFromModuleBytes(
160      Isolate*, base::Vector<const uint8_t> wire_byte, wasm::WireBytesRef,
161      InternalizeString);
162
163  TQ_OBJECT_CONSTRUCTORS(WasmModuleObject)
164};
165
166// Representation of a WebAssembly.Table JavaScript-level object.
167class WasmTableObject
168    : public TorqueGeneratedWasmTableObject<WasmTableObject, JSObject> {
169 public:
170  inline wasm::ValueType type();
171
172  V8_EXPORT_PRIVATE static int Grow(Isolate* isolate,
173                                    Handle<WasmTableObject> table,
174                                    uint32_t count, Handle<Object> init_value);
175
176  V8_EXPORT_PRIVATE static Handle<WasmTableObject> New(
177      Isolate* isolate, Handle<WasmInstanceObject> instance,
178      wasm::ValueType type, uint32_t initial, bool has_maximum,
179      uint32_t maximum, Handle<FixedArray>* entries,
180      Handle<Object> initial_value);
181
182  V8_EXPORT_PRIVATE static void AddDispatchTable(
183      Isolate* isolate, Handle<WasmTableObject> table,
184      Handle<WasmInstanceObject> instance, int table_index);
185
186  static bool IsInBounds(Isolate* isolate, Handle<WasmTableObject> table,
187                         uint32_t entry_index);
188
189  static bool IsValidElement(Isolate* isolate, Handle<WasmTableObject> table,
190                             Handle<Object> entry);
191
192  V8_EXPORT_PRIVATE static void Set(Isolate* isolate,
193                                    Handle<WasmTableObject> table,
194                                    uint32_t index, Handle<Object> entry);
195
196  V8_EXPORT_PRIVATE static Handle<Object> Get(Isolate* isolate,
197                                              Handle<WasmTableObject> table,
198                                              uint32_t index);
199
200  V8_EXPORT_PRIVATE static void Fill(Isolate* isolate,
201                                     Handle<WasmTableObject> table,
202                                     uint32_t start, Handle<Object> entry,
203                                     uint32_t count);
204
205  // TODO(wasm): Unify these three methods into one.
206  static void UpdateDispatchTables(Isolate* isolate, WasmTableObject table,
207                                   int entry_index,
208                                   const wasm::WasmFunction* func,
209                                   WasmInstanceObject target_instance);
210  static void UpdateDispatchTables(Isolate* isolate,
211                                   Handle<WasmTableObject> table,
212                                   int entry_index,
213                                   Handle<WasmJSFunction> function);
214  static void UpdateDispatchTables(Isolate* isolate,
215                                   Handle<WasmTableObject> table,
216                                   int entry_index,
217                                   Handle<WasmCapiFunction> capi_function);
218
219  static void ClearDispatchTables(Isolate* isolate,
220                                  Handle<WasmTableObject> table, int index);
221
222  V8_EXPORT_PRIVATE static void SetFunctionTablePlaceholder(
223      Isolate* isolate, Handle<WasmTableObject> table, int entry_index,
224      Handle<WasmInstanceObject> instance, int func_index);
225
226  // This function reads the content of a function table entry and returns it
227  // through the out parameters {is_valid}, {is_null}, {instance},
228  // {function_index}, and {maybe_js_function}.
229  static void GetFunctionTableEntry(
230      Isolate* isolate, const wasm::WasmModule* module,
231      Handle<WasmTableObject> table, int entry_index, bool* is_valid,
232      bool* is_null, MaybeHandle<WasmInstanceObject>* instance,
233      int* function_index, MaybeHandle<WasmJSFunction>* maybe_js_function);
234
235 private:
236  // {entry} is either {Null} or a {WasmInternalFunction}.
237  static void SetFunctionTableEntry(Isolate* isolate,
238                                    Handle<WasmTableObject> table,
239                                    Handle<FixedArray> entries, int entry_index,
240                                    Handle<Object> entry);
241
242  TQ_OBJECT_CONSTRUCTORS(WasmTableObject)
243};
244
245// Representation of a WebAssembly.Memory JavaScript-level object.
246class WasmMemoryObject
247    : public TorqueGeneratedWasmMemoryObject<WasmMemoryObject, JSObject> {
248 public:
249  DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList)
250
251  // Add an instance to the internal (weak) list.
252  V8_EXPORT_PRIVATE static void AddInstance(Isolate* isolate,
253                                            Handle<WasmMemoryObject> memory,
254                                            Handle<WasmInstanceObject> object);
255  inline bool has_maximum_pages();
256
257  V8_EXPORT_PRIVATE static MaybeHandle<WasmMemoryObject> New(
258      Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, int maximum);
259
260  V8_EXPORT_PRIVATE static MaybeHandle<WasmMemoryObject> New(Isolate* isolate,
261                                                             int initial,
262                                                             int maximum,
263                                                             SharedFlag shared);
264
265  static constexpr int kNoMaximum = -1;
266
267  void update_instances(Isolate* isolate, Handle<JSArrayBuffer> buffer);
268
269  V8_EXPORT_PRIVATE static int32_t Grow(Isolate*, Handle<WasmMemoryObject>,
270                                        uint32_t pages);
271
272  TQ_OBJECT_CONSTRUCTORS(WasmMemoryObject)
273};
274
275// Representation of a WebAssembly.Global JavaScript-level object.
276class WasmGlobalObject
277    : public TorqueGeneratedWasmGlobalObject<WasmGlobalObject, JSObject> {
278 public:
279  DECL_ACCESSORS(untagged_buffer, JSArrayBuffer)
280  DECL_ACCESSORS(tagged_buffer, FixedArray)
281  DECL_PRIMITIVE_ACCESSORS(type, wasm::ValueType)
282
283  // Dispatched behavior.
284  DECL_PRINTER(WasmGlobalObject)
285
286  V8_EXPORT_PRIVATE static MaybeHandle<WasmGlobalObject> New(
287      Isolate* isolate, Handle<WasmInstanceObject> instance,
288      MaybeHandle<JSArrayBuffer> maybe_untagged_buffer,
289      MaybeHandle<FixedArray> maybe_tagged_buffer, wasm::ValueType type,
290      int32_t offset, bool is_mutable);
291
292  inline int type_size() const;
293
294  inline int32_t GetI32();
295  inline int64_t GetI64();
296  inline float GetF32();
297  inline double GetF64();
298  inline Handle<Object> GetRef();
299
300  inline void SetI32(int32_t value);
301  inline void SetI64(int64_t value);
302  inline void SetF32(float value);
303  inline void SetF64(double value);
304  inline void SetExternRef(Handle<Object> value);
305  inline bool SetFuncRef(Isolate* isolate, Handle<Object> value);
306
307 private:
308  // This function returns the address of the global's data in the
309  // JSArrayBuffer. This buffer may be allocated on-heap, in which case it may
310  // not have a fixed address.
311  inline Address address() const;
312
313  TQ_OBJECT_CONSTRUCTORS(WasmGlobalObject)
314};
315
316// Representation of a WebAssembly.Instance JavaScript-level object.
317class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
318 public:
319  DECL_CAST(WasmInstanceObject)
320
321  DECL_ACCESSORS(module_object, WasmModuleObject)
322  DECL_ACCESSORS(exports_object, JSObject)
323  DECL_ACCESSORS(native_context, Context)
324  DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject)
325  DECL_OPTIONAL_ACCESSORS(untagged_globals_buffer, JSArrayBuffer)
326  DECL_OPTIONAL_ACCESSORS(tagged_globals_buffer, FixedArray)
327  DECL_OPTIONAL_ACCESSORS(imported_mutable_globals_buffers, FixedArray)
328  DECL_OPTIONAL_ACCESSORS(tables, FixedArray)
329  DECL_OPTIONAL_ACCESSORS(indirect_function_tables, FixedArray)
330  DECL_ACCESSORS(imported_function_refs, FixedArray)
331  DECL_OPTIONAL_ACCESSORS(indirect_function_table_refs, FixedArray)
332  DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign)
333  DECL_OPTIONAL_ACCESSORS(tags_table, FixedArray)
334  DECL_OPTIONAL_ACCESSORS(wasm_internal_functions, FixedArray)
335  DECL_ACCESSORS(managed_object_maps, FixedArray)
336  DECL_ACCESSORS(feedback_vectors, FixedArray)
337  DECL_SANDBOXED_POINTER_ACCESSORS(memory_start, byte*)
338  DECL_PRIMITIVE_ACCESSORS(memory_size, size_t)
339  DECL_PRIMITIVE_ACCESSORS(isolate_root, Address)
340  DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address)
341  DECL_PRIMITIVE_ACCESSORS(real_stack_limit_address, Address)
342  DECL_PRIMITIVE_ACCESSORS(new_allocation_limit_address, Address*)
343  DECL_PRIMITIVE_ACCESSORS(new_allocation_top_address, Address*)
344  DECL_PRIMITIVE_ACCESSORS(old_allocation_limit_address, Address*)
345  DECL_PRIMITIVE_ACCESSORS(old_allocation_top_address, Address*)
346  DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*)
347  DECL_PRIMITIVE_ACCESSORS(globals_start, byte*)
348  DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*)
349  DECL_PRIMITIVE_ACCESSORS(indirect_function_table_size, uint32_t)
350  DECL_PRIMITIVE_ACCESSORS(indirect_function_table_sig_ids, uint32_t*)
351  DECL_PRIMITIVE_ACCESSORS(indirect_function_table_targets, Address*)
352  DECL_PRIMITIVE_ACCESSORS(jump_table_start, Address)
353  DECL_PRIMITIVE_ACCESSORS(data_segment_starts, Address*)
354  DECL_PRIMITIVE_ACCESSORS(data_segment_sizes, uint32_t*)
355  DECL_PRIMITIVE_ACCESSORS(dropped_elem_segments, byte*)
356  DECL_PRIMITIVE_ACCESSORS(hook_on_function_call_address, Address)
357  DECL_PRIMITIVE_ACCESSORS(tiering_budget_array, uint32_t*)
358  DECL_PRIMITIVE_ACCESSORS(break_on_entry, uint8_t)
359
360  // Clear uninitialized padding space. This ensures that the snapshot content
361  // is deterministic. Depending on the V8 build mode there could be no padding.
362  V8_INLINE void clear_padding();
363
364  // Dispatched behavior.
365  DECL_PRINTER(WasmInstanceObject)
366  DECL_VERIFIER(WasmInstanceObject)
367
368// Layout description.
369#define WASM_INSTANCE_OBJECT_FIELDS(V)                                    \
370  /* Often-accessed fields go first to minimize generated code size. */   \
371  /* Less than system pointer sized fields come first. */                 \
372  V(kImportedFunctionRefsOffset, kTaggedSize)                             \
373  V(kIndirectFunctionTableRefsOffset, kTaggedSize)                        \
374  V(kIndirectFunctionTableSizeOffset, kUInt32Size)                        \
375  /* Optional padding to align system pointer size fields */              \
376  V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \
377  V(kMemoryStartOffset, kSystemPointerSize)                               \
378  V(kMemorySizeOffset, kSizetSize)                                        \
379  V(kStackLimitAddressOffset, kSystemPointerSize)                         \
380  V(kImportedFunctionTargetsOffset, kSystemPointerSize)                   \
381  V(kIndirectFunctionTableTargetsOffset, kSystemPointerSize)              \
382  V(kIndirectFunctionTableSigIdsOffset, kSystemPointerSize)               \
383  V(kGlobalsStartOffset, kSystemPointerSize)                              \
384  V(kImportedMutableGlobalsOffset, kSystemPointerSize)                    \
385  V(kIsolateRootOffset, kSystemPointerSize)                               \
386  V(kJumpTableStartOffset, kSystemPointerSize)                            \
387  /* End of often-accessed fields. */                                     \
388  /* Continue with system pointer size fields to maintain alignment. */   \
389  V(kNewAllocationLimitAddressOffset, kSystemPointerSize)                 \
390  V(kNewAllocationTopAddressOffset, kSystemPointerSize)                   \
391  V(kOldAllocationLimitAddressOffset, kSystemPointerSize)                 \
392  V(kOldAllocationTopAddressOffset, kSystemPointerSize)                   \
393  V(kRealStackLimitAddressOffset, kSystemPointerSize)                     \
394  V(kDataSegmentStartsOffset, kSystemPointerSize)                         \
395  V(kDataSegmentSizesOffset, kSystemPointerSize)                          \
396  V(kDroppedElemSegmentsOffset, kSystemPointerSize)                       \
397  V(kHookOnFunctionCallAddressOffset, kSystemPointerSize)                 \
398  V(kTieringBudgetArrayOffset, kSystemPointerSize)                        \
399  /* Less than system pointer size aligned fields are below. */           \
400  V(kModuleObjectOffset, kTaggedSize)                                     \
401  V(kExportsObjectOffset, kTaggedSize)                                    \
402  V(kNativeContextOffset, kTaggedSize)                                    \
403  V(kMemoryObjectOffset, kTaggedSize)                                     \
404  V(kUntaggedGlobalsBufferOffset, kTaggedSize)                            \
405  V(kTaggedGlobalsBufferOffset, kTaggedSize)                              \
406  V(kImportedMutableGlobalsBuffersOffset, kTaggedSize)                    \
407  V(kTablesOffset, kTaggedSize)                                           \
408  V(kIndirectFunctionTablesOffset, kTaggedSize)                           \
409  V(kManagedNativeAllocationsOffset, kTaggedSize)                         \
410  V(kTagsTableOffset, kTaggedSize)                                        \
411  V(kWasmInternalFunctionsOffset, kTaggedSize)                            \
412  V(kManagedObjectMapsOffset, kTaggedSize)                                \
413  V(kFeedbackVectorsOffset, kTaggedSize)                                  \
414  V(kBreakOnEntryOffset, kUInt8Size)                                      \
415  /* More padding to make the header pointer-size aligned */              \
416  V(kHeaderPaddingOffset, POINTER_SIZE_PADDING(kHeaderPaddingOffset))     \
417  V(kHeaderSize, 0)
418
419  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
420                                WASM_INSTANCE_OBJECT_FIELDS)
421  STATIC_ASSERT(IsAligned(kHeaderSize, kTaggedSize));
422  // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size
423  // fields (external pointers, doubles and BigInt data) are only kTaggedSize
424  // aligned so checking for alignments of fields bigger than kTaggedSize
425  // doesn't make sense until v8:8875 is fixed.
426#define ASSERT_FIELD_ALIGNED(offset, size)                                 \
427  STATIC_ASSERT(size == 0 || IsAligned(offset, size) ||                    \
428                (COMPRESS_POINTERS_BOOL && (size == kSystemPointerSize) && \
429                 IsAligned(offset, kTaggedSize)));
430  WASM_INSTANCE_OBJECT_FIELDS(ASSERT_FIELD_ALIGNED)
431#undef ASSERT_FIELD_ALIGNED
432#undef WASM_INSTANCE_OBJECT_FIELDS
433
434  static constexpr uint16_t kTaggedFieldOffsets[] = {
435      kImportedFunctionRefsOffset,
436      kIndirectFunctionTableRefsOffset,
437      kModuleObjectOffset,
438      kExportsObjectOffset,
439      kNativeContextOffset,
440      kMemoryObjectOffset,
441      kUntaggedGlobalsBufferOffset,
442      kTaggedGlobalsBufferOffset,
443      kImportedMutableGlobalsBuffersOffset,
444      kTablesOffset,
445      kIndirectFunctionTablesOffset,
446      kManagedNativeAllocationsOffset,
447      kTagsTableOffset,
448      kWasmInternalFunctionsOffset,
449      kManagedObjectMapsOffset,
450      kFeedbackVectorsOffset};
451
452  const wasm::WasmModule* module();
453
454  static bool EnsureIndirectFunctionTableWithMinimumSize(
455      Handle<WasmInstanceObject> instance, int table_index,
456      uint32_t minimum_size);
457
458  void SetRawMemory(byte* mem_start, size_t mem_size);
459
460  static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmModuleObject>);
461
462  Address GetCallTarget(uint32_t func_index);
463
464  Handle<WasmIndirectFunctionTable> GetIndirectFunctionTable(
465      Isolate*, uint32_t table_index);
466
467  void SetIndirectFunctionTableShortcuts(Isolate* isolate);
468
469  // Copies table entries. Returns {false} if the ranges are out-of-bounds.
470  static bool CopyTableEntries(Isolate* isolate,
471                               Handle<WasmInstanceObject> instance,
472                               uint32_t table_dst_index,
473                               uint32_t table_src_index, uint32_t dst,
474                               uint32_t src,
475                               uint32_t count) V8_WARN_UNUSED_RESULT;
476
477  // Copy table entries from an element segment. Returns {false} if the ranges
478  // are out-of-bounds.
479  static bool InitTableEntries(Isolate* isolate,
480                               Handle<WasmInstanceObject> instance,
481                               uint32_t table_index, uint32_t segment_index,
482                               uint32_t dst, uint32_t src,
483                               uint32_t count) V8_WARN_UNUSED_RESULT;
484
485  // Iterates all fields in the object except the untagged fields.
486  class BodyDescriptor;
487
488  static MaybeHandle<WasmInternalFunction> GetWasmInternalFunction(
489      Isolate* isolate, Handle<WasmInstanceObject> instance, int index);
490
491  // Acquires the {WasmInternalFunction} for a given {function_index} from the
492  // cache of the given {instance}, or creates a new {WasmInternalFunction} if
493  // it does not exist yet. The new {WasmInternalFunction} is added to the
494  // cache of the {instance} immediately.
495  static Handle<WasmInternalFunction> GetOrCreateWasmInternalFunction(
496      Isolate* isolate, Handle<WasmInstanceObject> instance,
497      int function_index);
498
499  static void SetWasmInternalFunction(Isolate* isolate,
500                                      Handle<WasmInstanceObject> instance,
501                                      int index,
502                                      Handle<WasmInternalFunction> val);
503
504  // Imports a constructed {WasmJSFunction} into the indirect function table of
505  // this instance. Note that this might trigger wrapper compilation, since a
506  // {WasmJSFunction} is instance-independent and just wraps a JS callable.
507  static void ImportWasmJSFunctionIntoTable(Isolate* isolate,
508                                            Handle<WasmInstanceObject> instance,
509                                            int table_index, int entry_index,
510                                            Handle<WasmJSFunction> js_function);
511
512  // Get a raw pointer to the location where the given global is stored.
513  // {global} must not be a reference type.
514  static uint8_t* GetGlobalStorage(Handle<WasmInstanceObject>,
515                                   const wasm::WasmGlobal&);
516
517  // Get the FixedArray and the index in that FixedArray for the given global,
518  // which must be a reference type.
519  static std::pair<Handle<FixedArray>, uint32_t> GetGlobalBufferAndIndex(
520      Handle<WasmInstanceObject>, const wasm::WasmGlobal&);
521
522  // Get the value of a global in the given instance.
523  static wasm::WasmValue GetGlobalValue(Handle<WasmInstanceObject>,
524                                        const wasm::WasmGlobal&);
525
526  OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
527
528 private:
529  static void InitDataSegmentArrays(Handle<WasmInstanceObject>,
530                                    Handle<WasmModuleObject>);
531  static void InitElemSegmentArrays(Handle<WasmInstanceObject>,
532                                    Handle<WasmModuleObject>);
533};
534
535// Representation of WebAssembly.Exception JavaScript-level object.
536class WasmTagObject
537    : public TorqueGeneratedWasmTagObject<WasmTagObject, JSObject> {
538 public:
539  // Checks whether the given {sig} has the same parameter types as the
540  // serialized signature stored within this tag object.
541  bool MatchesSignature(const wasm::FunctionSig* sig);
542
543  static Handle<WasmTagObject> New(Isolate* isolate,
544                                   const wasm::FunctionSig* sig,
545                                   Handle<HeapObject> tag);
546
547  TQ_OBJECT_CONSTRUCTORS(WasmTagObject)
548};
549
550// A Wasm exception that has been thrown out of Wasm code.
551class V8_EXPORT_PRIVATE WasmExceptionPackage : public JSObject {
552 public:
553  static Handle<WasmExceptionPackage> New(
554      Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
555      int encoded_size);
556
557  static Handle<WasmExceptionPackage> New(
558      Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
559      Handle<FixedArray> values);
560
561  // The below getters return {undefined} in case the given exception package
562  // does not carry the requested values (i.e. is of a different type).
563  static Handle<Object> GetExceptionTag(
564      Isolate* isolate, Handle<WasmExceptionPackage> exception_package);
565  static Handle<Object> GetExceptionValues(
566      Isolate* isolate, Handle<WasmExceptionPackage> exception_package);
567
568  // Determines the size of the array holding all encoded exception values.
569  static uint32_t GetEncodedSize(const wasm::WasmTag* tag);
570
571  DECL_CAST(WasmExceptionPackage)
572  OBJECT_CONSTRUCTORS(WasmExceptionPackage, JSObject);
573};
574
575void V8_EXPORT_PRIVATE EncodeI32ExceptionValue(
576    Handle<FixedArray> encoded_values, uint32_t* encoded_index, uint32_t value);
577
578void V8_EXPORT_PRIVATE EncodeI64ExceptionValue(
579    Handle<FixedArray> encoded_values, uint32_t* encoded_index, uint64_t value);
580
581void V8_EXPORT_PRIVATE
582DecodeI32ExceptionValue(Handle<FixedArray> encoded_values,
583                        uint32_t* encoded_index, uint32_t* value);
584
585void V8_EXPORT_PRIVATE
586DecodeI64ExceptionValue(Handle<FixedArray> encoded_values,
587                        uint32_t* encoded_index, uint64_t* value);
588
589// A Wasm function that is wrapped and exported to JavaScript.
590// Representation of WebAssembly.Function JavaScript-level object.
591class WasmExportedFunction : public JSFunction {
592 public:
593  WasmInstanceObject instance();
594  V8_EXPORT_PRIVATE int function_index();
595
596  V8_EXPORT_PRIVATE static bool IsWasmExportedFunction(Object object);
597
598  V8_EXPORT_PRIVATE static Handle<WasmExportedFunction> New(
599      Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index,
600      int arity, Handle<CodeT> export_wrapper);
601
602  Address GetWasmCallTarget();
603
604  V8_EXPORT_PRIVATE const wasm::FunctionSig* sig();
605
606  bool MatchesSignature(const wasm::WasmModule* other_module,
607                        const wasm::FunctionSig* other_sig);
608
609  // Return a null-terminated string with the debug name in the form
610  // 'js-to-wasm:<sig>'.
611  static std::unique_ptr<char[]> GetDebugName(const wasm::FunctionSig* sig);
612
613  DECL_CAST(WasmExportedFunction)
614  OBJECT_CONSTRUCTORS(WasmExportedFunction, JSFunction);
615};
616
617// A Wasm function that was created by wrapping a JavaScript callable.
618// Representation of WebAssembly.Function JavaScript-level object.
619class WasmJSFunction : public JSFunction {
620 public:
621  static bool IsWasmJSFunction(Object object);
622
623  static Handle<WasmJSFunction> New(Isolate* isolate,
624                                    const wasm::FunctionSig* sig,
625                                    Handle<JSReceiver> callable,
626                                    Handle<HeapObject> suspender);
627
628  JSReceiver GetCallable() const;
629  HeapObject GetSuspender() const;
630  // Deserializes the signature of this function using the provided zone. Note
631  // that lifetime of the signature is hence directly coupled to the zone.
632  const wasm::FunctionSig* GetSignature(Zone* zone);
633  bool MatchesSignature(const wasm::FunctionSig* sig);
634  // Special typing rule for imports wrapped by a Suspender.
635  bool MatchesSignatureForSuspend(const wasm::FunctionSig* sig);
636
637  DECL_CAST(WasmJSFunction)
638  OBJECT_CONSTRUCTORS(WasmJSFunction, JSFunction);
639};
640
641// An external function exposed to Wasm via the C/C++ API.
642class WasmCapiFunction : public JSFunction {
643 public:
644  static bool IsWasmCapiFunction(Object object);
645
646  static Handle<WasmCapiFunction> New(
647      Isolate* isolate, Address call_target, Handle<Foreign> embedder_data,
648      Handle<PodArray<wasm::ValueType>> serialized_signature);
649
650  PodArray<wasm::ValueType> GetSerializedSignature() const;
651  // Checks whether the given {sig} has the same parameter types as the
652  // serialized signature stored within this C-API function object.
653  bool MatchesSignature(const wasm::FunctionSig* sig) const;
654
655  DECL_CAST(WasmCapiFunction)
656  OBJECT_CONSTRUCTORS(WasmCapiFunction, JSFunction);
657};
658
659// Any external function that can be imported/exported in modules. This abstract
660// class just dispatches to the following concrete classes:
661//  - {WasmExportedFunction}: A proper Wasm function exported from a module.
662//  - {WasmJSFunction}: A function constructed via WebAssembly.Function in JS.
663// // TODO(wasm): Potentially {WasmCapiFunction} will be added here as well.
664class WasmExternalFunction : public JSFunction {
665 public:
666  static bool IsWasmExternalFunction(Object object);
667
668  DECL_CAST(WasmExternalFunction)
669  OBJECT_CONSTRUCTORS(WasmExternalFunction, JSFunction);
670};
671
672class WasmIndirectFunctionTable
673    : public TorqueGeneratedWasmIndirectFunctionTable<WasmIndirectFunctionTable,
674                                                      Struct> {
675 public:
676  DECL_PRIMITIVE_ACCESSORS(sig_ids, uint32_t*)
677  DECL_PRIMITIVE_ACCESSORS(targets, Address*)
678  DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign)
679
680  V8_EXPORT_PRIVATE static Handle<WasmIndirectFunctionTable> New(
681      Isolate* isolate, uint32_t size);
682  static void Resize(Isolate* isolate, Handle<WasmIndirectFunctionTable> table,
683                     uint32_t new_size);
684  V8_EXPORT_PRIVATE void Set(uint32_t index, int sig_id, Address call_target,
685                             Object ref);
686  void Clear(uint32_t index);
687
688  DECL_PRINTER(WasmIndirectFunctionTable)
689
690  STATIC_ASSERT(kStartOfStrongFieldsOffset == kManagedNativeAllocationsOffset);
691  using BodyDescriptor = FlexibleBodyDescriptor<kStartOfStrongFieldsOffset>;
692
693  TQ_OBJECT_CONSTRUCTORS(WasmIndirectFunctionTable)
694};
695
696class WasmFunctionData
697    : public TorqueGeneratedWasmFunctionData<WasmFunctionData, HeapObject> {
698 public:
699  DECL_ACCESSORS(internal, WasmInternalFunction)
700
701  DECL_PRINTER(WasmFunctionData)
702
703  using BodyDescriptor = FlexibleBodyDescriptor<kStartOfStrongFieldsOffset>;
704
705  TQ_OBJECT_CONSTRUCTORS(WasmFunctionData)
706};
707
708// Information for a WasmExportedFunction which is referenced as the function
709// data of the SharedFunctionInfo underlying the function. For details please
710// see the {SharedFunctionInfo::HasWasmExportedFunctionData} predicate.
711class WasmExportedFunctionData
712    : public TorqueGeneratedWasmExportedFunctionData<WasmExportedFunctionData,
713                                                     WasmFunctionData> {
714 public:
715  inline wasm::FunctionSig* sig() const;
716
717  // Dispatched behavior.
718  DECL_PRINTER(WasmExportedFunctionData)
719  DECL_VERIFIER(WasmExportedFunctionData)
720
721  using BodyDescriptor =
722      FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
723
724  TQ_OBJECT_CONSTRUCTORS(WasmExportedFunctionData)
725};
726
727class WasmApiFunctionRef
728    : public TorqueGeneratedWasmApiFunctionRef<WasmApiFunctionRef, HeapObject> {
729 public:
730  // Dispatched behavior.
731  DECL_PRINTER(WasmApiFunctionRef)
732
733  class BodyDescriptor;
734
735  TQ_OBJECT_CONSTRUCTORS(WasmApiFunctionRef)
736};
737
738class WasmInternalFunction
739    : public TorqueGeneratedWasmInternalFunction<WasmInternalFunction,
740                                                 Foreign> {
741 public:
742  // Returns a handle to the corresponding WasmInternalFunction if {external} is
743  // a WasmExternalFunction, or an empty handle otherwise.
744  static MaybeHandle<WasmInternalFunction> FromExternal(Handle<Object> external,
745                                                        Isolate* isolate);
746
747  // Dispatched behavior.
748  DECL_PRINTER(WasmInternalFunction)
749
750  class BodyDescriptor;
751
752  TQ_OBJECT_CONSTRUCTORS(WasmInternalFunction)
753};
754
755// Information for a WasmJSFunction which is referenced as the function data of
756// the SharedFunctionInfo underlying the function. For details please see the
757// {SharedFunctionInfo::HasWasmJSFunctionData} predicate.
758class WasmJSFunctionData
759    : public TorqueGeneratedWasmJSFunctionData<WasmJSFunctionData,
760                                               WasmFunctionData> {
761 public:
762  DECL_ACCESSORS(wasm_to_js_wrapper_code, CodeT)
763
764  // Dispatched behavior.
765  DECL_PRINTER(WasmJSFunctionData)
766
767  using BodyDescriptor =
768      FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
769
770 private:
771  TQ_OBJECT_CONSTRUCTORS(WasmJSFunctionData)
772};
773
774class WasmCapiFunctionData
775    : public TorqueGeneratedWasmCapiFunctionData<WasmCapiFunctionData,
776                                                 WasmFunctionData> {
777 public:
778  DECL_PRINTER(WasmCapiFunctionData)
779
780  using BodyDescriptor =
781      FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
782
783  TQ_OBJECT_CONSTRUCTORS(WasmCapiFunctionData)
784};
785
786class WasmOnFulfilledData
787    : public TorqueGeneratedWasmOnFulfilledData<WasmOnFulfilledData,
788                                                HeapObject> {
789 public:
790  using BodyDescriptor =
791      FlexibleBodyDescriptor<WasmOnFulfilledData::kStartOfStrongFieldsOffset>;
792  DECL_PRINTER(WasmOnFulfilledData)
793  TQ_OBJECT_CONSTRUCTORS(WasmOnFulfilledData)
794};
795
796class WasmScript : public AllStatic {
797 public:
798  // Position used for storing "on entry" breakpoints (a.k.a. instrumentation
799  // breakpoints). This would be an illegal position for any other breakpoint.
800  static constexpr int kOnEntryBreakpointPosition = -1;
801
802  // Set a breakpoint on the given byte position inside the given module.
803  // This will affect all live and future instances of the module.
804  // The passed position might be modified to point to the next breakable
805  // location inside the same function.
806  // If it points outside a function, or behind the last breakable location,
807  // this function returns false and does not set any breakpoint.
808  V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<Script>, int* position,
809                                              Handle<BreakPoint> break_point);
810
811  // Set an "on entry" breakpoint (a.k.a. instrumentation breakpoint) inside
812  // the given module. This will affect all live and future instances of the
813  // module.
814  V8_EXPORT_PRIVATE static void SetInstrumentationBreakpoint(
815      Handle<Script>, Handle<BreakPoint> break_point);
816
817  // Set a breakpoint on first breakable position of the given function index
818  // inside the given module. This will affect all live and future instances of
819  // the module.
820  V8_EXPORT_PRIVATE static bool SetBreakPointOnFirstBreakableForFunction(
821      Handle<Script>, int function_index, Handle<BreakPoint> break_point);
822
823  // Set a breakpoint at the breakable offset of the given function index
824  // inside the given module. This will affect all live and future instances of
825  // the module.
826  V8_EXPORT_PRIVATE static bool SetBreakPointForFunction(
827      Handle<Script>, int function_index, int breakable_offset,
828      Handle<BreakPoint> break_point);
829
830  // Remove a previously set breakpoint at the given byte position inside the
831  // given module. If this breakpoint is not found this function returns false.
832  V8_EXPORT_PRIVATE static bool ClearBreakPoint(Handle<Script>, int position,
833                                                Handle<BreakPoint> break_point);
834
835  // Remove a previously set breakpoint by id. If this breakpoint is not found,
836  // returns false.
837  V8_EXPORT_PRIVATE static bool ClearBreakPointById(Handle<Script>,
838                                                    int breakpoint_id);
839
840  // Remove all set breakpoints.
841  static void ClearAllBreakpoints(Script);
842
843  // Get a list of all possible breakpoints within a given range of this module.
844  V8_EXPORT_PRIVATE static bool GetPossibleBreakpoints(
845      wasm::NativeModule* native_module, const debug::Location& start,
846      const debug::Location& end, std::vector<debug::BreakLocation>* locations);
847
848  // Return an empty handle if no breakpoint is hit at that location, or a
849  // FixedArray with all hit breakpoint objects.
850  static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, Handle<Script>,
851                                                  int position,
852                                                  StackFrameId stack_frame_id);
853
854 private:
855  // Helper functions that update the breakpoint info list.
856  static void AddBreakpointToInfo(Handle<Script>, int position,
857                                  Handle<BreakPoint> break_point);
858};
859
860// Tags provide an object identity for each exception defined in a wasm module
861// header. They are referenced by the following fields:
862//  - {WasmTagObject::tag}: The tag of the {Tag} object.
863//  - {WasmInstanceObject::tags_table}: List of tags used by an instance.
864class WasmExceptionTag
865    : public TorqueGeneratedWasmExceptionTag<WasmExceptionTag, Struct> {
866 public:
867  V8_EXPORT_PRIVATE static Handle<WasmExceptionTag> New(Isolate* isolate,
868                                                        int index);
869
870  using BodyDescriptor = StructBodyDescriptor;
871
872  TQ_OBJECT_CONSTRUCTORS(WasmExceptionTag)
873};
874
875// Data annotated to the asm.js Module function. Used for later instantiation of
876// that function.
877class AsmWasmData : public TorqueGeneratedAsmWasmData<AsmWasmData, Struct> {
878 public:
879  static Handle<AsmWasmData> New(
880      Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
881      Handle<FixedArray> export_wrappers, Handle<HeapNumber> uses_bitset);
882
883  DECL_PRINTER(AsmWasmData)
884
885  using BodyDescriptor = StructBodyDescriptor;
886
887  TQ_OBJECT_CONSTRUCTORS(AsmWasmData)
888};
889
890class WasmTypeInfo : public TorqueGeneratedWasmTypeInfo<WasmTypeInfo, Foreign> {
891 public:
892  inline void clear_foreign_address(Isolate* isolate);
893
894  DECL_PRINTER(WasmTypeInfo)
895
896  class BodyDescriptor;
897
898  TQ_OBJECT_CONSTRUCTORS(WasmTypeInfo)
899};
900
901class WasmObject : public TorqueGeneratedWasmObject<WasmObject, JSReceiver> {
902 public:
903  // Prepares given value for being stored into a field of given Wasm type.
904  V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToWasmValue(
905      Isolate* isolate, wasm::ValueType type, Handle<Object> value);
906
907 protected:
908  // Returns boxed value of the object's field/element with given type and
909  // offset.
910  static inline Handle<Object> ReadValueAt(Isolate* isolate,
911                                           Handle<HeapObject> obj,
912                                           wasm::ValueType type,
913                                           uint32_t offset);
914
915  static inline void WriteValueAt(Isolate* isolate, Handle<HeapObject> obj,
916                                  wasm::ValueType type, uint32_t offset,
917                                  Handle<Object> value);
918
919 private:
920  template <typename ElementType>
921  static ElementType FromNumber(Object value);
922
923  TQ_OBJECT_CONSTRUCTORS(WasmObject)
924};
925
926class WasmStruct : public TorqueGeneratedWasmStruct<WasmStruct, WasmObject> {
927 public:
928  static inline wasm::StructType* type(Map map);
929  inline wasm::StructType* type() const;
930  static inline wasm::StructType* GcSafeType(Map map);
931  static inline int Size(const wasm::StructType* type);
932  static inline int GcSafeSize(Map map);
933  static inline void EncodeInstanceSizeInMap(int instance_size, Map map);
934  static inline int DecodeInstanceSizeFromMap(Map map);
935
936  // Returns the address of the field at given offset.
937  inline Address RawFieldAddress(int raw_offset);
938
939  // Returns the ObjectSlot for tagged value at given offset.
940  inline ObjectSlot RawField(int raw_offset);
941
942  wasm::WasmValue GetFieldValue(uint32_t field_index);
943
944  // Returns boxed value of the object's field.
945  static inline Handle<Object> GetField(Isolate* isolate,
946                                        Handle<WasmStruct> obj,
947                                        uint32_t field_index);
948
949  static inline void SetField(Isolate* isolate, Handle<WasmStruct> obj,
950                              uint32_t field_index, Handle<Object> value);
951
952  DECL_PRINTER(WasmStruct)
953
954  class BodyDescriptor;
955
956  TQ_OBJECT_CONSTRUCTORS(WasmStruct)
957};
958
959class WasmArray : public TorqueGeneratedWasmArray<WasmArray, WasmObject> {
960 public:
961  static inline wasm::ArrayType* type(Map map);
962  inline wasm::ArrayType* type() const;
963  static inline wasm::ArrayType* GcSafeType(Map map);
964
965  // Get the {ObjectSlot} corresponding to the element at {index}. Requires that
966  // this is a reference array.
967  inline ObjectSlot ElementSlot(uint32_t index);
968  V8_EXPORT_PRIVATE wasm::WasmValue GetElement(uint32_t index);
969
970  static inline int SizeFor(Map map, int length);
971
972  // Returns boxed value of the array's element.
973  static inline Handle<Object> GetElement(Isolate* isolate,
974                                          Handle<WasmArray> array,
975                                          uint32_t index);
976
977  // Returns the offset/Address of the element at {index}.
978  inline uint32_t element_offset(uint32_t index);
979  inline Address ElementAddress(uint32_t index);
980
981  static int MaxLength(uint32_t element_size_bytes) {
982    // The total object size must fit into a Smi, for filler objects. To make
983    // the behavior of Wasm programs independent from the Smi configuration,
984    // we hard-code the smaller of the two supported ranges.
985    return (SmiTagging<4>::kSmiMaxValue - kHeaderSize) / element_size_bytes;
986  }
987
988  static int MaxLength(const wasm::ArrayType* type) {
989    return MaxLength(type->element_type().value_kind_size());
990  }
991
992  static inline void EncodeElementSizeInMap(int element_size, Map map);
993  static inline int DecodeElementSizeFromMap(Map map);
994
995  DECL_PRINTER(WasmArray)
996
997  class BodyDescriptor;
998
999  TQ_OBJECT_CONSTRUCTORS(WasmArray)
1000};
1001
1002// A wasm delimited continuation.
1003class WasmContinuationObject
1004    : public TorqueGeneratedWasmContinuationObject<WasmContinuationObject,
1005                                                   Struct> {
1006 public:
1007  static Handle<WasmContinuationObject> New(
1008      Isolate* isolate, std::unique_ptr<wasm::StackMemory> stack);
1009  static Handle<WasmContinuationObject> New(
1010      Isolate* isolate, Handle<WasmContinuationObject> parent);
1011
1012  DECL_PRINTER(WasmContinuationObject)
1013
1014  using BodyDescriptor = StructBodyDescriptor;
1015
1016 private:
1017  static Handle<WasmContinuationObject> New(
1018      Isolate* isolate, std::unique_ptr<wasm::StackMemory> stack,
1019      Handle<HeapObject> parent);
1020
1021  TQ_OBJECT_CONSTRUCTORS(WasmContinuationObject)
1022};
1023
1024// The suspender object provides an API to suspend and resume wasm code using
1025// promises. See: https://github.com/WebAssembly/js-promise-integration.
1026class WasmSuspenderObject
1027    : public TorqueGeneratedWasmSuspenderObject<WasmSuspenderObject, JSObject> {
1028 public:
1029  enum State : int { Inactive = 0, Active, Suspended };
1030  static Handle<WasmSuspenderObject> New(Isolate* isolate);
1031  // TODO(thibaudm): returnPromiseOnSuspend & suspendOnReturnedPromise.
1032  DECL_PRINTER(WasmSuspenderObject)
1033  TQ_OBJECT_CONSTRUCTORS(WasmSuspenderObject)
1034};
1035
1036#undef DECL_OPTIONAL_ACCESSORS
1037
1038namespace wasm {
1039bool TypecheckJSObject(Isolate* isolate, const WasmModule* module,
1040                       Handle<Object> value, ValueType expected,
1041                       const char** error_message);
1042}  // namespace wasm
1043
1044}  // namespace internal
1045}  // namespace v8
1046
1047#include "src/objects/object-macros-undef.h"
1048
1049#endif  // V8_WASM_WASM_OBJECTS_H_
1050