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