%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/wasm/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/wasm/wasm-objects-inl.h

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

#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif  // !V8_ENABLE_WEBASSEMBLY

#ifndef V8_WASM_WASM_OBJECTS_INL_H_
#define V8_WASM_WASM_OBJECTS_INL_H_

#include <type_traits>

#include "src/base/memory.h"
#include "src/common/ptr-compr.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/contexts-inl.h"
#include "src/objects/foreign.h"
#include "src/objects/heap-number.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-function-inl.h"
#include "src/objects/js-objects-inl.h"
#include "src/objects/managed.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/script-inl.h"
#include "src/roots/roots.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"

// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

#include "torque-generated/src/wasm/wasm-objects-tq-inl.inc"

TQ_OBJECT_CONSTRUCTORS_IMPL(WasmTagObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmExceptionTag)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmCapiFunctionData)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmExportedFunctionData)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmGlobalObject)
OBJECT_CONSTRUCTORS_IMPL(WasmInstanceObject, JSObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmMemoryObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmModuleObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmTableObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(AsmWasmData)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmFunctionData)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmApiFunctionRef)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmInternalFunction)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmTypeInfo)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmStruct)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmArray)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmContinuationObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmSuspenderObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmResumeData)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmNull)

CAST_ACCESSOR(WasmInstanceObject)

#define OPTIONAL_ACCESSORS(holder, name, type, offset)       \
  DEF_GETTER(holder, has_##name, bool) {                     \
    Tagged<Object> value =                                   \
        TaggedField<Object, offset>::load(cage_base, *this); \
    return !IsUndefined(value, GetReadOnlyRoots(cage_base)); \
  }                                                          \
  ACCESSORS_CHECKED2(holder, name, type, offset,             \
                     !IsUndefined(value, GetReadOnlyRoots(cage_base)), true)

#define PRIMITIVE_ACCESSORS(holder, name, type, offset)               \
  type holder::name() const {                                         \
    return ReadMaybeUnalignedValue<type>(FIELD_ADDR(*this, offset));  \
  }                                                                   \
  void holder::set_##name(type value) {                               \
    WriteMaybeUnalignedValue<type>(FIELD_ADDR(*this, offset), value); \
  }

#define SANDBOXED_POINTER_ACCESSORS(holder, name, type, offset)      \
  type holder::name() const {                                        \
    PtrComprCageBase sandbox_base = GetPtrComprCageBase(*this);      \
    Address value = ReadSandboxedPointerField(offset, sandbox_base); \
    return reinterpret_cast<type>(value);                            \
  }                                                                  \
  void holder::set_##name(type value) {                              \
    PtrComprCageBase sandbox_base = GetPtrComprCageBase(*this);      \
    Address addr = reinterpret_cast<Address>(value);                 \
    WriteSandboxedPointerField(offset, sandbox_base, addr);          \
  }

// WasmModuleObject
wasm::NativeModule* WasmModuleObject::native_module() const {
  return managed_native_module()->raw();
}
const std::shared_ptr<wasm::NativeModule>&
WasmModuleObject::shared_native_module() const {
  return managed_native_module()->get();
}
const wasm::WasmModule* WasmModuleObject::module() const {
  // TODO(clemensb): Remove this helper (inline in callers).
  return native_module()->module();
}
bool WasmModuleObject::is_asm_js() {
  bool asm_js = is_asmjs_module(module());
  DCHECK_EQ(asm_js, script()->IsUserJavaScript());
  return asm_js;
}

// WasmMemoryObject
OPTIONAL_ACCESSORS(WasmMemoryObject, instances, Tagged<WeakArrayList>,
                   kInstancesOffset)

// WasmGlobalObject
ACCESSORS(WasmGlobalObject, untagged_buffer, Tagged<JSArrayBuffer>,
          kUntaggedBufferOffset)
ACCESSORS(WasmGlobalObject, tagged_buffer, Tagged<FixedArray>,
          kTaggedBufferOffset)

wasm::ValueType WasmGlobalObject::type() const {
  return wasm::ValueType::FromRawBitField(static_cast<uint32_t>(raw_type()));
}
void WasmGlobalObject::set_type(wasm::ValueType value) {
  set_raw_type(static_cast<int>(value.raw_bit_field()));
}

int WasmGlobalObject::type_size() const { return type().value_kind_size(); }

Address WasmGlobalObject::address() const {
  DCHECK_NE(type(), wasm::kWasmAnyRef);
  DCHECK_LE(offset() + type_size(), untagged_buffer()->byte_length());
  return reinterpret_cast<Address>(untagged_buffer()->backing_store()) +
         offset();
}

int32_t WasmGlobalObject::GetI32() {
  return base::ReadUnalignedValue<int32_t>(address());
}

int64_t WasmGlobalObject::GetI64() {
  return base::ReadUnalignedValue<int64_t>(address());
}

float WasmGlobalObject::GetF32() {
  return base::ReadUnalignedValue<float>(address());
}

double WasmGlobalObject::GetF64() {
  return base::ReadUnalignedValue<double>(address());
}

uint8_t* WasmGlobalObject::GetS128RawBytes() {
  return reinterpret_cast<uint8_t*>(address());
}

Handle<Object> WasmGlobalObject::GetRef() {
  // We use this getter for externref, funcref, and stringref.
  DCHECK(type().is_reference());
  return handle(tagged_buffer()->get(offset()), GetIsolate());
}

void WasmGlobalObject::SetI32(int32_t value) {
  base::WriteUnalignedValue(address(), value);
}

void WasmGlobalObject::SetI64(int64_t value) {
  base::WriteUnalignedValue(address(), value);
}

void WasmGlobalObject::SetF32(float value) {
  base::WriteUnalignedValue(address(), value);
}

void WasmGlobalObject::SetF64(double value) {
  base::WriteUnalignedValue(address(), value);
}

void WasmGlobalObject::SetRef(Handle<Object> value) {
  DCHECK(type().is_object_reference());
  tagged_buffer()->set(offset(), *value);
}

// WasmInstanceObject
SANDBOXED_POINTER_ACCESSORS(WasmInstanceObject, memory0_start, uint8_t*,
                            kMemory0StartOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, memory0_size, size_t,
                    kMemory0SizeOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, stack_limit_address, Address,
                    kStackLimitAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, real_stack_limit_address, Address,
                    kRealStackLimitAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, new_allocation_limit_address, Address*,
                    kNewAllocationLimitAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, new_allocation_top_address, Address*,
                    kNewAllocationTopAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, old_allocation_limit_address, Address*,
                    kOldAllocationLimitAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, old_allocation_top_address, Address*,
                    kOldAllocationTopAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, isorecursive_canonical_types,
                    const uint32_t*, kIsorecursiveCanonicalTypesOffset)
SANDBOXED_POINTER_ACCESSORS(WasmInstanceObject, globals_start, uint8_t*,
                            kGlobalsStartOffset)
ACCESSORS(WasmInstanceObject, imported_mutable_globals,
          Tagged<FixedAddressArray>, kImportedMutableGlobalsOffset)
ACCESSORS(WasmInstanceObject, imported_function_targets,
          Tagged<FixedAddressArray>, kImportedFunctionTargetsOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, indirect_function_table_size, uint32_t,
                    kIndirectFunctionTableSizeOffset)
ACCESSORS(WasmInstanceObject, indirect_function_table_sig_ids,
          Tagged<FixedUInt32Array>, kIndirectFunctionTableSigIdsOffset)
ACCESSORS(WasmInstanceObject, indirect_function_table_targets,
          Tagged<ExternalPointerArray>, kIndirectFunctionTableTargetsOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, jump_table_start, Address,
                    kJumpTableStartOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, hook_on_function_call_address, Address,
                    kHookOnFunctionCallAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, tiering_budget_array, uint32_t*,
                    kTieringBudgetArrayOffset)
ACCESSORS(WasmInstanceObject, memory_bases_and_sizes, Tagged<FixedAddressArray>,
          kMemoryBasesAndSizesOffset)
ACCESSORS(WasmInstanceObject, data_segment_starts, Tagged<FixedAddressArray>,
          kDataSegmentStartsOffset)
ACCESSORS(WasmInstanceObject, data_segment_sizes, Tagged<FixedUInt32Array>,
          kDataSegmentSizesOffset)
ACCESSORS(WasmInstanceObject, element_segments, Tagged<FixedArray>,
          kElementSegmentsOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, break_on_entry, uint8_t,
                    kBreakOnEntryOffset)

ACCESSORS(WasmInstanceObject, module_object, Tagged<WasmModuleObject>,
          kModuleObjectOffset)
ACCESSORS(WasmInstanceObject, exports_object, Tagged<JSObject>,
          kExportsObjectOffset)
ACCESSORS(WasmInstanceObject, native_context, Tagged<Context>,
          kNativeContextOffset)
ACCESSORS(WasmInstanceObject, memory_objects, Tagged<FixedArray>,
          kMemoryObjectsOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, untagged_globals_buffer,
                   Tagged<JSArrayBuffer>, kUntaggedGlobalsBufferOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, tagged_globals_buffer,
                   Tagged<FixedArray>, kTaggedGlobalsBufferOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, imported_mutable_globals_buffers,
                   Tagged<FixedArray>, kImportedMutableGlobalsBuffersOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, tables, Tagged<FixedArray>,
                   kTablesOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, indirect_function_tables,
                   Tagged<FixedArray>, kIndirectFunctionTablesOffset)
ACCESSORS(WasmInstanceObject, imported_function_refs, Tagged<FixedArray>,
          kImportedFunctionRefsOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, indirect_function_table_refs,
                   Tagged<FixedArray>, kIndirectFunctionTableRefsOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, tags_table, Tagged<FixedArray>,
                   kTagsTableOffset)
ACCESSORS(WasmInstanceObject, wasm_internal_functions, Tagged<FixedArray>,
          kWasmInternalFunctionsOffset)
ACCESSORS(WasmInstanceObject, managed_object_maps, Tagged<FixedArray>,
          kManagedObjectMapsOffset)
ACCESSORS(WasmInstanceObject, feedback_vectors, Tagged<FixedArray>,
          kFeedbackVectorsOffset)
ACCESSORS(WasmInstanceObject, well_known_imports, Tagged<FixedArray>,
          kWellKnownImportsOffset)

void WasmInstanceObject::clear_padding() {
  if constexpr (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
    DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
    memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
           FIELD_SIZE(kOptionalPaddingOffset));
  }
}

Tagged<WasmMemoryObject> WasmInstanceObject::memory_object(
    int memory_index) const {
  return WasmMemoryObject::cast(memory_objects()->get(memory_index));
}

uint8_t* WasmInstanceObject::memory_base(int memory_index) const {
  DCHECK_EQ(memory0_start(),
            reinterpret_cast<uint8_t*>(
                memory_bases_and_sizes()->get_sandboxed_pointer(0)));
  return reinterpret_cast<uint8_t*>(
      memory_bases_and_sizes()->get_sandboxed_pointer(2 * memory_index));
}

size_t WasmInstanceObject::memory_size(int memory_index) const {
  DCHECK_EQ(memory0_size(), memory_bases_and_sizes()->get(1));
  return memory_bases_and_sizes()->get(2 * memory_index + 1);
}

ImportedFunctionEntry::ImportedFunctionEntry(
    Handle<WasmInstanceObject> instance, int index)
    : instance_(instance), index_(index) {
  DCHECK_GE(index, 0);
  DCHECK_LT(index, instance->module()->num_imported_functions);
}

// WasmExceptionPackage
OBJECT_CONSTRUCTORS_IMPL(WasmExceptionPackage, JSObject)
CAST_ACCESSOR(WasmExceptionPackage)

// WasmExportedFunction
WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) {
  SLOW_DCHECK(IsWasmExportedFunction(*this));
}
CAST_ACCESSOR(WasmExportedFunction)

// WasmInternalFunction
EXTERNAL_POINTER_ACCESSORS(WasmInternalFunction, call_target, Address,
                           kCallTargetOffset,
                           kWasmInternalFunctionCallTargetTag)

// WasmFunctionData
ACCESSORS(WasmFunctionData, internal, Tagged<WasmInternalFunction>,
          kInternalOffset)

EXTERNAL_POINTER_ACCESSORS(WasmExportedFunctionData, sig, wasm::FunctionSig*,
                           kSigOffset, kWasmExportedFunctionDataSignatureTag)

// WasmJSFunction
WasmJSFunction::WasmJSFunction(Address ptr) : JSFunction(ptr) {
  SLOW_DCHECK(IsWasmJSFunction(*this));
}
CAST_ACCESSOR(WasmJSFunction)

// WasmJSFunctionData
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmJSFunctionData)

// WasmCapiFunction
WasmCapiFunction::WasmCapiFunction(Address ptr) : JSFunction(ptr) {
  SLOW_DCHECK(IsWasmCapiFunction(*this));
}
CAST_ACCESSOR(WasmCapiFunction)

// WasmExternalFunction
WasmExternalFunction::WasmExternalFunction(Address ptr) : JSFunction(ptr) {
  SLOW_DCHECK(IsWasmExternalFunction(*this));
}
CAST_ACCESSOR(WasmExternalFunction)

// WasmIndirectFunctionTable
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmIndirectFunctionTable)
ACCESSORS(WasmIndirectFunctionTable, sig_ids, Tagged<FixedUInt32Array>,
          kSigIdsOffset)
ACCESSORS(WasmIndirectFunctionTable, targets, Tagged<ExternalPointerArray>,
          kTargetsOffset)

// WasmTypeInfo
EXTERNAL_POINTER_ACCESSORS(WasmTypeInfo, native_type, Address,
                           kNativeTypeOffset, kWasmTypeInfoNativeTypeTag)

#undef OPTIONAL_ACCESSORS
#undef READ_PRIMITIVE_FIELD
#undef WRITE_PRIMITIVE_FIELD
#undef PRIMITIVE_ACCESSORS
#undef SANDBOXED_POINTER_ACCESSORS

wasm::ValueType WasmTableObject::type() {
  return wasm::ValueType::FromRawBitField(raw_type());
}

bool WasmMemoryObject::has_maximum_pages() { return maximum_pages() >= 0; }

bool WasmMemoryObject::is_memory64() const {
  int memory64_smi_value =
      TorqueGeneratedWasmMemoryObject<WasmMemoryObject,
                                      JSObject>::is_memory64();
  DCHECK_LE(0, memory64_smi_value);
  DCHECK_GE(1, memory64_smi_value);
  return memory64_smi_value != 0;
}

// static
Handle<Object> WasmObject::ReadValueAt(Isolate* isolate, Handle<HeapObject> obj,
                                       wasm::ValueType type, uint32_t offset) {
  Address field_address = obj->GetFieldAddress(offset);
  switch (type.kind()) {
    case wasm::kI8: {
      int8_t value = base::Memory<int8_t>(field_address);
      return handle(Smi::FromInt(value), isolate);
    }
    case wasm::kI16: {
      int16_t value = base::Memory<int16_t>(field_address);
      return handle(Smi::FromInt(value), isolate);
    }
    case wasm::kI32: {
      int32_t value = base::Memory<int32_t>(field_address);
      return isolate->factory()->NewNumberFromInt(value);
    }
    case wasm::kI64: {
      int64_t value = base::ReadUnalignedValue<int64_t>(field_address);
      return BigInt::FromInt64(isolate, value);
    }
    case wasm::kF32: {
      float value = base::Memory<float>(field_address);
      return isolate->factory()->NewNumber(value);
    }
    case wasm::kF64: {
      double value = base::ReadUnalignedValue<double>(field_address);
      return isolate->factory()->NewNumber(value);
    }
    case wasm::kS128:
      // TODO(v8:11804): implement
      UNREACHABLE();

    case wasm::kRef:
    case wasm::kRefNull: {
      ObjectSlot slot(field_address);
      return handle(slot.load(isolate), isolate);
    }

    case wasm::kRtt:
      // Rtt values are not supposed to be made available to JavaScript side.
      UNREACHABLE();

    case wasm::kVoid:
    case wasm::kBottom:
      UNREACHABLE();
  }
}

// static
MaybeHandle<Object> WasmObject::ToWasmValue(Isolate* isolate,
                                            wasm::ValueType type,
                                            Handle<Object> value) {
  switch (type.kind()) {
    case wasm::kI8:
    case wasm::kI16:
    case wasm::kI32:
    case wasm::kF32:
    case wasm::kF64:
      return Object::ToNumber(isolate, value);

    case wasm::kI64:
      return BigInt::FromObject(isolate, value);

    case wasm::kRef:
    case wasm::kRefNull: {
      // TODO(v8:11804): implement ref type check
      UNREACHABLE();
    }

    case wasm::kS128:
      // TODO(v8:11804): implement
      UNREACHABLE();

    case wasm::kRtt:
      // Rtt values are not supposed to be made available to JavaScript side.
      UNREACHABLE();

    case wasm::kVoid:
    case wasm::kBottom:
      UNREACHABLE();
  }
}

// Conversions from Numeric objects.
// static
template <typename ElementType>
ElementType WasmObject::FromNumber(Tagged<Object> value) {
  // The value must already be prepared for storing to numeric fields.
  DCHECK(IsNumber(value));
  if (IsSmi(value)) {
    return static_cast<ElementType>(Smi::ToInt(value));

  } else if (IsHeapNumber(value)) {
    double double_value = HeapNumber::cast(value)->value();
    if (std::is_same<ElementType, double>::value ||
        std::is_same<ElementType, float>::value) {
      return static_cast<ElementType>(double_value);
    } else {
      CHECK(std::is_integral<ElementType>::value);
      return static_cast<ElementType>(DoubleToInt32(double_value));
    }
  }
  UNREACHABLE();
}

// static
void WasmObject::WriteValueAt(Isolate* isolate, Handle<HeapObject> obj,
                              wasm::ValueType type, uint32_t offset,
                              Handle<Object> value) {
  Address field_address = obj->GetFieldAddress(offset);
  switch (type.kind()) {
    case wasm::kI8: {
      auto scalar_value = FromNumber<int8_t>(*value);
      base::Memory<int8_t>(field_address) = scalar_value;
      break;
    }
    case wasm::kI16: {
      auto scalar_value = FromNumber<int16_t>(*value);
      base::Memory<int16_t>(field_address) = scalar_value;
      break;
    }
    case wasm::kI32: {
      auto scalar_value = FromNumber<int32_t>(*value);
      base::Memory<int32_t>(field_address) = scalar_value;
      break;
    }
    case wasm::kI64: {
      int64_t scalar_value = BigInt::cast(*value)->AsInt64();
      base::WriteUnalignedValue<int64_t>(field_address, scalar_value);
      break;
    }
    case wasm::kF32: {
      auto scalar_value = FromNumber<float>(*value);
      base::Memory<float>(field_address) = scalar_value;
      break;
    }
    case wasm::kF64: {
      auto scalar_value = FromNumber<double>(*value);
      base::WriteUnalignedValue<double>(field_address, scalar_value);
      break;
    }
    case wasm::kRef:
    case wasm::kRefNull:
      // TODO(v8:11804): implement
      UNREACHABLE();

    case wasm::kS128:
      // TODO(v8:11804): implement
      UNREACHABLE();

    case wasm::kRtt:
      // Rtt values are not supposed to be made available to JavaScript side.
      UNREACHABLE();

    case wasm::kVoid:
    case wasm::kBottom:
      UNREACHABLE();
  }
}

wasm::StructType* WasmStruct::type(Tagged<Map> map) {
  Tagged<WasmTypeInfo> type_info = map->wasm_type_info();
  return reinterpret_cast<wasm::StructType*>(type_info->native_type());
}

wasm::StructType* WasmStruct::GcSafeType(Tagged<Map> map) {
  DCHECK_EQ(WASM_STRUCT_TYPE, map->instance_type());
  Tagged<HeapObject> raw = HeapObject::cast(map->constructor_or_back_pointer());
  // The {WasmTypeInfo} might be in the middle of being moved, which is why we
  // can't read its map for a checked cast. But we can rely on its native type
  // pointer being intact in the old location.
  Tagged<WasmTypeInfo> type_info = WasmTypeInfo::unchecked_cast(raw);
  return reinterpret_cast<wasm::StructType*>(type_info->native_type());
}

int WasmStruct::Size(const wasm::StructType* type) {
  // Object size must fit into a Smi (because of filler objects), and its
  // computation must not overflow.
  static_assert(Smi::kMaxValue <= kMaxInt);
  DCHECK_LE(type->total_fields_size(), Smi::kMaxValue - kHeaderSize);
  return std::max(kHeaderSize + static_cast<int>(type->total_fields_size()),
                  Heap::kMinObjectSizeInTaggedWords * kTaggedSize);
}

// static
void WasmStruct::EncodeInstanceSizeInMap(int instance_size, Tagged<Map> map) {
  // WasmStructs can be bigger than the {map.instance_size_in_words} field
  // can describe; yet we have to store the instance size somewhere on the
  // map so that the GC can read it without relying on any other objects
  // still being around. To solve this problem, we store the instance size
  // in two other fields that are otherwise unused for WasmStructs.
  static_assert(0xFFFF > ((kHeaderSize + wasm::kMaxValueTypeSize *
                                             wasm::kV8MaxWasmStructFields) >>
                          kObjectAlignmentBits));
  map->SetWasmByte1((instance_size >> kObjectAlignmentBits) & 0xff);
  map->SetWasmByte2(instance_size >> (8 + kObjectAlignmentBits));
}

// static
int WasmStruct::DecodeInstanceSizeFromMap(Tagged<Map> map) {
  return (map->WasmByte2() << (8 + kObjectAlignmentBits)) |
         (map->WasmByte1() << kObjectAlignmentBits);
}

int WasmStruct::GcSafeSize(Tagged<Map> map) {
  return DecodeInstanceSizeFromMap(map);
}

wasm::StructType* WasmStruct::type() const { return type(map()); }

Address WasmStruct::RawFieldAddress(int raw_offset) {
  int offset = WasmStruct::kHeaderSize + raw_offset;
  return FIELD_ADDR(*this, offset);
}

ObjectSlot WasmStruct::RawField(int raw_offset) {
  return ObjectSlot(RawFieldAddress(raw_offset));
}

// static
Handle<Object> WasmStruct::GetField(Isolate* isolate, Handle<WasmStruct> obj,
                                    uint32_t field_index) {
  wasm::StructType* type = obj->type();
  CHECK_LT(field_index, type->field_count());
  wasm::ValueType field_type = type->field(field_index);
  int offset = WasmStruct::kHeaderSize + type->field_offset(field_index);
  return ReadValueAt(isolate, obj, field_type, offset);
}

// static
void WasmStruct::SetField(Isolate* isolate, Handle<WasmStruct> obj,
                          uint32_t field_index, Handle<Object> value) {
  wasm::StructType* type = obj->type();
  CHECK_LT(field_index, type->field_count());
  wasm::ValueType field_type = type->field(field_index);
  int offset = WasmStruct::kHeaderSize + type->field_offset(field_index);
  WriteValueAt(isolate, obj, field_type, offset, value);
}

wasm::ArrayType* WasmArray::type(Tagged<Map> map) {
  DCHECK_EQ(WASM_ARRAY_TYPE, map->instance_type());
  Tagged<WasmTypeInfo> type_info = map->wasm_type_info();
  return reinterpret_cast<wasm::ArrayType*>(type_info->native_type());
}

wasm::ArrayType* WasmArray::GcSafeType(Tagged<Map> map) {
  DCHECK_EQ(WASM_ARRAY_TYPE, map->instance_type());
  Tagged<HeapObject> raw = HeapObject::cast(map->constructor_or_back_pointer());
  // The {WasmTypeInfo} might be in the middle of being moved, which is why we
  // can't read its map for a checked cast. But we can rely on its native type
  // pointer being intact in the old location.
  Tagged<WasmTypeInfo> type_info = WasmTypeInfo::unchecked_cast(raw);
  return reinterpret_cast<wasm::ArrayType*>(type_info->native_type());
}

wasm::ArrayType* WasmArray::type() const { return type(map()); }

int WasmArray::SizeFor(Tagged<Map> map, int length) {
  int element_size = DecodeElementSizeFromMap(map);
  return kHeaderSize + RoundUp(element_size * length, kTaggedSize);
}

uint32_t WasmArray::element_offset(uint32_t index) {
  DCHECK_LE(index, length());
  return WasmArray::kHeaderSize +
         index * type()->element_type().value_kind_size();
}

Address WasmArray::ElementAddress(uint32_t index) {
  return ptr() + element_offset(index) - kHeapObjectTag;
}

ObjectSlot WasmArray::ElementSlot(uint32_t index) {
  DCHECK_LE(index, length());
  DCHECK(type()->element_type().is_reference());
  return RawField(kHeaderSize + kTaggedSize * index);
}

// static
Handle<Object> WasmArray::GetElement(Isolate* isolate, Handle<WasmArray> array,
                                     uint32_t index) {
  if (index >= array->length()) {
    return isolate->factory()->undefined_value();
  }
  wasm::ValueType element_type = array->type()->element_type();
  return ReadValueAt(isolate, array, element_type,
                     array->element_offset(index));
}

// static
void WasmArray::EncodeElementSizeInMap(int element_size, Tagged<Map> map) {
  map->SetWasmByte1(element_size);
}

// static
int WasmArray::DecodeElementSizeFromMap(Tagged<Map> map) {
  return map->WasmByte1();
}

EXTERNAL_POINTER_ACCESSORS(WasmContinuationObject, jmpbuf, Address,
                           kJmpbufOffset, kWasmContinuationJmpbufTag)

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

}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_WASM_OBJECTS_INL_H_

Zerion Mini Shell 1.0