chromium/v8/src/wasm/wasm-objects.cc

// Copyright 2015 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.

#include "src/wasm/wasm-objects.h"

#include <optional>

#include "src/base/iterator.h"
#include "src/base/vector.h"
#include "src/builtins/builtins-inl.h"
#include "src/compiler/wasm-compiler.h"
#include "src/debug/debug.h"
#include "src/logging/counters.h"
#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/shared-function-info.h"
#include "src/roots/roots-inl.h"
#include "src/utils/utils.h"
#include "src/wasm/code-space-access.h"
#include "src/wasm/compilation-environment-inl.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/module-instantiate.h"
#include "src/wasm/serialized-signature-inl.h"
#include "src/wasm/signature-hashing.h"
#include "src/wasm/stacks.h"
#include "src/wasm/value-type.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-subtyping.h"
#include "src/wasm/wasm-value.h"

#if V8_ENABLE_DRUMBRAKE
#include "src/wasm/interpreter/wasm-interpreter-inl.h"
#include "src/wasm/interpreter/wasm-interpreter-runtime.h"
#endif  // V8_ENABLE_DRUMBRAKE

// Needs to be last so macros do not get undefined.
#include "src/objects/object-macros.h"

#define TRACE_IFT

namespace v8 {
namespace internal {

// Import a few often used types from the wasm namespace.
WasmFunction;
WasmModule;

namespace {

// The WasmTableObject::uses field holds pairs of <instance, index>. This enum
// helps compute the respective offset.
enum TableUses : int {};

}  // namespace

// static
Handle<WasmModuleObject> WasmModuleObject::New(
    Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
    DirectHandle<Script> script) {}

Handle<String> WasmModuleObject::ExtractUtf8StringFromModuleBytes(
    Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
    wasm::WireBytesRef ref, InternalizeString internalize) {}

Handle<String> WasmModuleObject::ExtractUtf8StringFromModuleBytes(
    Isolate* isolate, base::Vector<const uint8_t> wire_bytes,
    wasm::WireBytesRef ref, InternalizeString internalize) {}

MaybeHandle<String> WasmModuleObject::GetModuleNameOrNull(
    Isolate* isolate, DirectHandle<WasmModuleObject> module_object) {}

MaybeHandle<String> WasmModuleObject::GetFunctionNameOrNull(
    Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
    uint32_t func_index) {}

base::Vector<const uint8_t> WasmModuleObject::GetRawFunctionName(
    int func_index) {}

Handle<WasmTableObject> WasmTableObject::New(
    Isolate* isolate, Handle<WasmTrustedInstanceData> trusted_data,
    wasm::ValueType type, uint32_t initial, bool has_maximum, uint32_t maximum,
    DirectHandle<Object> initial_value, WasmTableFlag table_type) {}

void WasmTableObject::AddUse(Isolate* isolate,
                             DirectHandle<WasmTableObject> table_obj,
                             Handle<WasmInstanceObject> instance_object,
                             int table_index) {}

int WasmTableObject::Grow(Isolate* isolate, DirectHandle<WasmTableObject> table,
                          uint32_t count, DirectHandle<Object> init_value) {}

bool WasmTableObject::is_in_bounds(uint32_t entry_index) {}

MaybeHandle<Object> WasmTableObject::JSToWasmElement(
    Isolate* isolate, DirectHandle<WasmTableObject> table, Handle<Object> entry,
    const char** error_message) {}

void WasmTableObject::SetFunctionTableEntry(Isolate* isolate,
                                            DirectHandle<WasmTableObject> table,
                                            int entry_index,
                                            DirectHandle<Object> entry) {}

// Note: This needs to be handlified because it transitively calls
// {ImportWasmJSFunctionIntoTable} which calls {NewWasmImportData}.
void WasmTableObject::Set(Isolate* isolate, DirectHandle<WasmTableObject> table,
                          uint32_t index, DirectHandle<Object> entry) {}

Handle<Object> WasmTableObject::Get(Isolate* isolate,
                                    DirectHandle<WasmTableObject> table,
                                    uint32_t index) {}

void WasmTableObject::Fill(Isolate* isolate,
                           DirectHandle<WasmTableObject> table, uint32_t start,
                           DirectHandle<Object> entry, uint32_t count) {}

#if V8_ENABLE_SANDBOX || DEBUG
bool FunctionSigMatchesTable(uint32_t canonical_sig_id,
                             const WasmModule* module, int table_index) {}
#endif  // V8_ENABLE_SANDBOX || DEBUG

// static
void WasmTableObject::UpdateDispatchTables(
    Isolate* isolate, DirectHandle<WasmTableObject> table, int entry_index,
    const wasm::WasmFunction* func,
    DirectHandle<WasmTrustedInstanceData> target_instance_data
#if V8_ENABLE_DRUMBRAKE
    ,
    int target_func_index
#endif  // V8_ENABLE_DRUMBRAKE
) {}

// static
void WasmTableObject::UpdateDispatchTables(
    Isolate* isolate, DirectHandle<WasmTableObject> table, int entry_index,
    DirectHandle<WasmJSFunction> function) {}

// static
void WasmTableObject::UpdateDispatchTables(
    Isolate* isolate, DirectHandle<WasmTableObject> table, int entry_index,
    DirectHandle<WasmCapiFunction> capi_function) {}

void WasmTableObject::ClearDispatchTables(int index) {}

// static
void WasmTableObject::SetFunctionTablePlaceholder(
    Isolate* isolate, DirectHandle<WasmTableObject> table, int entry_index,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    int func_index) {}

// static
void WasmTableObject::GetFunctionTableEntry(
    Isolate* isolate, const WasmModule* module,
    DirectHandle<WasmTableObject> table, int entry_index, bool* is_valid,
    bool* is_null, MaybeHandle<WasmTrustedInstanceData>* instance_data,
    int* function_index, MaybeDirectHandle<WasmJSFunction>* maybe_js_function) {}

Handle<WasmSuspendingObject> WasmSuspendingObject::New(
    Isolate* isolate, DirectHandle<JSReceiver> callable) {}

namespace {

void SetInstanceMemory(Tagged<WasmTrustedInstanceData> trusted_instance_data,
                       Tagged<JSArrayBuffer> buffer, int memory_index) {}

}  // namespace

Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate,
                                               Handle<JSArrayBuffer> buffer,
                                               int maximum,
                                               WasmMemoryFlag memory_type) {}

MaybeHandle<WasmMemoryObject> WasmMemoryObject::New(
    Isolate* isolate, int initial, int maximum, SharedFlag shared,
    WasmMemoryFlag memory_type) {}

void WasmMemoryObject::UseInInstance(
    Isolate* isolate, DirectHandle<WasmMemoryObject> memory,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    Handle<WasmTrustedInstanceData> shared_trusted_instance_data,
    int memory_index_in_instance) {}

void WasmMemoryObject::SetNewBuffer(Tagged<JSArrayBuffer> new_buffer) {}

// static
int32_t WasmMemoryObject::Grow(Isolate* isolate,
                               Handle<WasmMemoryObject> memory_object,
                               uint32_t pages) {}

// static
MaybeHandle<WasmGlobalObject> WasmGlobalObject::New(
    Isolate* isolate, Handle<WasmTrustedInstanceData> trusted_data,
    MaybeHandle<JSArrayBuffer> maybe_untagged_buffer,
    MaybeHandle<FixedArray> maybe_tagged_buffer, wasm::ValueType type,
    int32_t offset, bool is_mutable) {}

FunctionTargetAndImplicitArg::FunctionTargetAndImplicitArg(
    Isolate* isolate, Handle<WasmTrustedInstanceData> target_instance_data,
    int target_func_index) {}

void ImportedFunctionEntry::SetGenericWasmToJs(
    Isolate* isolate, DirectHandle<JSReceiver> callable, wasm::Suspend suspend,
    const wasm::FunctionSig* sig) {}

void ImportedFunctionEntry::SetCompiledWasmToJs(
    Isolate* isolate, DirectHandle<JSReceiver> callable,
    wasm::WasmCode* wasm_to_js_wrapper, wasm::Suspend suspend,
    const wasm::FunctionSig* sig) {}

void ImportedFunctionEntry::SetWasmToWasm(
    Tagged<WasmTrustedInstanceData> target_instance_data, Address call_target
#if V8_ENABLE_DRUMBRAKE
    ,
    int exported_function_index
#endif  // V8_ENABLE_DRUMBRAKE
) {}

// Returns an empty Tagged<Object>() if no callable is available, a JSReceiver
// otherwise.
Tagged<Object> ImportedFunctionEntry::maybe_callable() {}

Tagged<JSReceiver> ImportedFunctionEntry::callable() {}

Tagged<Object> ImportedFunctionEntry::implicit_arg() {}

Address ImportedFunctionEntry::target() {}

void ImportedFunctionEntry::set_target(Address new_target,
                                       wasm::WasmCode* wrapper_if_known,
                                       IsAWrapper contextual_knowledge) {}

#if V8_ENABLE_DRUMBRAKE
int ImportedFunctionEntry::function_index_in_called_module() {
  return instance_data_->imported_function_indices()->get(index_);
}
#endif  // V8_ENABLE_DRUMBRAKE

// static
constexpr std::array<uint16_t, WasmTrustedInstanceData::kTaggedFieldsCount>
    WasmTrustedInstanceData::kTaggedFieldOffsets;
// static
constexpr std::array<const char*, WasmTrustedInstanceData::kTaggedFieldsCount>
    WasmTrustedInstanceData::kTaggedFieldNames;
// static
constexpr std::array<uint16_t, 6>
    WasmTrustedInstanceData::kProtectedFieldOffsets;
// static
constexpr std::array<const char*, 6>
    WasmTrustedInstanceData::kProtectedFieldNames;

// static
void WasmTrustedInstanceData::EnsureMinimumDispatchTableSize(
    Isolate* isolate,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    int table_index, int minimum_size) {}

void WasmTrustedInstanceData::SetRawMemory(int memory_index, uint8_t* mem_start,
                                           size_t mem_size) {}

#if V8_ENABLE_DRUMBRAKE
Handle<Tuple2> WasmTrustedInstanceData::GetOrCreateInterpreterObject(
    Handle<WasmInstanceObject> instance) {
  DCHECK(v8_flags.wasm_jitless);
  Isolate* isolate = instance->GetIsolate();
  Handle<WasmTrustedInstanceData> trusted_data =
      handle(instance->trusted_data(isolate), isolate);
  if (trusted_data->has_interpreter_object()) {
    return handle(trusted_data->interpreter_object(), isolate);
  }
  Handle<Tuple2> new_interpreter = WasmInterpreterObject::New(instance);
  DCHECK(trusted_data->has_interpreter_object());
  return new_interpreter;
}

Handle<Tuple2> WasmTrustedInstanceData::GetInterpreterObject(
    Handle<WasmInstanceObject> instance) {
  DCHECK(v8_flags.wasm_jitless);
  Isolate* isolate = instance->GetIsolate();
  Handle<WasmTrustedInstanceData> trusted_data =
      handle(instance->trusted_data(isolate), isolate);
  CHECK(trusted_data->has_interpreter_object());
  return handle(trusted_data->interpreter_object(), isolate);
}
#endif  // V8_ENABLE_DRUMBRAKE

Handle<WasmTrustedInstanceData> WasmTrustedInstanceData::New(
    Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
    bool shared) {}

void WasmTrustedInstanceData::InitDataSegmentArrays(
    const wasm::NativeModule* native_module) {}

Address WasmTrustedInstanceData::GetCallTarget(uint32_t func_index) {}

// static
bool WasmTrustedInstanceData::CopyTableEntries(
    Isolate* isolate,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    uint32_t table_dst_index, uint32_t table_src_index, uint32_t dst,
    uint32_t src, uint32_t count) {}

// static
std::optional<MessageTemplate> WasmTrustedInstanceData::InitTableEntries(
    Isolate* isolate, Handle<WasmTrustedInstanceData> trusted_instance_data,
    Handle<WasmTrustedInstanceData> shared_trusted_instance_data,
    uint32_t table_index, uint32_t segment_index, uint32_t dst, uint32_t src,
    uint32_t count) {}

bool WasmTrustedInstanceData::try_get_func_ref(int index,
                                               Tagged<WasmFuncRef>* result) {}

Handle<WasmFuncRef> WasmTrustedInstanceData::GetOrCreateFuncRef(
    Isolate* isolate,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    int function_index) {}

bool WasmInternalFunction::try_get_external(Tagged<JSFunction>* result) {}

// static
Handle<JSFunction> WasmInternalFunction::GetOrCreateExternal(
    DirectHandle<WasmInternalFunction> internal) {}

// static
void WasmImportData::SetImportIndexAsCallOrigin(
    DirectHandle<WasmImportData> import_data, int entry_index) {}

// static
void WasmImportData::SetIndexInTableAsCallOrigin(
    DirectHandle<WasmImportData> import_data, int entry_index) {}

// static
bool WasmImportData::CallOriginIsImportIndex(DirectHandle<Object> call_origin) {}

// static
bool WasmImportData::CallOriginIsIndexInTable(
    DirectHandle<Object> call_origin) {}

// static
int WasmImportData::CallOriginAsIndex(DirectHandle<Object> call_origin) {}

// static
void WasmImportData::SetCrossInstanceTableIndexAsCallOrigin(
    Isolate* isolate, DirectHandle<WasmImportData> import_data,
    DirectHandle<WasmInstanceObject> instance_object, int entry_index) {}

// static
void WasmImportData::SetFuncRefAsCallOrigin(
    DirectHandle<WasmImportData> import_data,
    DirectHandle<WasmFuncRef> func_ref) {}

// static
void WasmTrustedInstanceData::ImportWasmJSFunctionIntoTable(
    Isolate* isolate,
    DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
    int table_index, int entry_index,
    DirectHandle<WasmJSFunction> js_function) {}

uint8_t* WasmTrustedInstanceData::GetGlobalStorage(
    const wasm::WasmGlobal& global) {}

std::pair<Tagged<FixedArray>, uint32_t>
WasmTrustedInstanceData::GetGlobalBufferAndIndex(
    const wasm::WasmGlobal& global) {}

wasm::WasmValue WasmTrustedInstanceData::GetGlobalValue(
    Isolate* isolate, const wasm::WasmGlobal& global) {}

wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {}

wasm::WasmValue WasmArray::GetElement(uint32_t index) {}

void WasmArray::SetTaggedElement(uint32_t index, DirectHandle<Object> value,
                                 WriteBarrierMode mode) {}

// static
Handle<WasmTagObject> WasmTagObject::New(
    Isolate* isolate, const wasm::FunctionSig* sig,
    uint32_t canonical_type_index, DirectHandle<HeapObject> tag,
    DirectHandle<WasmTrustedInstanceData> trusted_data) {}

bool WasmTagObject::MatchesSignature(uint32_t expected_canonical_type_index) {}

const wasm::FunctionSig* WasmCapiFunction::GetSignature(Zone* zone) const {}

WasmDispatchTableData::~WasmDispatchTableData() {}

void WasmDispatchTableData::Add(Address call_target,
                                wasm::WasmCode* wrapper_if_known,
                                IsAWrapper contextual_knowledge) {}

void WasmDispatchTableData::Remove(Address call_target) {}

void WasmDispatchTable::Set(int index, Tagged<Object> implicit_arg,
                            Address call_target, int sig_id
#if V8_ENABLE_DRUMBRAKE
                            ,
                            uint32_t function_index
#endif  // V8_ENABLE_DRUMBRAKE
) {}

void WasmDispatchTable::SetForImport(int index,
                                     Tagged<TrustedObject> implicit_arg,
                                     Address call_target) {}

void WasmDispatchTable::Clear(int index) {}

void WasmDispatchTable::SetTarget(int index, Address call_target) {}

// static
Handle<WasmDispatchTable> WasmDispatchTable::New(Isolate* isolate, int length) {}

// static
Handle<WasmDispatchTable> WasmDispatchTable::Grow(
    Isolate* isolate, Handle<WasmDispatchTable> old_table, int new_length) {}

bool WasmCapiFunction::MatchesSignature(
    uint32_t other_canonical_sig_index) const {}

// static
Handle<WasmExceptionPackage> WasmExceptionPackage::New(
    Isolate* isolate, DirectHandle<WasmExceptionTag> exception_tag, int size) {}

Handle<WasmExceptionPackage> WasmExceptionPackage::New(
    Isolate* isolate, DirectHandle<WasmExceptionTag> exception_tag,
    DirectHandle<FixedArray> values) {}

// static
Handle<Object> WasmExceptionPackage::GetExceptionTag(
    Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {}

// static
Handle<Object> WasmExceptionPackage::GetExceptionValues(
    Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {}

void EncodeI32ExceptionValue(DirectHandle<FixedArray> encoded_values,
                             uint32_t* encoded_index, uint32_t value) {}

void EncodeI64ExceptionValue(DirectHandle<FixedArray> encoded_values,
                             uint32_t* encoded_index, uint64_t value) {}

void DecodeI32ExceptionValue(DirectHandle<FixedArray> encoded_values,
                             uint32_t* encoded_index, uint32_t* value) {}

void DecodeI64ExceptionValue(DirectHandle<FixedArray> encoded_values,
                             uint32_t* encoded_index, uint64_t* value) {}

// static
Handle<WasmContinuationObject> WasmContinuationObject::New(
    Isolate* isolate, wasm::StackMemory* stack,
    wasm::JumpBuffer::StackState state, DirectHandle<HeapObject> parent,
    AllocationType allocation_type) {}

bool UseGenericWasmToJSWrapper(wasm::ImportCallKind kind,
                               const wasm::FunctionSig* sig,
                               wasm::Suspend suspend) {}

// static
Handle<WasmContinuationObject> WasmContinuationObject::New(
    Isolate* isolate, wasm::StackMemory* stack,
    wasm::JumpBuffer::StackState state, AllocationType allocation_type) {}
#ifdef DEBUG

namespace {

constexpr uint32_t kBytesPerExceptionValuesArrayElement =;

size_t ComputeEncodedElementSize(wasm::ValueType type) {}

}  // namespace

#endif  // DEBUG

// static
uint32_t WasmExceptionPackage::GetEncodedSize(const wasm::WasmTag* tag) {}

// static
uint32_t WasmExceptionPackage::GetEncodedSize(const wasm::WasmTagSig* sig) {}

bool WasmExportedFunction::IsWasmExportedFunction(Tagged<Object> object) {}

bool WasmCapiFunction::IsWasmCapiFunction(Tagged<Object> object) {}

Handle<WasmCapiFunction> WasmCapiFunction::New(
    Isolate* isolate, Address call_target, DirectHandle<Foreign> embedder_data,
    DirectHandle<PodArray<wasm::ValueType>> serialized_signature,
    uintptr_t signature_hash) {}

Handle<WasmExportedFunction> WasmExportedFunction::New(
    Isolate* isolate, DirectHandle<WasmTrustedInstanceData> instance_data,
    DirectHandle<WasmFuncRef> func_ref,
    DirectHandle<WasmInternalFunction> internal_function, int arity,
    DirectHandle<Code> export_wrapper) {}

bool WasmExportedFunctionData::MatchesSignature(
    uint32_t other_canonical_type_index) {}

// static
std::unique_ptr<char[]> WasmExportedFunction::GetDebugName(
    const wasm::FunctionSig* sig) {}

// static
bool WasmJSFunction::IsWasmJSFunction(Tagged<Object> object) {}

Handle<Map> CreateFuncRefMap(Isolate* isolate, Handle<Map> opt_rtt_parent) {}

Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
                                           const wasm::FunctionSig* sig,
                                           Handle<JSReceiver> callable,
                                           wasm::Suspend suspend) {}

Tagged<JSReceiver> WasmJSFunctionData::GetCallable() const {}

wasm::Suspend WasmJSFunctionData::GetSuspend() const {}

const wasm::FunctionSig* WasmJSFunctionData::GetSignature() const {}

bool WasmJSFunctionData::MatchesSignature(
    uint32_t other_canonical_sig_index) const {}

Tagged<PodArray<wasm::ValueType>> WasmCapiFunction::GetSerializedSignature()
    const {}

bool WasmExternalFunction::IsWasmExternalFunction(Tagged<Object> object) {}

Handle<WasmExceptionTag> WasmExceptionTag::New(Isolate* isolate, int index) {}

Handle<AsmWasmData> AsmWasmData::New(
    Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
    DirectHandle<HeapNumber> uses_bitset) {}

namespace {
constexpr int32_t kInt31MaxValue =;
constexpr int32_t kInt31MinValue =;

// Tries to canonicalize a HeapNumber to an i31ref Smi. Returns the original
// HeapNumber if it fails.
Handle<Object> CanonicalizeHeapNumber(Handle<Object> number, Isolate* isolate) {}

// Tries to canonicalize a Smi into an i31 Smi. Returns a HeapNumber if it
// fails.
Handle<Object> CanonicalizeSmi(Handle<Object> smi, Isolate* isolate) {}
}  // namespace

namespace wasm {
MaybeHandle<Object> JSToWasmObject(Isolate* isolate, Handle<Object> value,
                                   ValueType expected, uint32_t canonical_index,
                                   const char** error_message) {}

// Utility which canonicalizes {expected} in addition.
MaybeHandle<Object> JSToWasmObject(Isolate* isolate, const WasmModule* module,
                                   Handle<Object> value, ValueType expected,
                                   const char** error_message) {}

Handle<Object> WasmToJSObject(Isolate* isolate, Handle<Object> value) {}

}  // namespace wasm

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"
#undef TRACE_IFT