// Generated by tools/generate_wasm_opcodes.py from wasm_opcodes.schema.
// DO NOT EDIT. Update the schema and run a Moon development command.

///|
pub(all) enum WasmOpcode {
  WasmCall(Int)
  WasmCallIndirect(Int, Int)
  CallRef(Int)
  ReturnCall(Int)
  ReturnCallIndirect(Int, Int)
  ReturnCallRef(Int)
  GetFuncRef(Int)
  StructNew(Int)
  StructNewDefault(Int)
  StructGet(Int, Int)
  StructGetS(Int, Int, Int)
  StructGetU(Int, Int, Int)
  StructSet(Int, Int)
  ArrayNew(Int)
  ArrayNewDefault(Int)
  ArrayNewFixed(Int, Int)
  ArrayGet(Int)
  ArrayGetS(Int, Int)
  ArrayGetU(Int, Int)
  ArraySet(Int)
  ArrayLen
  ArrayFill(Int)
  ArrayCopy(Int, Int)
  ArrayNewData(Int, Int)
  ArrayNewElem(Int, Int)
  ArrayInitData(Int, Int)
  ArrayInitElem(Int, Int)
  I31New
  I31GetS
  I31GetU
  RefTest(Int, Bool)
  RefCast(Int, Bool)
  AnyConvertExtern
  ExternConvertAny
  RefEq
  Throw(Int)
  ThrowRef
  TryTableBegin(Int)
  TryTableEnd(Int)
  GetExceptionTag
  GetExceptionValue(Int)
  GetExceptionValueCount
  Delegate(Int)
  SpillLocalsForThrow(Int)
  GetSpilledLocal(Int)
} derive(Debug, Eq, Hash)

///|
let wasm_opcode_specs : Array[WasmOpcodeSpec] = [
  {
    id: 0,
    typed_constructor: "WasmCall",
    wire_name: "call",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: true,
    variadic_results: true,
  },
  {
    id: 1,
    typed_constructor: "WasmCallIndirect",
    wire_name: "call_indirect",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [IntegerType],
    result_types: [],
    variadic_operands: true,
    variadic_results: true,
  },
  {
    id: 2,
    typed_constructor: "CallRef",
    wire_name: "call_ref",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(CallableRef)],
    result_types: [],
    variadic_operands: true,
    variadic_results: true,
  },
  {
    id: 3,
    typed_constructor: "ReturnCall",
    wire_name: "return_call",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 4,
    typed_constructor: "ReturnCallIndirect",
    wire_name: "return_call_indirect",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [IntegerType],
    result_types: [],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 5,
    typed_constructor: "ReturnCallRef",
    wire_name: "return_call_ref",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(CallableRef)],
    result_types: [],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 6,
    typed_constructor: "GetFuncRef",
    wire_name: "get_func_ref",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(CallableRef)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 7,
    typed_constructor: "StructNew",
    wire_name: "struct_new",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(Ref)],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 8,
    typed_constructor: "StructNewDefault",
    wire_name: "struct_new_default",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 9,
    typed_constructor: "StructGet",
    wire_name: "struct_get",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(Ref)],
    result_types: [ContextualType],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 10,
    typed_constructor: "StructGetS",
    wire_name: "struct_get_s",
    immediate_kinds: [IntegerImmediate, IntegerImmediate, PackedWidthImmediate],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 11,
    typed_constructor: "StructGetU",
    wire_name: "struct_get_u",
    immediate_kinds: [IntegerImmediate, IntegerImmediate, PackedWidthImmediate],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 12,
    typed_constructor: "StructSet",
    wire_name: "struct_set",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(Ref), ContextualType],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 13,
    typed_constructor: "ArrayNew",
    wire_name: "array_new",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ContextualType, ExactType(I32)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 14,
    typed_constructor: "ArrayNewDefault",
    wire_name: "array_new_default",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(I32)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 15,
    typed_constructor: "ArrayNewFixed",
    wire_name: "array_new_fixed",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(Ref)],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 16,
    typed_constructor: "ArrayGet",
    wire_name: "array_get",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32)],
    result_types: [ContextualType],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 17,
    typed_constructor: "ArrayGetS",
    wire_name: "array_get_s",
    immediate_kinds: [IntegerImmediate, PackedWidthImmediate],
    operand_types: [ExactType(Ref), ExactType(I32)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 18,
    typed_constructor: "ArrayGetU",
    wire_name: "array_get_u",
    immediate_kinds: [IntegerImmediate, PackedWidthImmediate],
    operand_types: [ExactType(Ref), ExactType(I32)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 19,
    typed_constructor: "ArraySet",
    wire_name: "array_set",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32), ContextualType],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 20,
    typed_constructor: "ArrayLen",
    wire_name: "array_len",
    immediate_kinds: [],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 21,
    typed_constructor: "ArrayFill",
    wire_name: "array_fill",
    immediate_kinds: [IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32), ContextualType, ExactType(I32)],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 22,
    typed_constructor: "ArrayCopy",
    wire_name: "array_copy",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32), ExactType(Ref), ExactType(I32), ExactType(I32)],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 23,
    typed_constructor: "ArrayNewData",
    wire_name: "array_new_data",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(I32), ExactType(I32)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 24,
    typed_constructor: "ArrayNewElem",
    wire_name: "array_new_elem",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(I32), ExactType(I32)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 25,
    typed_constructor: "ArrayInitData",
    wire_name: "array_init_data",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32), ExactType(I32), ExactType(I32)],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 26,
    typed_constructor: "ArrayInitElem",
    wire_name: "array_init_elem",
    immediate_kinds: [IntegerImmediate, IntegerImmediate],
    operand_types: [ExactType(Ref), ExactType(I32), ExactType(I32), ExactType(I32)],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 27,
    typed_constructor: "I31New",
    wire_name: "i31_new",
    immediate_kinds: [],
    operand_types: [ExactType(I32)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 28,
    typed_constructor: "I31GetS",
    wire_name: "i31_get_s",
    immediate_kinds: [],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 29,
    typed_constructor: "I31GetU",
    wire_name: "i31_get_u",
    immediate_kinds: [],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 30,
    typed_constructor: "RefTest",
    wire_name: "ref_test",
    immediate_kinds: [IntegerImmediate, BooleanImmediate],
    operand_types: [ReferenceLike],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 31,
    typed_constructor: "RefCast",
    wire_name: "ref_cast",
    immediate_kinds: [IntegerImmediate, BooleanImmediate],
    operand_types: [ReferenceLike],
    result_types: [ReferenceLike],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 32,
    typed_constructor: "AnyConvertExtern",
    wire_name: "any_convert_extern",
    immediate_kinds: [],
    operand_types: [ExactType(OpaqueRef)],
    result_types: [ExactType(Ref)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 33,
    typed_constructor: "ExternConvertAny",
    wire_name: "extern_convert_any",
    immediate_kinds: [],
    operand_types: [ExactType(Ref)],
    result_types: [ExactType(OpaqueRef)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 34,
    typed_constructor: "RefEq",
    wire_name: "ref_eq",
    immediate_kinds: [],
    operand_types: [ReferenceLike, ReferenceLike],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 35,
    typed_constructor: "Throw",
    wire_name: "throw",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 36,
    typed_constructor: "ThrowRef",
    wire_name: "throw_ref",
    immediate_kinds: [],
    operand_types: [ReferenceLike],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 37,
    typed_constructor: "TryTableBegin",
    wire_name: "try_table_begin",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 38,
    typed_constructor: "TryTableEnd",
    wire_name: "try_table_end",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 39,
    typed_constructor: "GetExceptionTag",
    wire_name: "get_exception_tag",
    immediate_kinds: [],
    operand_types: [],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 40,
    typed_constructor: "GetExceptionValue",
    wire_name: "get_exception_value",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(I64)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 41,
    typed_constructor: "GetExceptionValueCount",
    wire_name: "get_exception_value_count",
    immediate_kinds: [],
    operand_types: [],
    result_types: [ExactType(I32)],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 42,
    typed_constructor: "Delegate",
    wire_name: "delegate",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: false,
    variadic_results: false,
  },
  {
    id: 43,
    typed_constructor: "SpillLocalsForThrow",
    wire_name: "spill_locals_for_throw",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [],
    variadic_operands: true,
    variadic_results: false,
  },
  {
    id: 44,
    typed_constructor: "GetSpilledLocal",
    wire_name: "get_spilled_local",
    immediate_kinds: [IntegerImmediate],
    operand_types: [],
    result_types: [ExactType(I64)],
    variadic_operands: false,
    variadic_results: false,
  },
]

///|
fn opcode_payload(opcode : WasmOpcode) -> (Int, FixedArray[Int]) {
  match opcode {
    WasmCall(imm0) => (0, imm([imm0]))
    WasmCallIndirect(imm0, imm1) => (1, imm([imm0, imm1]))
    CallRef(imm0) => (2, imm([imm0]))
    ReturnCall(imm0) => (3, imm([imm0]))
    ReturnCallIndirect(imm0, imm1) => (4, imm([imm0, imm1]))
    ReturnCallRef(imm0) => (5, imm([imm0]))
    GetFuncRef(imm0) => (6, imm([imm0]))
    StructNew(imm0) => (7, imm([imm0]))
    StructNewDefault(imm0) => (8, imm([imm0]))
    StructGet(imm0, imm1) => (9, imm([imm0, imm1]))
    StructGetS(imm0, imm1, imm2) => (10, imm([imm0, imm1, imm2]))
    StructGetU(imm0, imm1, imm2) => (11, imm([imm0, imm1, imm2]))
    StructSet(imm0, imm1) => (12, imm([imm0, imm1]))
    ArrayNew(imm0) => (13, imm([imm0]))
    ArrayNewDefault(imm0) => (14, imm([imm0]))
    ArrayNewFixed(imm0, imm1) => (15, imm([imm0, imm1]))
    ArrayGet(imm0) => (16, imm([imm0]))
    ArrayGetS(imm0, imm1) => (17, imm([imm0, imm1]))
    ArrayGetU(imm0, imm1) => (18, imm([imm0, imm1]))
    ArraySet(imm0) => (19, imm([imm0]))
    ArrayLen => (20, imm([]))
    ArrayFill(imm0) => (21, imm([imm0]))
    ArrayCopy(imm0, imm1) => (22, imm([imm0, imm1]))
    ArrayNewData(imm0, imm1) => (23, imm([imm0, imm1]))
    ArrayNewElem(imm0, imm1) => (24, imm([imm0, imm1]))
    ArrayInitData(imm0, imm1) => (25, imm([imm0, imm1]))
    ArrayInitElem(imm0, imm1) => (26, imm([imm0, imm1]))
    I31New => (27, imm([]))
    I31GetS => (28, imm([]))
    I31GetU => (29, imm([]))
    RefTest(imm0, imm1) => (30, imm([imm0, bool_imm(imm1)]))
    RefCast(imm0, imm1) => (31, imm([imm0, bool_imm(imm1)]))
    AnyConvertExtern => (32, imm([]))
    ExternConvertAny => (33, imm([]))
    RefEq => (34, imm([]))
    Throw(imm0) => (35, imm([imm0]))
    ThrowRef => (36, imm([]))
    TryTableBegin(imm0) => (37, imm([imm0]))
    TryTableEnd(imm0) => (38, imm([imm0]))
    GetExceptionTag => (39, imm([]))
    GetExceptionValue(imm0) => (40, imm([imm0]))
    GetExceptionValueCount => (41, imm([]))
    Delegate(imm0) => (42, imm([imm0]))
    SpillLocalsForThrow(imm0) => (43, imm([imm0]))
    GetSpilledLocal(imm0) => (44, imm([imm0]))
  }
}

///|
fn opcode_from_payload(
  id : Int,
  imms : FixedArray[Int],
) -> WasmOpcode? {
  match id {
    0 => Some(WasmCall(imms[0]))
    1 => Some(WasmCallIndirect(imms[0], imms[1]))
    2 => Some(CallRef(imms[0]))
    3 => Some(ReturnCall(imms[0]))
    4 => Some(ReturnCallIndirect(imms[0], imms[1]))
    5 => Some(ReturnCallRef(imms[0]))
    6 => Some(GetFuncRef(imms[0]))
    7 => Some(StructNew(imms[0]))
    8 => Some(StructNewDefault(imms[0]))
    9 => Some(StructGet(imms[0], imms[1]))
    10 => Some(StructGetS(imms[0], imms[1], imms[2]))
    11 => Some(StructGetU(imms[0], imms[1], imms[2]))
    12 => Some(StructSet(imms[0], imms[1]))
    13 => Some(ArrayNew(imms[0]))
    14 => Some(ArrayNewDefault(imms[0]))
    15 => Some(ArrayNewFixed(imms[0], imms[1]))
    16 => Some(ArrayGet(imms[0]))
    17 => Some(ArrayGetS(imms[0], imms[1]))
    18 => Some(ArrayGetU(imms[0], imms[1]))
    19 => Some(ArraySet(imms[0]))
    20 => Some(ArrayLen)
    21 => Some(ArrayFill(imms[0]))
    22 => Some(ArrayCopy(imms[0], imms[1]))
    23 => Some(ArrayNewData(imms[0], imms[1]))
    24 => Some(ArrayNewElem(imms[0], imms[1]))
    25 => Some(ArrayInitData(imms[0], imms[1]))
    26 => Some(ArrayInitElem(imms[0], imms[1]))
    27 => Some(I31New)
    28 => Some(I31GetS)
    29 => Some(I31GetU)
    30 => Some(RefTest(imms[0], imm_bool(imms[1])))
    31 => Some(RefCast(imms[0], imm_bool(imms[1])))
    32 => Some(AnyConvertExtern)
    33 => Some(ExternConvertAny)
    34 => Some(RefEq)
    35 => Some(Throw(imms[0]))
    36 => Some(ThrowRef)
    37 => Some(TryTableBegin(imms[0]))
    38 => Some(TryTableEnd(imms[0]))
    39 => Some(GetExceptionTag)
    40 => Some(GetExceptionValue(imms[0]))
    41 => Some(GetExceptionValueCount)
    42 => Some(Delegate(imms[0]))
    43 => Some(SpillLocalsForThrow(imms[0]))
    44 => Some(GetSpilledLocal(imms[0]))
    _ => None
  }
}