/*
 * Copyright (c) 2026-present, the Ladybird developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

/* Generated with cbindgen:0.29.2 */

#include <stdint.h>
#include <stddef.h>

namespace Wasm {
namespace Cranelift {

constexpr static const uint32_t HELPER_COUNT = 32;

/// Stable index assigned to each runtime helper. Embedded in cranelift `ExternalName`
/// entries so we can recover, post-codegen, which helper a given relocation targets.
/// The numeric values are part of the cache blob format -- do NOT reorder.
enum class HelperId : uint32_t {
    call_function = 0,
    set_trap = 1,
    memory_load8_s = 2,
    memory_load8_u = 3,
    memory_load16_s = 4,
    memory_load16_u = 5,
    memory_load32_s = 6,
    memory_load32_u = 7,
    memory_load64 = 8,
    memory_store8 = 9,
    memory_store16 = 10,
    memory_store32 = 11,
    memory_store64 = 12,
    memory_size = 13,
    memory_grow = 14,
    read_global = 15,
    write_global = 16,
    stack_push = 17,
    stack_pop = 18,
    stack_size = 19,
    stack_cleanup = 20,
    callrec_read = 21,
    callrec_write = 22,
    call_with_record = 23,
    direct_call_0 = 24,
    direct_call_1 = 25,
    direct_call_2 = 26,
    direct_call_3 = 27,
    call_indirect = 28,
    memory_copy = 29,
    memory_fill = 30,
    primitive_storage_cage_base = 31,
};

/// Immediates:
///   constants:    imm1 = value (i32 sign-extended, i64, or f32/f64 bits)
///   local ops:    imm1 = local index
///   branch:       imm1 = label index (from control stack)
///   block/loop:   imm1 = end_ip, imm2 = else_ip (-1 if none), imm3 = arity | (param_count << 16)
///   call:         imm1 = function index
///   memory ops:   imm1 = offset, imm3 = memory index
struct CraneliftInsn {
    uint64_t opcode;
    uint8_t sources[3];
    uint8_t destination;
    int64_t imm1;
    int64_t imm2;
    uint32_t imm3;
    uint32_t _pad;
};

struct RuntimeHelpers {
    size_t call_function;
    size_t set_trap;
    size_t memory_load8_s;
    size_t memory_load8_u;
    size_t memory_load16_s;
    size_t memory_load16_u;
    size_t memory_load32_s;
    size_t memory_load32_u;
    size_t memory_load64;
    size_t memory_store8;
    size_t memory_store16;
    size_t memory_store32;
    size_t memory_store64;
    size_t memory_size;
    size_t memory_grow;
    size_t read_global;
    size_t write_global;
    size_t stack_push;
    size_t stack_pop;
    size_t stack_size;
    size_t stack_cleanup;
    size_t callrec_read;
    size_t callrec_write;
    size_t call_with_record;
    size_t direct_call_0;
    size_t direct_call_1;
    size_t direct_call_2;
    size_t direct_call_3;
    size_t call_indirect;
    size_t memory_copy;
    size_t memory_fill;
    size_t primitive_storage_cage_base;
    size_t primitive_storage_cage_offset_mask;
    uint32_t regs_offset;
    uint32_t value_size;
    uint32_t locals_base_offset;
    uint32_t default_memory_offset;
    uint32_t memory_instance_data_offset;
    uint32_t memory_buffer_size_offset;
    uint32_t memory_buffer_storage_offset_offset;
    uint32_t compiled_call_result_scratch_offset;
};

/// One relocation slot in the generated machine code. `code_offset` is the byte offset
/// from the start of the function where 8 contiguous bytes hold the absolute helper
/// address; on cache install, those bytes get rewritten to the current process's
/// helper pointer.
struct HelperReloc {
    uint32_t code_offset;
    uint32_t helper_id;
    int64_t addend;
};

}  // namespace Cranelift
}  // namespace Wasm
