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

extern class WasmInstanceObject extends JSObject;

extern class WasmExportedFunctionData extends Struct {
  wrapper_code: Code;
  instance: WasmInstanceObject;
  jump_table_offset: Smi;
  function_index: Smi;
  // The remaining fields are for fast calling from C++. The contract is
  // that they are lazily populated, and either all will be present or none.
  c_wrapper_code: Object;
  wasm_call_target: Smi|Foreign;
  packed_args_size: Smi;
}

extern class WasmJSFunctionData extends Struct {
  callable: JSReceiver;
  wrapper_code: Code;
  serialized_return_count: Smi;
  serialized_parameter_count: Smi;
  serialized_signature: ByteArray;  // PodArray<wasm::ValueType>
}

extern class WasmCapiFunctionData extends Struct {
  call_target: RawPtr;
  embedder_data: Foreign;  // Managed<wasm::FuncData>
  wrapper_code: Code;
  serialized_signature: ByteArray;  // PodArray<wasm::ValueType>
}

extern class WasmIndirectFunctionTable extends Struct {
  size: uint32;
  @if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
  @ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void;
  sig_ids: RawPtr;
  targets: RawPtr;
  managed_native_allocations: Foreign|Undefined;
  refs: FixedArray;
}

@generateCppClass
extern class WasmExceptionTag extends Struct {
  // Note that this index is only useful for debugging purposes and it is not
  // unique across modules. The GC however does not allow objects without at
  // least one field, hence this also serves as a padding field for now.
  index: Smi;
}

extern class WasmModuleObject extends JSObject {
  native_module: Foreign;
  export_wrappers: FixedArray;
  script: Script;
}

extern class WasmTableObject extends JSObject {
  entries: FixedArray;
  current_length: Smi;
  maximum_length: Smi|HeapNumber|Undefined;
  dispatch_tables: FixedArray;
  raw_type: Smi;
}

extern class WasmMemoryObject extends JSObject {
  array_buffer: JSArrayBuffer;
  maximum_pages: Smi;
  instances: WeakArrayList|Undefined;
}

type WasmValueType extends uint8 constexpr 'wasm::ValueType::Kind';

extern class WasmGlobalObject extends JSObject {
  untagged_buffer: JSArrayBuffer|Undefined;
  tagged_buffer: FixedArray|Undefined;
  offset: Smi;
  raw_type: Smi;
  is_mutable: Smi;
}

extern class WasmExceptionObject extends JSObject {
  serialized_signature: ByteArray;  // PodArray<wasm::ValueType>
  exception_tag: HeapObject;
}

type WasmExportedFunction extends JSFunction;

extern class AsmWasmData extends Struct {
  managed_native_module: Foreign;  // Managed<wasm::NativeModule>
  export_wrappers: FixedArray;
  uses_bitset: HeapNumber;
}

@generateCppClass
extern class WasmTypeInfo extends Foreign {
  parent: Map;
  subtypes: ArrayList;
}

@generateCppClass
extern class WasmStruct extends HeapObject {
}

@generateCppClass
extern class WasmArray extends HeapObject {
  length: uint32;

  @if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
  @ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void;
}
