// 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 "src/base/bits.h" #include "src/debug/debug.h" #include "src/debug/interface-types.h" #include "src/heap/heap.h" #include "src/objects.h" #include "src/objects/script.h" #include "src/signature.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; struct InterpretedFrameDeleter; class NativeModule; struct ModuleEnv; class WasmCode; struct WasmModule; class SignatureMap; class WireBytesRef; class WasmInterpreter; using FunctionSig = Signature; struct WasmFeatures; } // namespace wasm class BreakPoint; class JSArrayBuffer; class SeqOneByteString; class WasmDebugInfo; class WasmInstanceObject; template class Managed; #define DECL_OPTIONAL_ACCESSORS(name, type) \ V8_INLINE bool has_##name(); \ DECL_ACCESSORS(name, type) // An entry in an indirect function table (IFT). // Each entry in the IFT has the following fields: // - instance = target instance // - sig_id = signature id of function // - target = entrypoint to wasm code for the function, or wasm-to-js wrapper class IndirectFunctionTableEntry { public: inline IndirectFunctionTableEntry(Handle, int index); void clear(); void set(int sig_id, WasmInstanceObject* instance, Address call_target); WasmInstanceObject* instance(); int sig_id(); Address target(); private: Handle const instance_; int const index_; }; // An entry for an imported function. // (note this is not called a "table" since it is not dynamically indexed). // The imported function entries are used to call imported functions. // For each imported function there is an entry which is either: // - an imported JSReceiver, which has fields // - instance = importing instance // - receiver = JSReceiver, either a JS function or other callable // - target = pointer to wasm-to-js wrapper code entrypoint // - an imported wasm function from another instance, which has fields // - instance = target instance // - target = entrypoint for the function class ImportedFunctionEntry { public: inline ImportedFunctionEntry(Handle, int index); // Initialize this entry as a {JSReceiver} call. void set_wasm_to_js(JSReceiver* callable, const wasm::WasmCode* wasm_to_js_wrapper); // Initialize this entry as a WASM to WASM call. void set_wasm_to_wasm(WasmInstanceObject* target_instance, Address call_target); WasmInstanceObject* instance(); JSReceiver* callable(); Address target(); bool is_js_receiver_entry(); private: Handle const instance_; int const index_; }; // Representation of a WebAssembly.Module JavaScript-level object. class WasmModuleObject : public JSObject { public: DECL_CAST(WasmModuleObject) DECL_ACCESSORS(managed_native_module, Managed) DECL_ACCESSORS(export_wrappers, FixedArray) DECL_ACCESSORS(script, Script) DECL_ACCESSORS(weak_instance_list, WeakArrayList) DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray) DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray) inline wasm::NativeModule* native_module() const; inline const wasm::WasmModule* module() const; inline void reset_breakpoint_infos(); // Dispatched behavior. DECL_PRINTER(WasmModuleObject) DECL_VERIFIER(WasmModuleObject) // Layout description. #define WASM_MODULE_OBJECT_FIELDS(V) \ V(kNativeModuleOffset, kPointerSize) \ V(kExportWrappersOffset, kPointerSize) \ V(kScriptOffset, kPointerSize) \ V(kWeakInstanceListOffset, kPointerSize) \ V(kAsmJsOffsetTableOffset, kPointerSize) \ V(kBreakPointInfosOffset, kPointerSize) \ V(kSize, 0) DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, WASM_MODULE_OBJECT_FIELDS) #undef WASM_MODULE_OBJECT_FIELDS // Creates a new {WasmModuleObject} with a new {NativeModule} underneath. static Handle New( Isolate* isolate, const wasm::WasmFeatures& enabled, std::shared_ptr module, wasm::ModuleEnv& env, OwnedVector wire_bytes, Handle