| // Copyright 2016 the V8 project authors. All rights reserved. Use of |
| // this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_WASM_WASM_OBJECTS_H_ |
| #define V8_WASM_WASM_OBJECTS_H_ |
| |
| #include <memory> |
| |
| #include "src/base/bit-field.h" |
| #include "src/base/bits.h" |
| #include "src/codegen/signature.h" |
| #include "src/debug/debug.h" |
| #include "src/heap/heap.h" |
| #include "src/objects/js-function.h" |
| #include "src/objects/objects.h" |
| #include "src/wasm/struct-types.h" |
| #include "src/wasm/value-type.h" |
| |
| // Has to be the last include (doesn't have include guards) |
| #include "src/objects/object-macros.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace wasm { |
| class InterpretedFrame; |
| class NativeModule; |
| class WasmCode; |
| struct WasmException; |
| struct WasmGlobal; |
| struct WasmModule; |
| class WasmValue; |
| class WireBytesRef; |
| } // namespace wasm |
| |
| class BreakPoint; |
| class JSArrayBuffer; |
| class SeqOneByteString; |
| class WasmCapiFunction; |
| class WasmExceptionTag; |
| class WasmExportedFunction; |
| class WasmExternalFunction; |
| class WasmInstanceObject; |
| class WasmJSFunction; |
| class WasmModuleObject; |
| |
| enum class SharedFlag : uint8_t; |
| |
| template <class CppType> |
| class Managed; |
| |
| #include "torque-generated/src/wasm/wasm-objects-tq.inc" |
| |
| #define DECL_OPTIONAL_ACCESSORS(name, type) \ |
| DECL_GETTER(has_##name, bool) \ |
| DECL_ACCESSORS(name, type) |
| |
| // A helper for an entry in an indirect function table (IFT). |
| // The underlying storage in the instance is used by generated code to |
| // call functions indirectly at runtime. |
| // Each entry has the following fields: |
| // - object = target instance, if a Wasm function, tuple if imported |
| // - sig_id = signature id of function |
| // - target = entrypoint to Wasm code or import wrapper code |
| class V8_EXPORT_PRIVATE IndirectFunctionTableEntry { |
| public: |
| inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int table_index, |
| int entry_index); |
| |
| inline IndirectFunctionTableEntry(Handle<WasmIndirectFunctionTable> table, |
| int entry_index); |
| |
| void clear(); |
| void Set(int sig_id, Handle<WasmInstanceObject> target_instance, |
| int target_func_index); |
| void Set(int sig_id, Address call_target, Object ref); |
| |
| Object object_ref() const; |
| int sig_id() const; |
| Address target() const; |
| |
| private: |
| Handle<WasmInstanceObject> const instance_; |
| Handle<WasmIndirectFunctionTable> const table_; |
| int const index_; |
| }; |
| |
| // A helper for an entry for an imported function, indexed statically. |
| // The underlying storage in the instance is used by generated code to |
| // call imported functions at runtime. |
| // Each entry is either: |
| // - Wasm to JS, which has fields |
| // - object = a Tuple2 of the importing instance and the callable |
| // - target = entrypoint to import wrapper code |
| // - Wasm to Wasm, which has fields |
| // - object = target instance |
| // - target = entrypoint for the function |
| class ImportedFunctionEntry { |
| public: |
| inline ImportedFunctionEntry(Handle<WasmInstanceObject>, int index); |
| |
| // Initialize this entry as a Wasm to JS call. This accepts the isolate as a |
| // parameter, since it must allocate a tuple. |
| V8_EXPORT_PRIVATE void SetWasmToJs(Isolate*, Handle<JSReceiver> callable, |
| const wasm::WasmCode* wasm_to_js_wrapper); |
| // Initialize this entry as a Wasm to Wasm call. |
| void SetWasmToWasm(WasmInstanceObject target_instance, Address call_target); |
| |
| WasmInstanceObject instance(); |
| JSReceiver callable(); |
| Object maybe_callable(); |
| Object object_ref(); |
| Address target(); |
| |
| private: |
| Handle<WasmInstanceObject> const instance_; |
| int const index_; |
| }; |
| |
| enum InternalizeString : bool { kInternalize = true, kNoInternalize = false }; |
| |
| // Representation of a WebAssembly.Module JavaScript-level object. |
| class WasmModuleObject : public JSObject { |
| public: |
| DECL_CAST(WasmModuleObject) |
| |
| DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>) |
| DECL_ACCESSORS(export_wrappers, FixedArray) |
| DECL_ACCESSORS(script, Script) |
| inline wasm::NativeModule* native_module() const; |
| inline const std::shared_ptr<wasm::NativeModule>& shared_native_module() |
| const; |
| inline const wasm::WasmModule* module() const; |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmModuleObject) |
| DECL_VERIFIER(WasmModuleObject) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_MODULE_OBJECT_FIELDS) |
| |
| // Creates a new {WasmModuleObject} for an existing {NativeModule} that is |
| // reference counted and might be shared between multiple Isolates. |
| V8_EXPORT_PRIVATE static Handle<WasmModuleObject> New( |
| Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module, |
| Handle<Script> script); |
| V8_EXPORT_PRIVATE static Handle<WasmModuleObject> New( |
| Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module, |
| Handle<Script> script, Handle<FixedArray> export_wrappers); |
| |
| // Check whether this module was generated from asm.js source. |
| inline bool is_asm_js(); |
| |
| // Get the module name, if set. Returns an empty handle otherwise. |
| static MaybeHandle<String> GetModuleNameOrNull(Isolate*, |
| Handle<WasmModuleObject>); |
| |
| // Get the function name of the function identified by the given index. |
| // Returns a null handle if the function is unnamed or the name is not a valid |
| // UTF-8 string. |
| static MaybeHandle<String> GetFunctionNameOrNull(Isolate*, |
| Handle<WasmModuleObject>, |
| uint32_t func_index); |
| |
| // Get the function name of the function identified by the given index. |
| // Returns "func[func_index]" if the function is unnamed or the |
| // name is not a valid UTF-8 string. |
| static Handle<String> GetFunctionName(Isolate*, Handle<WasmModuleObject>, |
| uint32_t func_index); |
| |
| // Get the raw bytes of the function name of the function identified by the |
| // given index. |
| // Meant to be used for debugging or frame printing. |
| // Does not allocate, hence gc-safe. |
| Vector<const uint8_t> GetRawFunctionName(uint32_t func_index); |
| |
| // Extract a portion of the wire bytes as UTF-8 string, optionally |
| // internalized. (Prefer to internalize early if the string will be used for a |
| // property lookup anyway.) |
| static Handle<String> ExtractUtf8StringFromModuleBytes( |
| Isolate*, Handle<WasmModuleObject>, wasm::WireBytesRef, |
| InternalizeString); |
| static Handle<String> ExtractUtf8StringFromModuleBytes( |
| Isolate*, Vector<const uint8_t> wire_byte, wasm::WireBytesRef, |
| InternalizeString); |
| |
| OBJECT_CONSTRUCTORS(WasmModuleObject, JSObject); |
| }; |
| |
| // Representation of a WebAssembly.Table JavaScript-level object. |
| class V8_EXPORT_PRIVATE WasmTableObject : public JSObject { |
| public: |
| DECL_CAST(WasmTableObject) |
| |
| // The instance in which this WasmTableObject is defined. |
| // This field is undefined if the global is defined outside any Wasm module, |
| // i.e., through the JS API (WebAssembly.Table). |
| // Because it might be undefined, we declare it as a HeapObject. |
| DECL_ACCESSORS(instance, HeapObject) |
| // The entries array is at least as big as {current_length()}, but might be |
| // bigger to make future growth more efficient. |
| DECL_ACCESSORS(entries, FixedArray) |
| DECL_INT_ACCESSORS(current_length) |
| // TODO(titzer): introduce DECL_I64_ACCESSORS macro |
| DECL_ACCESSORS(maximum_length, Object) |
| DECL_ACCESSORS(dispatch_tables, FixedArray) |
| DECL_INT_ACCESSORS(raw_type) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmTableObject) |
| DECL_VERIFIER(WasmTableObject) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_TABLE_OBJECT_FIELDS) |
| |
| inline wasm::ValueType type(); |
| |
| static int Grow(Isolate* isolate, Handle<WasmTableObject> table, |
| uint32_t count, Handle<Object> init_value); |
| |
| static Handle<WasmTableObject> New(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| wasm::ValueType type, uint32_t initial, |
| bool has_maximum, uint32_t maximum, |
| Handle<FixedArray>* entries); |
| |
| static void AddDispatchTable(Isolate* isolate, Handle<WasmTableObject> table, |
| Handle<WasmInstanceObject> instance, |
| int table_index); |
| |
| static bool IsInBounds(Isolate* isolate, Handle<WasmTableObject> table, |
| uint32_t entry_index); |
| |
| static bool IsValidElement(Isolate* isolate, Handle<WasmTableObject> table, |
| Handle<Object> entry); |
| |
| static void Set(Isolate* isolate, Handle<WasmTableObject> table, |
| uint32_t index, Handle<Object> entry); |
| |
| static Handle<Object> Get(Isolate* isolate, Handle<WasmTableObject> table, |
| uint32_t index); |
| |
| static void Fill(Isolate* isolate, Handle<WasmTableObject> table, |
| uint32_t start, Handle<Object> entry, uint32_t count); |
| |
| // TODO(wasm): Unify these three methods into one. |
| static void UpdateDispatchTables(Isolate* isolate, |
| Handle<WasmTableObject> table, |
| int entry_index, |
| const wasm::FunctionSig* sig, |
| Handle<WasmInstanceObject> target_instance, |
| int target_func_index); |
| static void UpdateDispatchTables(Isolate* isolate, |
| Handle<WasmTableObject> table, |
| int entry_index, |
| Handle<WasmJSFunction> function); |
| static void UpdateDispatchTables(Isolate* isolate, |
| Handle<WasmTableObject> table, |
| int entry_index, |
| Handle<WasmCapiFunction> capi_function); |
| |
| static void ClearDispatchTables(Isolate* isolate, |
| Handle<WasmTableObject> table, int index); |
| |
| static void SetFunctionTablePlaceholder(Isolate* isolate, |
| Handle<WasmTableObject> table, |
| int entry_index, |
| Handle<WasmInstanceObject> instance, |
| int func_index); |
| |
| // This function reads the content of a function table entry and returns it |
| // through the out parameters {is_valid}, {is_null}, {instance}, |
| // {function_index}, and {maybe_js_function}. |
| static void GetFunctionTableEntry( |
| Isolate* isolate, const wasm::WasmModule* module, |
| Handle<WasmTableObject> table, int entry_index, bool* is_valid, |
| bool* is_null, MaybeHandle<WasmInstanceObject>* instance, |
| int* function_index, MaybeHandle<WasmJSFunction>* maybe_js_function); |
| |
| private: |
| static void SetFunctionTableEntry(Isolate* isolate, |
| Handle<WasmTableObject> table, |
| Handle<FixedArray> entries, int entry_index, |
| Handle<Object> entry); |
| |
| OBJECT_CONSTRUCTORS(WasmTableObject, JSObject); |
| }; |
| |
| // Representation of a WebAssembly.Memory JavaScript-level object. |
| class WasmMemoryObject : public JSObject { |
| public: |
| DECL_CAST(WasmMemoryObject) |
| |
| DECL_ACCESSORS(array_buffer, JSArrayBuffer) |
| DECL_INT_ACCESSORS(maximum_pages) |
| DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmMemoryObject) |
| DECL_VERIFIER(WasmMemoryObject) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_MEMORY_OBJECT_FIELDS) |
| |
| // Add an instance to the internal (weak) list. |
| V8_EXPORT_PRIVATE static void AddInstance(Isolate* isolate, |
| Handle<WasmMemoryObject> memory, |
| Handle<WasmInstanceObject> object); |
| inline bool has_maximum_pages(); |
| |
| V8_EXPORT_PRIVATE static Handle<WasmMemoryObject> New( |
| Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, uint32_t maximum); |
| |
| V8_EXPORT_PRIVATE static MaybeHandle<WasmMemoryObject> New(Isolate* isolate, |
| uint32_t initial, |
| uint32_t maximum, |
| SharedFlag shared); |
| |
| void update_instances(Isolate* isolate, Handle<JSArrayBuffer> buffer); |
| |
| V8_EXPORT_PRIVATE static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, |
| uint32_t pages); |
| |
| OBJECT_CONSTRUCTORS(WasmMemoryObject, JSObject); |
| }; |
| |
| // Representation of a WebAssembly.Global JavaScript-level object. |
| class WasmGlobalObject : public JSObject { |
| public: |
| DECL_CAST(WasmGlobalObject) |
| |
| // The instance in which this WasmGlobalObject is defined. |
| // This field is undefined if the global is defined outside any Wasm module, |
| // i.e., through the JS API (WebAssembly.Global). |
| // Because it might be undefined, we declare it as a HeapObject. |
| DECL_ACCESSORS(instance, HeapObject) |
| DECL_ACCESSORS(untagged_buffer, JSArrayBuffer) |
| DECL_ACCESSORS(tagged_buffer, FixedArray) |
| DECL_INT32_ACCESSORS(offset) |
| DECL_INT_ACCESSORS(raw_type) |
| DECL_PRIMITIVE_ACCESSORS(type, wasm::ValueType) |
| // TODO(7748): Once we improve the encoding of mutability/type, turn this back |
| // into a boolean accessor. |
| DECL_INT_ACCESSORS(is_mutable) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmGlobalObject) |
| DECL_VERIFIER(WasmGlobalObject) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_GLOBAL_OBJECT_FIELDS) |
| |
| V8_EXPORT_PRIVATE static MaybeHandle<WasmGlobalObject> New( |
| Isolate* isolate, Handle<WasmInstanceObject> instance, |
| MaybeHandle<JSArrayBuffer> maybe_untagged_buffer, |
| MaybeHandle<FixedArray> maybe_tagged_buffer, wasm::ValueType type, |
| int32_t offset, bool is_mutable); |
| |
| inline int type_size() const; |
| |
| inline int32_t GetI32(); |
| inline int64_t GetI64(); |
| inline float GetF32(); |
| inline double GetF64(); |
| inline Handle<Object> GetRef(); |
| |
| inline void SetI32(int32_t value); |
| inline void SetI64(int64_t value); |
| inline void SetF32(float value); |
| inline void SetF64(double value); |
| inline void SetExternRef(Handle<Object> value); |
| inline bool SetFuncRef(Isolate* isolate, Handle<Object> value); |
| |
| private: |
| // This function returns the address of the global's data in the |
| // JSArrayBuffer. This buffer may be allocated on-heap, in which case it may |
| // not have a fixed address. |
| inline Address address() const; |
| |
| OBJECT_CONSTRUCTORS(WasmGlobalObject, JSObject); |
| }; |
| |
| // Representation of a WebAssembly.Instance JavaScript-level object. |
| class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject { |
| public: |
| DECL_CAST(WasmInstanceObject) |
| |
| DECL_ACCESSORS(module_object, WasmModuleObject) |
| DECL_ACCESSORS(exports_object, JSObject) |
| DECL_ACCESSORS(native_context, Context) |
| DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject) |
| DECL_OPTIONAL_ACCESSORS(untagged_globals_buffer, JSArrayBuffer) |
| DECL_OPTIONAL_ACCESSORS(tagged_globals_buffer, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(imported_mutable_globals_buffers, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(tables, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(indirect_function_tables, FixedArray) |
| DECL_ACCESSORS(imported_function_refs, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(indirect_function_table_refs, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign) |
| DECL_OPTIONAL_ACCESSORS(exceptions_table, FixedArray) |
| DECL_OPTIONAL_ACCESSORS(wasm_external_functions, FixedArray) |
| DECL_ACCESSORS(managed_object_maps, FixedArray) |
| DECL_PRIMITIVE_ACCESSORS(memory_start, byte*) |
| DECL_PRIMITIVE_ACCESSORS(memory_size, size_t) |
| DECL_PRIMITIVE_ACCESSORS(memory_mask, size_t) |
| DECL_PRIMITIVE_ACCESSORS(isolate_root, Address) |
| DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address) |
| DECL_PRIMITIVE_ACCESSORS(real_stack_limit_address, Address) |
| DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*) |
| DECL_PRIMITIVE_ACCESSORS(globals_start, byte*) |
| DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*) |
| DECL_PRIMITIVE_ACCESSORS(indirect_function_table_size, uint32_t) |
| DECL_PRIMITIVE_ACCESSORS(indirect_function_table_sig_ids, uint32_t*) |
| DECL_PRIMITIVE_ACCESSORS(indirect_function_table_targets, Address*) |
| DECL_PRIMITIVE_ACCESSORS(jump_table_start, Address) |
| DECL_PRIMITIVE_ACCESSORS(data_segment_starts, Address*) |
| DECL_PRIMITIVE_ACCESSORS(data_segment_sizes, uint32_t*) |
| DECL_PRIMITIVE_ACCESSORS(dropped_elem_segments, byte*) |
| DECL_PRIMITIVE_ACCESSORS(hook_on_function_call_address, Address) |
| DECL_PRIMITIVE_ACCESSORS(num_liftoff_function_calls_array, uint32_t*) |
| |
| // Clear uninitialized padding space. This ensures that the snapshot content |
| // is deterministic. Depending on the V8 build mode there could be no padding. |
| V8_INLINE void clear_padding(); |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmInstanceObject) |
| DECL_VERIFIER(WasmInstanceObject) |
| |
| // Layout description. |
| #define WASM_INSTANCE_OBJECT_FIELDS(V) \ |
| /* Often-accessed fields go first to minimize generated code size. */ \ |
| V(kMemoryStartOffset, kSystemPointerSize) \ |
| V(kMemorySizeOffset, kSizetSize) \ |
| V(kMemoryMaskOffset, kSizetSize) \ |
| V(kStackLimitAddressOffset, kSystemPointerSize) \ |
| V(kImportedFunctionRefsOffset, kTaggedSize) \ |
| V(kImportedFunctionTargetsOffset, kSystemPointerSize) \ |
| V(kIndirectFunctionTableRefsOffset, kTaggedSize) \ |
| V(kIndirectFunctionTableTargetsOffset, kSystemPointerSize) \ |
| V(kIndirectFunctionTableSigIdsOffset, kSystemPointerSize) \ |
| V(kIndirectFunctionTableSizeOffset, kUInt32Size) \ |
| /* Optional padding to align system pointer size fields */ \ |
| V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \ |
| V(kGlobalsStartOffset, kSystemPointerSize) \ |
| V(kImportedMutableGlobalsOffset, kSystemPointerSize) \ |
| V(kIsolateRootOffset, kSystemPointerSize) \ |
| V(kJumpTableStartOffset, kSystemPointerSize) \ |
| /* End of often-accessed fields. */ \ |
| V(kModuleObjectOffset, kTaggedSize) \ |
| V(kExportsObjectOffset, kTaggedSize) \ |
| V(kNativeContextOffset, kTaggedSize) \ |
| V(kMemoryObjectOffset, kTaggedSize) \ |
| V(kUntaggedGlobalsBufferOffset, kTaggedSize) \ |
| V(kTaggedGlobalsBufferOffset, kTaggedSize) \ |
| V(kImportedMutableGlobalsBuffersOffset, kTaggedSize) \ |
| V(kTablesOffset, kTaggedSize) \ |
| V(kIndirectFunctionTablesOffset, kTaggedSize) \ |
| V(kManagedNativeAllocationsOffset, kTaggedSize) \ |
| V(kExceptionsTableOffset, kTaggedSize) \ |
| V(kWasmExternalFunctionsOffset, kTaggedSize) \ |
| V(kManagedObjectMapsOffset, kTaggedSize) \ |
| V(kRealStackLimitAddressOffset, kSystemPointerSize) \ |
| V(kDataSegmentStartsOffset, kSystemPointerSize) \ |
| V(kDataSegmentSizesOffset, kSystemPointerSize) \ |
| V(kDroppedElemSegmentsOffset, kSystemPointerSize) \ |
| V(kHookOnFunctionCallAddressOffset, kSystemPointerSize) \ |
| V(kNumLiftoffFunctionCallsArrayOffset, kSystemPointerSize) \ |
| V(kHeaderSize, 0) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| WASM_INSTANCE_OBJECT_FIELDS) |
| STATIC_ASSERT(IsAligned(kHeaderSize, kTaggedSize)); |
| // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size |
| // fields (external pointers, doubles and BigInt data) are only kTaggedSize |
| // aligned so checking for alignments of fields bigger than kTaggedSize |
| // doesn't make sense until v8:8875 is fixed. |
| #define ASSERT_FIELD_ALIGNED(offset, size) \ |
| STATIC_ASSERT(size == 0 || IsAligned(offset, size) || \ |
| (COMPRESS_POINTERS_BOOL && (size == kSystemPointerSize) && \ |
| IsAligned(offset, kTaggedSize))); |
| WASM_INSTANCE_OBJECT_FIELDS(ASSERT_FIELD_ALIGNED) |
| #undef ASSERT_FIELD_ALIGNED |
| #undef WASM_INSTANCE_OBJECT_FIELDS |
| |
| static constexpr uint16_t kTaggedFieldOffsets[] = { |
| kImportedFunctionRefsOffset, |
| kIndirectFunctionTableRefsOffset, |
| kModuleObjectOffset, |
| kExportsObjectOffset, |
| kNativeContextOffset, |
| kMemoryObjectOffset, |
| kUntaggedGlobalsBufferOffset, |
| kTaggedGlobalsBufferOffset, |
| kImportedMutableGlobalsBuffersOffset, |
| kTablesOffset, |
| kIndirectFunctionTablesOffset, |
| kManagedNativeAllocationsOffset, |
| kExceptionsTableOffset, |
| kWasmExternalFunctionsOffset, |
| kManagedObjectMapsOffset}; |
| |
| const wasm::WasmModule* module(); |
| |
| static bool EnsureIndirectFunctionTableWithMinimumSize( |
| Handle<WasmInstanceObject> instance, int table_index, |
| uint32_t minimum_size); |
| |
| void SetRawMemory(byte* mem_start, size_t mem_size); |
| |
| static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmModuleObject>); |
| |
| Address GetCallTarget(uint32_t func_index); |
| |
| static int IndirectFunctionTableSize(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| uint32_t table_index); |
| |
| // Copies table entries. Returns {false} if the ranges are out-of-bounds. |
| static bool CopyTableEntries(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| uint32_t table_dst_index, |
| uint32_t table_src_index, uint32_t dst, |
| uint32_t src, |
| uint32_t count) V8_WARN_UNUSED_RESULT; |
| |
| // Copy table entries from an element segment. Returns {false} if the ranges |
| // are out-of-bounds. |
| static bool InitTableEntries(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| uint32_t table_index, uint32_t segment_index, |
| uint32_t dst, uint32_t src, |
| uint32_t count) V8_WARN_UNUSED_RESULT; |
| |
| // Iterates all fields in the object except the untagged fields. |
| class BodyDescriptor; |
| |
| static MaybeHandle<WasmExternalFunction> GetWasmExternalFunction( |
| Isolate* isolate, Handle<WasmInstanceObject> instance, int index); |
| |
| // Acquires the {WasmExternalFunction} for a given {function_index} from the |
| // cache of the given {instance}, or creates a new {WasmExportedFunction} if |
| // it does not exist yet. The new {WasmExportedFunction} is added to the |
| // cache of the {instance} immediately. |
| static Handle<WasmExternalFunction> GetOrCreateWasmExternalFunction( |
| Isolate* isolate, Handle<WasmInstanceObject> instance, |
| int function_index); |
| |
| static void SetWasmExternalFunction(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| int index, |
| Handle<WasmExternalFunction> val); |
| |
| // Imports a constructed {WasmJSFunction} into the indirect function table of |
| // this instance. Note that this might trigger wrapper compilation, since a |
| // {WasmJSFunction} is instance-independent and just wraps a JS callable. |
| static void ImportWasmJSFunctionIntoTable(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, |
| int table_index, int entry_index, |
| Handle<WasmJSFunction> js_function); |
| |
| // Get a raw pointer to the location where the given global is stored. |
| // {global} must not be a reference type. |
| static uint8_t* GetGlobalStorage(Handle<WasmInstanceObject>, |
| const wasm::WasmGlobal&); |
| |
| // Get the FixedArray and the index in that FixedArray for the given global, |
| // which must be a reference type. |
| static std::pair<Handle<FixedArray>, uint32_t> GetGlobalBufferAndIndex( |
| Handle<WasmInstanceObject>, const wasm::WasmGlobal&); |
| |
| // Get the value of a global in the given instance. |
| static wasm::WasmValue GetGlobalValue(Handle<WasmInstanceObject>, |
| const wasm::WasmGlobal&); |
| |
| // Get the name of a global in the given instance by index. |
| static MaybeHandle<String> GetGlobalNameOrNull(Isolate*, |
| Handle<WasmInstanceObject>, |
| uint32_t global_index); |
| |
| // Get the name of a memory in the given instance by index. |
| static MaybeHandle<String> GetMemoryNameOrNull(Isolate*, |
| Handle<WasmInstanceObject>, |
| uint32_t memory_index); |
| |
| // Get the name of a table in the given instance by index. |
| static MaybeHandle<String> GetTableNameOrNull(Isolate*, |
| Handle<WasmInstanceObject>, |
| uint32_t table_index); |
| |
| OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject); |
| |
| private: |
| // Get the name in the given instance by index and kind. |
| static MaybeHandle<String> GetNameFromImportsAndExportsOrNull( |
| Isolate*, Handle<WasmInstanceObject>, wasm::ImportExportKindCode kind, |
| uint32_t index); |
| |
| static void InitDataSegmentArrays(Handle<WasmInstanceObject>, |
| Handle<WasmModuleObject>); |
| static void InitElemSegmentArrays(Handle<WasmInstanceObject>, |
| Handle<WasmModuleObject>); |
| }; |
| |
| // Representation of WebAssembly.Exception JavaScript-level object. |
| class WasmExceptionObject : public JSObject { |
| public: |
| DECL_CAST(WasmExceptionObject) |
| |
| DECL_ACCESSORS(serialized_signature, PodArray<wasm::ValueType>) |
| DECL_ACCESSORS(exception_tag, HeapObject) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmExceptionObject) |
| DECL_VERIFIER(WasmExceptionObject) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_EXCEPTION_OBJECT_FIELDS) |
| |
| // Checks whether the given {sig} has the same parameter types as the |
| // serialized signature stored within this exception object. |
| bool MatchesSignature(const wasm::FunctionSig* sig); |
| |
| static Handle<WasmExceptionObject> New(Isolate* isolate, |
| const wasm::FunctionSig* sig, |
| Handle<HeapObject> exception_tag); |
| |
| OBJECT_CONSTRUCTORS(WasmExceptionObject, JSObject); |
| }; |
| |
| // A Wasm exception that has been thrown out of Wasm code. |
| class V8_EXPORT_PRIVATE WasmExceptionPackage : public JSReceiver { |
| public: |
| static Handle<WasmExceptionPackage> New( |
| Isolate* isolate, Handle<WasmExceptionTag> exception_tag, |
| int encoded_size); |
| |
| // The below getters return {undefined} in case the given exception package |
| // does not carry the requested values (i.e. is of a different type). |
| static Handle<Object> GetExceptionTag( |
| Isolate* isolate, Handle<WasmExceptionPackage> exception_package); |
| static Handle<Object> GetExceptionValues( |
| Isolate* isolate, Handle<WasmExceptionPackage> exception_package); |
| |
| // Determines the size of the array holding all encoded exception values. |
| static uint32_t GetEncodedSize(const wasm::WasmException* exception); |
| |
| DECL_CAST(WasmExceptionPackage) |
| OBJECT_CONSTRUCTORS(WasmExceptionPackage, JSReceiver); |
| }; |
| |
| // A Wasm function that is wrapped and exported to JavaScript. |
| // Representation of WebAssembly.Function JavaScript-level object. |
| class WasmExportedFunction : public JSFunction { |
| public: |
| WasmInstanceObject instance(); |
| V8_EXPORT_PRIVATE int function_index(); |
| |
| V8_EXPORT_PRIVATE static bool IsWasmExportedFunction(Object object); |
| |
| V8_EXPORT_PRIVATE static Handle<WasmExportedFunction> New( |
| Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index, |
| int arity, Handle<Code> export_wrapper); |
| |
| Address GetWasmCallTarget(); |
| |
| V8_EXPORT_PRIVATE const wasm::FunctionSig* sig(); |
| |
| bool MatchesSignature(const wasm::WasmModule* other_module, |
| const wasm::FunctionSig* other_sig); |
| |
| DECL_CAST(WasmExportedFunction) |
| OBJECT_CONSTRUCTORS(WasmExportedFunction, JSFunction); |
| }; |
| |
| // A Wasm function that was created by wrapping a JavaScript callable. |
| // Representation of WebAssembly.Function JavaScript-level object. |
| class WasmJSFunction : public JSFunction { |
| public: |
| static bool IsWasmJSFunction(Object object); |
| |
| static Handle<WasmJSFunction> New(Isolate* isolate, |
| const wasm::FunctionSig* sig, |
| Handle<JSReceiver> callable); |
| |
| JSReceiver GetCallable() const; |
| // Deserializes the signature of this function using the provided zone. Note |
| // that lifetime of the signature is hence directly coupled to the zone. |
| const wasm::FunctionSig* GetSignature(Zone* zone); |
| bool MatchesSignature(const wasm::FunctionSig* sig); |
| |
| DECL_CAST(WasmJSFunction) |
| OBJECT_CONSTRUCTORS(WasmJSFunction, JSFunction); |
| }; |
| |
| // An external function exposed to Wasm via the C/C++ API. |
| class WasmCapiFunction : public JSFunction { |
| public: |
| static bool IsWasmCapiFunction(Object object); |
| |
| static Handle<WasmCapiFunction> New( |
| Isolate* isolate, Address call_target, Handle<Foreign> embedder_data, |
| Handle<PodArray<wasm::ValueType>> serialized_signature); |
| |
| Address GetHostCallTarget() const; |
| PodArray<wasm::ValueType> GetSerializedSignature() const; |
| // Checks whether the given {sig} has the same parameter types as the |
| // serialized signature stored within this C-API function object. |
| bool MatchesSignature(const wasm::FunctionSig* sig) const; |
| |
| DECL_CAST(WasmCapiFunction) |
| OBJECT_CONSTRUCTORS(WasmCapiFunction, JSFunction); |
| }; |
| |
| // Any external function that can be imported/exported in modules. This abstract |
| // class just dispatches to the following concrete classes: |
| // - {WasmExportedFunction}: A proper Wasm function exported from a module. |
| // - {WasmJSFunction}: A function constructed via WebAssembly.Function in JS. |
| // // TODO(wasm): Potentially {WasmCapiFunction} will be added here as well. |
| class WasmExternalFunction : public JSFunction { |
| public: |
| static bool IsWasmExternalFunction(Object object); |
| |
| DECL_CAST(WasmExternalFunction) |
| OBJECT_CONSTRUCTORS(WasmExternalFunction, JSFunction); |
| }; |
| |
| class WasmIndirectFunctionTable : public Struct { |
| public: |
| DECL_PRIMITIVE_ACCESSORS(size, uint32_t) |
| DECL_PRIMITIVE_ACCESSORS(sig_ids, uint32_t*) |
| DECL_PRIMITIVE_ACCESSORS(targets, Address*) |
| DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign) |
| DECL_ACCESSORS(refs, FixedArray) |
| |
| V8_EXPORT_PRIVATE static Handle<WasmIndirectFunctionTable> New( |
| Isolate* isolate, uint32_t size); |
| static void Resize(Isolate* isolate, Handle<WasmIndirectFunctionTable> table, |
| uint32_t new_size); |
| |
| DECL_CAST(WasmIndirectFunctionTable) |
| |
| DECL_PRINTER(WasmIndirectFunctionTable) |
| DECL_VERIFIER(WasmIndirectFunctionTable) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS( |
| HeapObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_INDIRECT_FUNCTION_TABLE_FIELDS) |
| |
| STATIC_ASSERT(kStartOfStrongFieldsOffset == kManagedNativeAllocationsOffset); |
| using BodyDescriptor = FlexibleBodyDescriptor<kStartOfStrongFieldsOffset>; |
| |
| OBJECT_CONSTRUCTORS(WasmIndirectFunctionTable, Struct); |
| }; |
| |
| // Information for a WasmExportedFunction which is referenced as the function |
| // data of the SharedFunctionInfo underlying the function. For details please |
| // see the {SharedFunctionInfo::HasWasmExportedFunctionData} predicate. |
| class WasmExportedFunctionData : public Struct { |
| public: |
| DECL_ACCESSORS(wrapper_code, Code) |
| DECL_ACCESSORS(instance, WasmInstanceObject) |
| DECL_INT_ACCESSORS(jump_table_offset) |
| DECL_INT_ACCESSORS(function_index) |
| DECL_ACCESSORS(signature, Foreign) |
| DECL_INT_ACCESSORS(call_count) |
| DECL_ACCESSORS(c_wrapper_code, Object) |
| DECL_ACCESSORS(wasm_call_target, Object) |
| DECL_INT_ACCESSORS(packed_args_size) |
| |
| DECL_CAST(WasmExportedFunctionData) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmExportedFunctionData) |
| DECL_VERIFIER(WasmExportedFunctionData) |
| |
| // Layout description. |
| DEFINE_FIELD_OFFSET_CONSTANTS( |
| HeapObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_EXPORTED_FUNCTION_DATA_FIELDS) |
| |
| OBJECT_CONSTRUCTORS(WasmExportedFunctionData, Struct); |
| }; |
| |
| // Information for a WasmJSFunction which is referenced as the function data of |
| // the SharedFunctionInfo underlying the function. For details please see the |
| // {SharedFunctionInfo::HasWasmJSFunctionData} predicate. |
| class WasmJSFunctionData : public Struct { |
| public: |
| DECL_INT_ACCESSORS(serialized_return_count) |
| DECL_INT_ACCESSORS(serialized_parameter_count) |
| DECL_ACCESSORS(serialized_signature, PodArray<wasm::ValueType>) |
| DECL_ACCESSORS(callable, JSReceiver) |
| DECL_ACCESSORS(wrapper_code, Code) |
| DECL_ACCESSORS(wasm_to_js_wrapper_code, Code) |
| |
| DECL_CAST(WasmJSFunctionData) |
| |
| // Dispatched behavior. |
| DECL_PRINTER(WasmJSFunctionData) |
| DECL_VERIFIER(WasmJSFunctionData) |
| |
| // Layout description. |
| DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, |
| TORQUE_GENERATED_WASM_JS_FUNCTION_DATA_FIELDS) |
| |
| OBJECT_CONSTRUCTORS(WasmJSFunctionData, Struct); |
| }; |
| |
| class WasmScript : public AllStatic { |
| public: |
| // Set a breakpoint on the given byte position inside the given module. |
| // This will affect all live and future instances of the module. |
| // The passed position might be modified to point to the next breakable |
| // location inside the same function. |
| // If it points outside a function, or behind the last breakable location, |
| // this function returns false and does not set any breakpoint. |
| V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<Script>, int* position, |
| Handle<BreakPoint> break_point); |
| |
| // Set a breakpoint on first breakable position of the given function index |
| // inside the given module. This will affect all live and future instances of |
| // the module. |
| V8_EXPORT_PRIVATE static bool SetBreakPointOnFirstBreakableForFunction( |
| Handle<Script>, int function_index, Handle<BreakPoint> break_point); |
| |
| // Set a breakpoint at the breakable offset of the given function index |
| // inside the given module. This will affect all live and future instances of |
| // the module. |
| V8_EXPORT_PRIVATE static bool SetBreakPointForFunction( |
| Handle<Script>, int function_index, int breakable_offset, |
| Handle<BreakPoint> break_point); |
| |
| // Remove a previously set breakpoint at the given byte position inside the |
| // given module. If this breakpoint is not found this function returns false. |
| V8_EXPORT_PRIVATE static bool ClearBreakPoint(Handle<Script>, int position, |
| Handle<BreakPoint> break_point); |
| |
| // Remove a previously set breakpoint by id. If this breakpoint is not found, |
| // returns false. |
| V8_EXPORT_PRIVATE static bool ClearBreakPointById(Handle<Script>, |
| int breakpoint_id); |
| |
| // Remove all set breakpoints. |
| static void ClearAllBreakpoints(Script); |
| |
| // Get a list of all possible breakpoints within a given range of this module. |
| V8_EXPORT_PRIVATE static bool GetPossibleBreakpoints( |
| wasm::NativeModule* native_module, const debug::Location& start, |
| const debug::Location& end, std::vector<debug::BreakLocation>* locations); |
| |
| // Return an empty handle if no breakpoint is hit at that location, or a |
| // FixedArray with all hit breakpoint objects. |
| static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, Handle<Script>, |
| int position); |
| |
| private: |
| // Helper functions that update the breakpoint info list. |
| static void AddBreakpointToInfo(Handle<Script>, int position, |
| Handle<BreakPoint> break_point); |
| }; |
| |
| // Tags provide an object identity for each exception defined in a wasm module |
| // header. They are referenced by the following fields: |
| // - {WasmExceptionObject::exception_tag} : The tag of the exception object. |
| // - {WasmInstanceObject::exceptions_table}: List of tags used by an instance. |
| class WasmExceptionTag |
| : public TorqueGeneratedWasmExceptionTag<WasmExceptionTag, Struct> { |
| public: |
| V8_EXPORT_PRIVATE static Handle<WasmExceptionTag> New(Isolate* isolate, |
| int index); |
| |
| DECL_PRINTER(WasmExceptionTag) |
| |
| TQ_OBJECT_CONSTRUCTORS(WasmExceptionTag) |
| }; |
| |
| // Data annotated to the asm.js Module function. Used for later instantiation of |
| // that function. |
| class AsmWasmData : public Struct { |
| public: |
| static Handle<AsmWasmData> New( |
| Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module, |
| Handle<FixedArray> export_wrappers, Handle<HeapNumber> uses_bitset); |
| |
| DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>) |
| DECL_ACCESSORS(export_wrappers, FixedArray) |
| DECL_ACCESSORS(uses_bitset, HeapNumber) |
| |
| DECL_CAST(AsmWasmData) |
| DECL_PRINTER(AsmWasmData) |
| DECL_VERIFIER(AsmWasmData) |
| |
| DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, |
| TORQUE_GENERATED_ASM_WASM_DATA_FIELDS) |
| |
| OBJECT_CONSTRUCTORS(AsmWasmData, Struct); |
| }; |
| |
| class WasmTypeInfo : public TorqueGeneratedWasmTypeInfo<WasmTypeInfo, Foreign> { |
| public: |
| inline void clear_foreign_address(Isolate* isolate); |
| |
| DECL_CAST(WasmTypeInfo) |
| DECL_PRINTER(WasmTypeInfo) |
| |
| class BodyDescriptor; |
| |
| TQ_OBJECT_CONSTRUCTORS(WasmTypeInfo) |
| }; |
| |
| class WasmStruct : public TorqueGeneratedWasmStruct<WasmStruct, HeapObject> { |
| public: |
| static inline wasm::StructType* type(Map map); |
| inline wasm::StructType* type() const; |
| static inline wasm::StructType* GcSafeType(Map map); |
| |
| inline ObjectSlot RawField(int raw_offset); |
| |
| DECL_CAST(WasmStruct) |
| DECL_PRINTER(WasmStruct) |
| |
| class BodyDescriptor; |
| |
| TQ_OBJECT_CONSTRUCTORS(WasmStruct) |
| }; |
| |
| class WasmArray : public TorqueGeneratedWasmArray<WasmArray, HeapObject> { |
| public: |
| static inline wasm::ArrayType* type(Map map); |
| inline wasm::ArrayType* type() const; |
| static inline wasm::ArrayType* GcSafeType(Map map); |
| |
| static inline int SizeFor(Map map, int length); |
| |
| DECL_CAST(WasmArray) |
| DECL_PRINTER(WasmArray) |
| |
| class BodyDescriptor; |
| |
| TQ_OBJECT_CONSTRUCTORS(WasmArray) |
| }; |
| |
| #undef DECL_OPTIONAL_ACCESSORS |
| |
| namespace wasm { |
| |
| Handle<Map> CreateStructMap(Isolate* isolate, const WasmModule* module, |
| int struct_index, Handle<Map> rtt_parent); |
| Handle<Map> CreateArrayMap(Isolate* isolate, const WasmModule* module, |
| int array_index, Handle<Map> rtt_parent); |
| Handle<Map> CreateGenericRtt(Isolate* isolate, const WasmModule* module, |
| Handle<Map> rtt_parent); |
| Handle<Map> AllocateSubRtt(Isolate* isolate, |
| Handle<WasmInstanceObject> instance, uint32_t type, |
| Handle<Map> parent); |
| |
| bool TypecheckJSObject(Isolate* isolate, const WasmModule* module, |
| Handle<Object> value, ValueType expected, |
| const char** error_message); |
| } // namespace wasm |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #include "src/objects/object-macros-undef.h" |
| |
| #endif // V8_WASM_WASM_OBJECTS_H_ |