/*
 * 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 JS {
namespace FFI {

constexpr static const int32_t FinallyContext_NORMAL = 0;

constexpr static const int32_t FinallyContext_THROW = 1;

constexpr static const int32_t FinallyContext_RETURN = 2;

constexpr static const int32_t FinallyContext_FIRST_JUMP_INDEX = 3;

constexpr static const uint32_t Register_RESERVED_COUNT = 5;

constexpr static const uint32_t StringTableIndex_INVALID = 4294967295;

constexpr static const uint32_t IdentifierTableIndex_INVALID = 4294967295;

constexpr static const uint32_t EnvironmentCoordinate_INVALID = 4294967294;

/// Categorization of validation failures, mirrored to C++ as an enum class.
enum class ValidationErrorKind : uint32_t {
    Ok = 0,
    BufferNotAligned = 1,
    InstructionMisaligned = 2,
    UnknownOpcode = 3,
    TruncatedInstruction = 4,
    InvalidLength = 5,
    OperandOutOfRange = 6,
    OperandInvalid = 7,
    LabelNotAtInstructionBoundary = 8,
    IdentifierIndexOutOfRange = 9,
    StringIndexOutOfRange = 10,
    PropertyKeyIndexOutOfRange = 11,
    RegexIndexOutOfRange = 12,
    PropertyLookupCacheIndexOutOfRange = 13,
    GlobalVariableCacheIndexOutOfRange = 14,
    TemplateObjectCacheIndexOutOfRange = 15,
    ObjectShapeCacheIndexOutOfRange = 16,
    ObjectPropertyIteratorCacheIndexOutOfRange = 17,
    SharedFunctionDataIndexOutOfRange = 18,
    ClassBlueprintIndexOutOfRange = 19,
    EnumOutOfRange = 20,
    BasicBlockOffsetInvalid = 21,
    ExceptionHandlerStartInvalid = 22,
    ExceptionHandlerEndInvalid = 23,
    ExceptionHandlerHandlerInvalid = 24,
    ExceptionHandlerRangeInvalid = 25,
    SourceMapOffsetInvalid = 26,
};

/// Literal value kind for class field initializers
enum class LiteralValueKind : uint8_t {
    None = 0,
    Number = 1,
    BooleanTrue = 2,
    BooleanFalse = 3,
    Null = 4,
    String = 5,
};

/// NativeJavaScriptBackedFunction intrinsic IDs resolved by C++ when materializing an Executable.
enum class AbstractOperationKind : uint8_t {
    AsyncIteratorClose = 0,
    GetMethod = 1,
    GetIteratorDirect = 2,
    GetIteratorFromMethod = 3,
    IteratorComplete = 4,
};

/// Constant tags for the FFI constant buffer (ABI-compatible).
enum class ConstantTag : uint8_t {
    Number = 0,
    BooleanTrue = 1,
    BooleanFalse = 2,
    Null = 3,
    Undefined = 4,
    Empty = 5,
    String = 6,
    BigInt = 7,
    WellKnownSymbol = 8,
    AbstractOperation = 9,
};

/// Well-known symbol IDs resolved by C++ when materializing an Executable.
enum class WellKnownSymbolKind : uint8_t {
    SymbolIterator = 0,
    SymbolAsyncIterator = 1,
};

struct CompiledFunction;

struct CompiledProgram;

struct DecodedBytecodeCacheBlob;

/// A parsed program (script or module) that can be compiled later.
/// Contains no GC references, so it can safely be transferred between threads.
struct ParsedProgram;

/// A bytecode register index.
///
/// Reserved registers:
/// - 0: accumulator
/// - 1: exception
/// - 2: this_value
/// - 3: return_value
/// - 4: saved_lexical_environment
/// - 5+: user registers
struct Register;

/// Callback type for reporting parse errors to C++.
using ParseErrorCallback = void(*)(void *ctx, const uint8_t *message, size_t message_len, uint32_t line, uint32_t column);

struct BytecodeCacheBlob {
    uint8_t *data;
    size_t length;
};

/// Callback types for module compilation.
using ModuleBoolCallback = void(*)(void *ctx, bool value);

/// A borrowed UTF-16 string slice for passing across FFI.
/// Points into Rust-owned memory; valid only for the duration of the FFI call.
struct FFIUtf16Slice {
    const uint16_t *data;
    size_t length;
};

using ModuleImportEntryCallback = void(*)(void *ctx,
                                          const uint16_t *import_name,
                                          size_t import_name_len,
                                          bool is_namespace,
                                          const uint16_t *local_name,
                                          size_t local_name_len,
                                          const uint16_t *module_specifier,
                                          size_t specifier_len,
                                          const FFIUtf16Slice *attribute_keys,
                                          const FFIUtf16Slice *attribute_values,
                                          size_t attribute_count);

using ModuleExportEntryCallback = void(*)(void *ctx,
                                          uint8_t kind,
                                          const uint16_t *export_name,
                                          size_t export_name_len,
                                          const uint16_t *local_or_import_name,
                                          size_t local_or_import_name_len,
                                          const uint16_t *module_specifier,
                                          size_t specifier_len,
                                          const FFIUtf16Slice *attribute_keys,
                                          const FFIUtf16Slice *attribute_values,
                                          size_t attribute_count);

using ModuleRequestedModuleCallback = void(*)(void *ctx,
                                              const uint16_t *specifier,
                                              size_t specifier_len,
                                              const FFIUtf16Slice *attribute_keys,
                                              const FFIUtf16Slice *attribute_values,
                                              size_t attribute_count);

using ModuleNameCallback = void(*)(void *ctx, const uint16_t *name, size_t name_len);

using ModuleFunctionCallback = void(*)(void *ctx, void *sfd_ptr, const uint16_t *name, size_t name_len);

using ModuleLexicalBindingCallback = void(*)(void *ctx,
                                             const uint16_t *name,
                                             size_t name_len,
                                             bool is_constant,
                                             int32_t function_index);

/// Module callback table passed from C++ to avoid many function pointer parameters.
struct ModuleCallbacks {
    ModuleBoolCallback set_has_top_level_await;
    ModuleImportEntryCallback push_import_entry;
    ModuleExportEntryCallback push_local_export;
    ModuleExportEntryCallback push_indirect_export;
    ModuleExportEntryCallback push_star_export;
    ModuleRequestedModuleCallback push_requested_module;
    ModuleNameCallback set_default_export_binding;
    ModuleNameCallback push_var_name;
    ModuleFunctionCallback push_function;
    ModuleLexicalBindingCallback push_lexical_binding;
};

/// Callback type for reporting builtin file functions to C++.
using BuiltinFunctionCallback = void(*)(void *ctx, void *sfd_ptr, const uint16_t *name, size_t name_len);

/// C-compatible token info for the tokenize callback.
struct FFIToken {
    uint8_t token_type;
    uint8_t category;
    uint32_t offset;
    uint32_t length;
    uint32_t trivia_offset;
    uint32_t trivia_length;
};

/// Bounds against which bytecode references are checked.
struct FFIValidatorBounds {
    uint32_t number_of_registers;
    uint32_t number_of_locals;
    uint32_t number_of_constants;
    uint32_t number_of_arguments;
    uint32_t identifier_table_size;
    uint32_t string_table_size;
    uint32_t property_key_table_size;
    uint32_t regex_table_size;
    uint32_t property_lookup_cache_count;
    uint32_t global_variable_cache_count;
    uint32_t template_object_cache_count;
    uint32_t object_shape_cache_count;
    uint32_t object_property_iterator_cache_count;
    uint32_t class_blueprint_count;
    uint32_t shared_function_data_count;
    /// Variant counts for the C++ enum types referenced by Bytecode.def
    /// fields. Plumbed across the FFI rather than hardcoded so that adding
    /// or removing a variant in the C++ enum can't silently outdate the
    /// Rust validator.
    uint32_t completion_type_variant_count;
    uint32_t iterator_hint_variant_count;
    uint32_t environment_mode_variant_count;
    uint32_t put_kind_variant_count;
    uint32_t arguments_kind_variant_count;
    /// If true, m_cache fields hold indices that should be range-checked
    /// against the corresponding cache_count. If false, the cache fixup
    /// pass has already replaced them with real pointers and they are
    /// skipped during validation.
    bool before_cache_fixup;
};

/// Layout-compatible mirror of `Bytecode::Executable::ExceptionHandlers`,
/// flattened to plain offsets for FFI.
struct FFIExceptionHandlerOffsets {
    uint32_t start;
    uint32_t end;
    uint32_t handler;
};

/// Structural metadata that lives on `Executable` alongside the bytecode
/// itself. Every offset must point at an instruction boundary; some endpoints
/// (handler ranges, source map entries) may also be one-past-the-last
/// instruction so that "end of bytecode" is representable.
struct FFIValidatorExtras {
    const uint32_t *basic_block_offsets;
    size_t basic_block_count;
    const FFIExceptionHandlerOffsets *exception_handlers;
    size_t exception_handler_count;
    const uint32_t *source_map_offsets;
    size_t source_map_count;
};

/// Detail returned to the C++ caller on validation failure.
struct FFIValidationError {
    ValidationErrorKind kind;
    uint32_t offset;
    uint32_t opcode;
};

/// Exception handler range (C++ `BytecodeFactory::ExceptionHandlerData`).
struct FFIExceptionHandler {
    uint32_t start_offset;
    uint32_t end_offset;
    uint32_t handler_offset;
};

/// Source map entry mapping bytecode offset to source position.
struct FFISourceMapEntry {
    uint32_t bytecode_offset;
    uint32_t source_start_line;
    uint32_t source_start_column;
};

/// C-compatible `Optional<u32>` (C++ doesn't have a standard Optional ABI).
struct FFIOptionalU32 {
    uint32_t value;
    bool has_value;
};

/// All data needed to create a C++ `Bytecode::Executable`.
/// Passed to `rust_create_executable()`.
struct FFIExecutableData {
    const uint8_t *bytecode;
    size_t bytecode_length;
    const FFIUtf16Slice *identifier_table;
    size_t identifier_count;
    const FFIUtf16Slice *property_key_table;
    size_t property_key_count;
    const FFIUtf16Slice *string_table;
    size_t string_count;
    const uint8_t *constants_data;
    size_t constants_data_length;
    size_t constants_count;
    const FFIExceptionHandler *exception_handlers;
    size_t exception_handler_count;
    const FFISourceMapEntry *source_map;
    size_t source_map_count;
    const size_t *basic_block_offsets;
    size_t basic_block_count;
    const FFIUtf16Slice *local_variable_names;
    size_t local_variable_count;
    uint32_t property_lookup_cache_count;
    uint32_t global_variable_cache_count;
    uint32_t template_object_cache_count;
    uint32_t object_shape_cache_count;
    uint32_t object_property_iterator_cache_count;
    uint32_t number_of_registers;
    uint32_t number_of_arguments;
    bool is_strict;
    FFIOptionalU32 length_identifier;
    const void *const *shared_function_data;
    size_t shared_function_data_count;
    void *const *class_blueprints;
    size_t class_blueprint_count;
    void *const *compiled_regexes;
    size_t regex_count;
};

/// Data for creating a C++ `SharedFunctionInstanceData`.
/// Passed to `rust_create_sfd()`.
struct FFISharedFunctionData {
    const uint16_t *name;
    size_t name_len;
    uint8_t function_kind;
    int32_t function_length;
    uint32_t formal_parameter_count;
    bool strict;
    bool is_arrow;
    bool has_simple_parameter_list;
    const FFIUtf16Slice *parameter_names;
    size_t parameter_name_count;
    size_t source_text_offset;
    size_t source_text_length;
    void *rust_function_ast;
    bool uses_this;
    bool uses_this_from_environment;
};

/// Class element descriptor for ClassBlueprint creation
/// (C++ `BytecodeFactory::ClassElementData`).
struct FFIClassElement {
    uint8_t kind;
    bool is_static;
    bool is_private;
    const uint16_t *private_identifier;
    size_t private_identifier_len;
    FFIOptionalU32 shared_function_data_index;
    bool has_initializer;
    LiteralValueKind literal_value_kind;
    double literal_value_number;
    const uint16_t *literal_value_string;
    size_t literal_value_string_len;
};











extern "C" {

/// Parse a program (script or module) without any GC interaction.
///
/// Lexes, parses, and runs scope analysis. The result is a `ParsedProgram`
/// that can be compiled later via `rust_compile_parsed_script()` or
/// `rust_compile_parsed_module()`.
///
/// `program_type`: 0 = Script, 1 = Module.
///
/// Returns nullptr if `source` is null. Otherwise returns a non-null
/// pointer. Caller must check for errors via
/// `rust_parsed_program_has_errors()` before compiling.
///
/// # Safety
/// - `source` must point to a valid UTF-16 buffer of `source_len` elements.
ParsedProgram *rust_parse_program(const uint16_t *source,
                                  size_t source_len,
                                  uint8_t program_type,
                                  size_t initial_line_number,
                                  bool dump_ast,
                                  bool use_color);

/// Check whether a ParsedProgram has parse errors.
///
/// # Safety
/// `parsed` must be a valid pointer from `rust_parse_program()`.
bool rust_parsed_program_has_errors(const ParsedProgram *parsed);

/// Report parse errors from a ParsedProgram via callback, then clear them.
///
/// Calls `error_callback` for each error with the same signature as
/// `ParseErrorCallback`.
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()`.
/// - `error_callback` must be a valid function pointer.
void rust_parsed_program_take_errors(ParsedProgram *parsed, void *error_context, ParseErrorCallback error_callback);

/// Free a ParsedProgram without compiling it.
///
/// # Safety
/// `parsed` must be a valid pointer from `rust_parse_program()`.
void rust_free_parsed_program(ParsedProgram *parsed);

/// Compile a parsed program to an off-thread bytecode artifact.
///
/// Consumes and frees the ParsedProgram. The returned CompiledProgram still needs to be materialized on the main thread
/// before it becomes a GC-backed Executable.
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()` with no errors.
CompiledProgram *rust_compile_parsed_program_off_thread(ParsedProgram *parsed, size_t source_len);

/// Fully compile a parsed program to an off-thread bytecode artifact for persistence.
///
/// This is intended for post-handoff cache generation, not the latency-sensitive
/// path that produces bytecode for immediate execution.
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()` with no errors.
CompiledProgram *rust_compile_parsed_program_fully_off_thread(ParsedProgram *parsed, size_t source_len);

/// Free a CompiledProgram without materializing it.
///
/// # Safety
/// `compiled` must be a valid pointer from `rust_compile_parsed_program_off_thread()`.
void rust_free_compiled_program(CompiledProgram *compiled);

/// Serialize a fully compiled program into a versioned bytecode cache blob.
///
/// The caller owns the returned bytes and must release them with
/// `rust_free_bytecode_cache_blob()`.
///
/// # Safety
/// `compiled` must be a valid pointer from `rust_compile_parsed_program_fully_off_thread()`.
BytecodeCacheBlob rust_serialize_compiled_program_for_bytecode_cache(const CompiledProgram *compiled,
                                                                     uint8_t program_type,
                                                                     const uint8_t *source_hash,
                                                                     size_t source_hash_len);

/// Free a bytecode cache blob returned by `rust_serialize_compiled_program_for_bytecode_cache()`.
///
/// # Safety
/// `data` and `length` must match a blob returned by Rust.
void rust_free_bytecode_cache_blob(uint8_t *data, size_t length);

/// Decode a bytecode cache blob into an owned parser-free cache handle.
///
/// # Safety
/// `data` must point to `length` readable bytes.
DecodedBytecodeCacheBlob *rust_decode_bytecode_cache_blob(const uint8_t *data,
                                                          size_t length,
                                                          uint8_t expected_program_type,
                                                          const uint8_t *expected_source_hash,
                                                          size_t expected_source_hash_len);

/// Free a decoded bytecode cache blob.
///
/// # Safety
/// `blob` must be a valid pointer from `rust_decode_bytecode_cache_blob()`.
void rust_free_decoded_bytecode_cache_blob(DecodedBytecodeCacheBlob *blob);

/// Materialize a decoded script bytecode cache blob. Consumes and frees the blob.
///
/// # Safety
/// - `blob` must be a valid pointer from `rust_decode_bytecode_cache_blob()`.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `gdi_context` must be a valid pointer to a C++ ScriptGdiBuilder.
void *rust_materialize_bytecode_cache_script(DecodedBytecodeCacheBlob *blob,
                                             void *vm_ptr,
                                             const void *source_code_ptr,
                                             size_t source_len,
                                             void *gdi_context);

/// Materialize a decoded module bytecode cache blob. Consumes and frees the blob.
///
/// # Safety
/// - `blob` must be a valid pointer from `rust_decode_bytecode_cache_blob()`.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `module_context` must be a valid `ModuleBuilder*`.
/// - `callbacks` must point to a valid `ModuleCallbacks`.
void *rust_materialize_bytecode_cache_module(DecodedBytecodeCacheBlob *blob,
                                             void *vm_ptr,
                                             const void *source_code_ptr,
                                             size_t source_len,
                                             void *module_context,
                                             const ModuleCallbacks *callbacks,
                                             void **tla_executable_out);

/// Materialize a decoded function executable from a bytecode cache blob.
/// Consumes and frees the cached executable.
///
/// # Safety
/// - `cached_executable` must be a valid pointer attached to a
///   `SharedFunctionInstanceData` by bytecode cache materialization.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
void *rust_materialize_bytecode_cache_function(void *cached_executable, void *vm_ptr, const void *source_code_ptr);

/// Free a cached decoded function executable without materializing it.
///
/// # Safety
/// `cached_executable` must be either null or a valid pointer attached to a
/// `SharedFunctionInstanceData` by bytecode cache materialization.
void rust_free_cached_bytecode_executable(void *cached_executable);

/// Materialize a precompiled function executable.
/// Consumes and frees the precompiled executable.
///
/// # Safety
/// - `precompiled_executable` must be a valid `Box<PrecompiledFunction>`
///   pointer attached to a `SharedFunctionInstanceData`.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
void *rust_materialize_precompiled_bytecode_function(void *precompiled_executable,
                                                     void *vm_ptr,
                                                     const void *source_code_ptr);

/// Free a precompiled function executable without materializing it.
///
/// # Safety
/// `precompiled_executable` must be either null or a valid
/// `Box<PrecompiledFunction>` pointer attached to a `SharedFunctionInstanceData`.
void rust_free_precompiled_bytecode_executable(void *precompiled_executable);

/// Get the AST dump string from a ParsedProgram.
///
/// Generates the dump on first call and caches it. Writes the pointer
/// and length to the provided out-parameters. The string is owned by
/// the ParsedProgram and freed when it is freed or compiled.
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()` with no errors.
/// - `output_ptr` and `output_len` must be valid writable pointers.
void rust_parsed_program_ast_dump(ParsedProgram *parsed, const uint8_t **output_ptr, size_t *output_len);

/// Compile a previously parsed script. Consumes and frees the ParsedProgram.
///
/// Performs codegen and GDI extraction. Requires VM and GC access.
///
/// Returns the `Executable*` as `void*`, or nullptr on failure.
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()` with no errors.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `gdi_context` must be a valid pointer to a C++ ScriptGdiBuilder.
void *rust_compile_parsed_script(ParsedProgram *parsed,
                                 void *vm_ptr,
                                 const void *source_code_ptr,
                                 void *gdi_context,
                                 size_t source_len);

/// Materialize an off-thread-compiled script. Consumes and frees the CompiledProgram.
///
/// # Safety
/// - `compiled` must be a valid pointer from `rust_compile_parsed_program_off_thread()`.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `gdi_context` must be a valid pointer to a C++ ScriptGdiBuilder.
void *rust_materialize_compiled_script(CompiledProgram *compiled,
                                       void *vm_ptr,
                                       const void *source_code_ptr,
                                       void *gdi_context);

/// Compile an eval script and extract EDI (EvalDeclarationInstantiation) metadata.
///
/// This is the path for eval(). It:
/// 1. Parses the program with eval flags
/// 2. Runs scope analysis with initiated_by_eval=true
/// 3. Generates bytecode → creates Executable
/// 4. Extracts EDI metadata from the program AST
/// 5. Populates the C++ EvalGdiBuilder via callbacks
///
/// Returns the `Executable*` as `void*`, or nullptr on failure.
///
/// # Safety
/// - `source` must point to a valid UTF-16 buffer of `source_len` elements.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `gdi_context` must be a valid pointer to a C++ EvalGdiBuilder.
void *rust_compile_eval(const uint16_t *source,
                        size_t source_len,
                        void *vm_ptr,
                        const void *source_code_ptr,
                        void *gdi_context,
                        bool starts_in_strict_mode,
                        bool in_eval_function_context,
                        bool allow_super_property_lookup,
                        bool allow_super_constructor_call,
                        bool in_class_field_initializer,
                        void *error_context,
                        ParseErrorCallback error_callback,
                        uint8_t **ast_dump_output,
                        size_t *ast_dump_output_len);

/// Compile a dynamically-created function (new Function()).
/// https://tc39.es/ecma262/#sec-createdynamicfunction
///
/// Validates parameters and body separately per spec, then parses
/// the full synthetic source to create a SharedFunctionInstanceData.
///
/// Returns a `SharedFunctionInstanceData*` as `void*`, or nullptr on
/// parse failure.
///
/// # Safety
/// - All source pointers must be valid UTF-16 buffers.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
void *rust_compile_dynamic_function(const uint16_t *full_source,
                                    size_t full_source_len,
                                    const uint16_t *parameters_source,
                                    size_t parameters_source_len,
                                    const uint16_t *body_source,
                                    size_t body_source_len,
                                    void *vm_ptr,
                                    const void *source_code_ptr,
                                    uint8_t function_kind,
                                    void *error_context,
                                    ParseErrorCallback error_callback,
                                    uint8_t **ast_dump_output,
                                    size_t *ast_dump_output_len);

/// Parse a builtin JS file in strict mode, extract top-level function
/// declarations, and create SharedFunctionInstanceData for each via the
/// the pipeline.
///
/// Calls `push_function` for each top-level FunctionDeclaration found.
///
/// # Safety
/// - `source` must point to a valid UTF-16 buffer of `source_len` elements.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `ctx` must be a valid pointer passed through to `push_function`.
void rust_compile_builtin_file(const uint16_t *source,
                               size_t source_len,
                               void *vm_ptr,
                               const void *source_code_ptr,
                               void *ctx,
                               BuiltinFunctionCallback push_function,
                               uint8_t **ast_dump_output,
                               size_t *ast_dump_output_len);

/// Compile a previously parsed module. Consumes and frees the ParsedProgram.
///
/// Extracts import/export metadata, compiles the module body to bytecode,
/// and extracts declaration data needed for initialize_environment().
///
/// Returns `Executable*` for non-TLA modules (tla_executable_out is null),
/// or nullptr for TLA modules (tla_executable_out is set to the async wrapper).
///
/// # Safety
/// - `parsed` must be a valid pointer from `rust_parse_program()` with no errors.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `module_context` must be a valid `ModuleBuilder*`.
/// - `callbacks` must point to a valid `ModuleCallbacks`.
void *rust_compile_parsed_module(ParsedProgram *parsed,
                                 void *vm_ptr,
                                 const void *source_code_ptr,
                                 void *module_context,
                                 const ModuleCallbacks *callbacks,
                                 void **tla_executable_out,
                                 size_t source_len);

/// Materialize an off-thread-compiled module. Consumes and frees the CompiledProgram.
///
/// # Safety
/// - `compiled` must be a valid pointer from `rust_compile_parsed_program_off_thread()`.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `module_context` must be a valid `ModuleBuilder*`.
/// - `callbacks` must point to a valid `ModuleCallbacks`.
void *rust_materialize_compiled_module(CompiledProgram *compiled,
                                       void *vm_ptr,
                                       const void *source_code_ptr,
                                       void *module_context,
                                       const ModuleCallbacks *callbacks,
                                       void **tla_executable_out);

/// Compile an ES module using the parser and bytecode generator.
///
/// This is the combined parse+compile path for modules. Internally calls
/// `rust_parse_program()` + `rust_compile_parsed_module()`.
///
/// Returns `Executable*` for non-TLA modules (tla_executable_out is null),
/// or nullptr for TLA modules (tla_executable_out is set to the async wrapper executable).
///
/// # Safety
/// - `source` must point to a valid UTF-16 buffer of `source_len` elements.
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `module_context` must be a valid `ModuleBuilder*`.
/// - `callbacks` must point to a valid `ModuleCallbacks`.
void *rust_compile_module(const uint16_t *source,
                          size_t source_len,
                          void *vm_ptr,
                          const void *source_code_ptr,
                          void *module_context,
                          const ModuleCallbacks *callbacks,
                          bool dump_ast,
                          bool use_color,
                          void *error_context,
                          ParseErrorCallback error_callback,
                          void **tla_executable_out,
                          uint8_t **ast_dump_output,
                          size_t *ast_dump_output_len);

extern void module_sfd_set_name(void *sfd_ptr, const uint16_t *name, size_t name_len);

/// Free a `Box<FunctionData>` stored in a C++ SharedFunctionInstanceData.
///
/// Called from the SFD's `finalize()` or `clear_compile_inputs()` when the
/// AST is no longer needed.
///
/// # Safety
/// `ast` must be a valid pointer returned by `Box::into_raw(Box<FunctionData>)`.
void rust_free_function_ast(void *ast);

/// Clone a lazy function compilation payload.
///
/// The clone lets background compilation race with synchronous lazy
/// compilation. Each path owns and eventually frees its own AST payload.
///
/// # Safety
/// `ast` must be null or a valid pointer returned by `Box::into_raw(Box<FunctionPayload>)`.
void *rust_clone_function_ast(const void *ast);

/// Free a string allocated by Rust (e.g. AST dump output).
///
/// # Safety
/// `ptr` and `len` must correspond to a `Box<[u8]>` previously leaked via `std::mem::forget`.
void rust_free_string(uint8_t *ptr, size_t len);

/// Compile a function body.
///
/// Takes ownership of the `Box<FunctionData>` and compiles it into a
/// C++ `Bytecode::Executable`. Also populates FDI runtime metadata on the
/// `SharedFunctionInstanceData`.
///
/// # Safety
/// - `vm_ptr` must be a valid `JS::VM*`.
/// - `source_code_ptr` must be a valid `JS::SourceCode const*`.
/// - `sfd_ptr` must be a valid `JS::SharedFunctionInstanceData*`.
/// - `rust_function_ast` must be a valid `Box<FunctionData>` pointer.
void *rust_compile_function(void *vm_ptr,
                            const void *source_code_ptr,
                            const uint16_t *_source,
                            size_t source_len,
                            void *sfd_ptr,
                            void *rust_function_ast,
                            bool builtin_abstract_operations_enabled);

/// Compile a function payload to a GC-free bytecode artifact.
///
/// Takes ownership of the cloned `Box<FunctionPayload>`. The result must be
/// materialized on the main thread or freed with `rust_free_compiled_function`.
///
/// # Safety
/// `rust_function_ast` must be a valid `Box<FunctionPayload>` pointer.
CompiledFunction *rust_compile_function_off_thread(void *rust_function_ast,
                                                   size_t source_len,
                                                   bool builtin_abstract_operations_enabled);

/// Attach a GC-free compiled function to an existing SFD.
///
/// Consumes the compiled function. Its precompiled bytecode is materialized
/// lazily the first time the function is called.
///
/// # Safety
/// - `compiled` must be a valid pointer returned by `rust_compile_function_off_thread`.
/// - `vm_ptr`, `source_code_ptr`, and `sfd_ptr` must be valid main-thread pointers.
void rust_materialize_compiled_function(CompiledFunction *compiled,
                                        void *_vm_ptr,
                                        const void *_source_code_ptr,
                                        void *sfd_ptr);

/// Free a GC-free compiled function without materializing it.
///
/// # Safety
/// `compiled` must be null or a valid pointer returned by `rust_compile_function_off_thread`.
void rust_free_compiled_function(CompiledFunction *compiled);

extern void rust_sfd_set_metadata(void *sfd_ptr,
                                  bool uses_this,
                                  bool this_value_needs_environment_resolution,
                                  bool function_environment_needed,
                                  size_t function_environment_bindings_count,
                                  bool might_need_arguments_object,
                                  bool contains_direct_call_to_eval);

/// Tokenize a UTF-16 source string, calling `callback` for each token.
///
/// # Safety
/// - `source` must point to a valid UTF-16 buffer of `source_len` elements.
/// - `callback` must be a valid function pointer.
/// - `ctx` is passed through to the callback.
void rust_tokenize(const uint16_t *source, size_t source_len, void *ctx, void (*callback)(void *ctx,
                                                                                          const FFIToken *token));

/// Validate the structural integrity of a packed bytecode buffer along with
/// the structural metadata that travels with it (basic block offsets,
/// exception handler ranges, source map entries).
///
/// Returns `true` if every instruction is well-formed against the supplied
/// bounds. On failure, writes the error category, byte offset, and opcode
/// into `*error_out` (when non-null) and returns `false`.
///
/// # Safety
/// - `bytecode_ptr` must point to a buffer of `bytecode_len` bytes, aligned
///   to 8 bytes (matching `alignof(Instruction)`). May be null only when
///   `bytecode_len` is zero.
/// - `bounds` must point to a valid `FFIValidatorBounds`.
/// - `extras` must point to a valid `FFIValidatorExtras`. Each
///   inner pointer may be null only when its corresponding count is zero.
/// - `error_out` must be either null or a writable `FFIValidationError`.
bool rust_validate_bytecode(const uint8_t *bytecode_ptr,
                            size_t bytecode_len,
                            const FFIValidatorBounds *bounds,
                            const FFIValidatorExtras *extras,
                            FFIValidationError *error_out);

extern uint8_t *ladybird_rust_alloc(size_t size, size_t alignment);

extern uint8_t *ladybird_rust_alloc_zeroed(size_t size, size_t alignment);

extern void ladybird_rust_dealloc(uint8_t *ptr, size_t alignment);

extern uint8_t *ladybird_rust_realloc(uint8_t *ptr, size_t old_size, size_t new_size, size_t alignment);

extern void rust_free_compiled_regex(void *ptr);

extern size_t rust_format_double(double value, uint8_t *buffer, size_t buffer_len);

extern void *rust_create_executable(void *vm_ptr, const void *source_code_ptr, const FFIExecutableData *data);

extern void *rust_create_sfd(void *vm_ptr, const void *source_code_ptr, const FFISharedFunctionData *data);

extern void rust_sfd_set_class_field_initializer_name(void *sfd_ptr,
                                                      const uint16_t *name,
                                                      size_t name_len,
                                                      bool is_private);

extern void rust_sfd_set_precompiled_executable(void *sfd_ptr,
                                                void *executable_ptr,
                                                bool uses_this,
                                                bool this_value_needs_environment_resolution,
                                                bool function_environment_needed,
                                                size_t function_environment_bindings_count,
                                                bool might_need_arguments_object,
                                                bool contains_direct_call_to_eval);

extern void rust_sfd_set_cached_bytecode_executable(void *sfd_ptr,
                                                    void *cached_executable_ptr,
                                                    bool uses_this,
                                                    bool this_value_needs_environment_resolution,
                                                    bool function_environment_needed,
                                                    size_t function_environment_bindings_count,
                                                    bool might_need_arguments_object,
                                                    bool contains_direct_call_to_eval);

extern void rust_sfd_set_precompiled_bytecode_executable(void *sfd_ptr,
                                                         void *precompiled_executable_ptr,
                                                         bool uses_this,
                                                         bool this_value_needs_environment_resolution,
                                                         bool function_environment_needed,
                                                         size_t function_environment_bindings_count,
                                                         bool might_need_arguments_object,
                                                         bool contains_direct_call_to_eval);

extern void *rust_create_class_blueprint(void *vm_ptr,
                                         const void *source_code_ptr,
                                         const uint16_t *name,
                                         size_t name_len,
                                         size_t source_text_offset,
                                         size_t source_text_len,
                                         uint32_t constructor_sfd_index,
                                         bool has_super_class,
                                         bool has_name,
                                         const FFIClassElement *elements,
                                         size_t element_count);

extern void script_gdi_push_lexical_name(void *ctx, const uint16_t *name, size_t len);

extern void script_gdi_push_var_name(void *ctx, const uint16_t *name, size_t len);

extern void script_gdi_push_function(void *ctx, void *sfd, const uint16_t *name, size_t len);

extern void script_gdi_push_var_scoped_name(void *ctx, const uint16_t *name, size_t len);

extern void script_gdi_push_annex_b_name(void *ctx, const uint16_t *name, size_t len);

extern void script_gdi_push_lexical_binding(void *ctx, const uint16_t *name, size_t len, bool is_constant);

extern void eval_gdi_set_strict(void *ctx, bool is_strict);

extern void eval_gdi_push_var_name(void *ctx, const uint16_t *name, size_t len);

extern void eval_gdi_push_function(void *ctx, void *sfd, const uint16_t *name, size_t len);

extern void eval_gdi_push_var_scoped_name(void *ctx, const uint16_t *name, size_t len);

extern void eval_gdi_push_annex_b_name(void *ctx, const uint16_t *name, size_t len);

extern void eval_gdi_push_lexical_binding(void *ctx, const uint16_t *name, size_t len, bool is_constant);

extern void *rust_compile_regex(const uint16_t *pattern_data,
                                size_t pattern_len,
                                const uint16_t *flags_data,
                                size_t flags_len,
                                const char **error_out);

extern void rust_free_error_string(const char *str);

extern size_t rust_number_to_utf16(double value, uint16_t *buffer, size_t buffer_len);

}  // extern "C"

}  // namespace FFI
}  // namespace JS
