#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/module_tier_ladder.hpp"
#include "rive/wasm/wamr_state_transplant.hpp"
#include "rive/wasm/wasm_scripting_vm.hpp"
#include <unordered_map>
#ifdef WITH_RIVE_TEXT
#include "rive/text/raw_text.hpp"
#include "rive/text/cursor.hpp"
#include "rive/text/font_hb.hpp"
#endif
#include "rive/wasm/prelinked_aot.hpp"
#if WASM_ENABLE_PRELINKED_AOT != 0
// AOT_MAGIC_NUMBER / AOT_CURRENT_VERSION for container validation; same
// internal-header precedent as wamr_state_transplant.cpp.
#include "aot_runtime.h"
#endif

#include "rive/animation/linear_animation.hpp"
#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/listener_invocation.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/artboard.hpp"
#include "rive/assets/blob_asset.hpp"
#include "rive/custom_property_boolean.hpp"
#include "rive/custom_property_color.hpp"
#include "rive/assets/manifest_asset.hpp"
#include "rive/custom_property.hpp"
#include "rive/custom_property_number.hpp"
#include "rive/custom_property_string.hpp"
#include "rive/drawable.hpp"
#ifdef WITH_RIVE_AUDIO
#include "rive/assets/audio_asset.hpp"
#include "rive/audio/audio_engine.hpp"
#include "rive/audio/audio_sound.hpp"
#include "rive/audio/audio_source.hpp"
#endif
#include "rive/bones/root_bone.hpp"
#include "rive/constraints/constraint.hpp"
#include "rive/container_component.hpp"
#include "rive/math/transform_components.hpp"
#include "rive/node.hpp"
#include "rive/shapes/path.hpp"
#include "rive/transform_component.hpp"
#include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp"
#include "rive/wasm/artboard_wire.hpp"
#include "rive/assets/font_asset.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/assets/shader_asset.hpp"
#include "rive/async/work_pool.hpp"
#include "rive/data_bind/data_context.hpp"
#include "rive/data_bind/data_values/data_value.hpp"
#include "rive/data_bind/data_values/data_value_boolean.hpp"
#include "rive/data_bind/data_values/data_value_color.hpp"
#include "rive/data_bind/data_values/data_value_number.hpp"
#include "rive/data_bind/data_values/data_value_string.hpp"
#include "rive/factory.hpp"
#include "rive/file.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/image_sampler.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/solid_color.hpp"
#include "rive/shapes/paint/stroke.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/math/contour_measure.hpp"
#include "rive/math/path_measure.hpp"
#include "rive/renderer.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/viewmodel/viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/viewmodel/viewmodel_instance_boolean.hpp"
#include "rive/viewmodel/viewmodel_instance_number.hpp"
#include "rive/viewmodel/viewmodel_instance_string.hpp"
#include "rive/viewmodel/data_enum.hpp"
#include "rive/viewmodel/data_enum_value.hpp"
#include "rive/viewmodel/viewmodel_instance_color.hpp"
#include "rive/viewmodel/viewmodel_instance_enum.hpp"
#include "rive/viewmodel/viewmodel_property_enum.hpp"
#include "rive/viewmodel/viewmodel_instance_trigger.hpp"
#include "rive/viewmodel/viewmodel_instance_list.hpp"
#include "rive/viewmodel/viewmodel_instance_list_item.hpp"
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_blob.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_font.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_image.hpp"
#include "rive/wasm/data_convert_wire.hpp"
#include "rive/wasm/gamepad_wire.hpp"
#include "rive/wasm/listener_wire.hpp"
#include "rive/wasm/path_effect_wire.hpp"

#ifdef RIVE_DECODERS
#include "rive/decoders/bitmap_decoder.hpp"

#include <chrono>
#include <sys/stat.h>
#endif

#ifdef RIVE_CANVAS
#include "rive/renderer/render_context.hpp"
#include "rive/renderer/render_canvas.hpp"
#include "rive/renderer/cmd/deferred_canvas_host.hpp"
#include "rive/renderer/rive_render_image.hpp"
#endif
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
#include "rive/renderer/ore/ore_context.hpp"
#include "rive/renderer/ore/ore_script_guards.hpp"
#include "rive/renderer/ore/ore_buffer.hpp"
#include "rive/renderer/ore/ore_texture.hpp"
#include "rive/renderer/ore/ore_sampler.hpp"
#include "rive/renderer/ore/ore_shader_module.hpp"
#include "rive/renderer/ore/ore_bind_group_layout.hpp"
#include "rive/renderer/ore/ore_bind_group.hpp"
#include "rive/renderer/ore/ore_pipeline.hpp"
#include "rive/renderer/ore/cmd/ore_deferred_render_pass.hpp"
#include "rive/renderer/cmd/deferred_render_resource.hpp"

#include <algorithm>
#include <vector>
#include <atomic>
#include <unordered_map>
#include <condition_variable>
#include <thread>
#include <mutex>
#include <cmath>
#include <cassert>
#endif

#include "wasm_export.h"

#include <chrono>
#include <string.h>
#include <time.h>

using namespace rive;

namespace
{

constexpr char kLongjmpTag[] = "rive-longjmp";

WasmScriptingVM* vmFromEnv(wasm_exec_env_t env)
{
    return static_cast<WasmScriptingVM*>(wasm_runtime_get_user_data(env));
}

// Module start runs inside wasm_runtime_instantiate, before an exec env
// exists to carry the vm, so natives called from there resolve none. rasc
// runs every script's top level there, and its output is the one thing a
// host still needs; the sink for that window is parked here.
thread_local const std::function<void(const char*, size_t)>* s_bootPrint =
    nullptr;
// The VM whose module is starting, for the debug probes its top level hits.
thread_local WasmScriptingVM* s_booting = nullptr;
thread_local WasmScriptingVM::BootHook s_bootHook;

} // namespace

struct rive::WasmScriptingVMNatives
{
    static void print(WasmScriptingVM* vm, const char* data, size_t size);
};

// Loaded modules are immutable and shared: fast-interp translation costs
// ~11ms per load while instantiation is microseconds, and every file
// instance of the same content reloads identical bytes. Entries live for
// the process; the byte buffer must outlive the module (wasm_runtime_load
// keeps referencing it).
struct SharedWasmModule
{
    // The buffer WAMR loads from and references for the module's lifetime;
    // the loader null-terminates import/export names in place, so these
    // bytes are unfit to recompile.
    std::vector<uint8_t> bytes;
    // Pristine pre-load copy handed to wamrc for the AOT lane.
    std::vector<uint8_t> pristineBytes;
    wasm_module_t module = nullptr;
    // Artifact-backed entries hand every later VM their real tier; without
    // this a cache hit reports interp while running compiled code.
    WasmScriptingVM::ExecutionTier tier =
        WasmScriptingVM::ExecutionTier::interp;
};

static std::unordered_map<uint64_t, SharedWasmModule>& sharedModuleCache()
{
    static std::unordered_map<uint64_t, SharedWasmModule> cache;
    return cache;
}

struct WasmScriptingVM::WamrState
{
    // Backing for an artifact loaded by a tier swap; wasm_runtime_load keeps
    // referencing it.
    std::vector<uint8_t> artifactBytes;
    wasm_module_t module = nullptr;
    bool ownsModule = true;
    wasm_module_inst_t instance = nullptr;
    wasm_exec_env_t execEnv = nullptr;
    uint32_t callDepth = 0;
    std::unordered_map<std::string, uint32_t> guestNames;

    // Export names reach callModule as literals, so the pointer is the key;
    // the owned copy lets debug builds catch a caller that reuses a buffer.
    struct ExportSlot
    {
        const char* key = nullptr;
        std::string name;
        wasm_function_inst_t function = nullptr;
    };
    ExportSlot exportCache[64];

    wasm_function_inst_t lookupExport(const char* name)
    {
        ExportSlot& slot = exportCache[(reinterpret_cast<uintptr_t>(name) *
                                        0x9E3779B97F4A7C15ull) >>
                                       58];
        if (slot.key != name)
        {
            wasm_function_inst_t function =
                wasm_runtime_lookup_function(instance, name);
            if (function == nullptr)
            {
                return nullptr;
            }
            slot = {name, name, function};
        }
        assert(slot.name == name);
        return slot.function;
    }

    ~WamrState()
    {
        if (execEnv != nullptr)
        {
            wasm_runtime_destroy_exec_env(execEnv);
        }
        if (instance != nullptr)
        {
            wasm_runtime_deinstantiate(instance);
        }
        if (module != nullptr && ownsModule)
        {
            wasm_runtime_unload(module);
        }
    }
};

#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
namespace
{
ore::Context* gpuOreContext(WasmScriptingVM* vm);
}
#endif
#ifdef RIVE_CANVAS
namespace
{
void canvasEndFrameImpl(WasmScriptingVM* vm, uint32_t canvas);
}
#endif

uint32_t WasmScriptingVM::callModule(const char* name,
                                     uint32_t argc,
                                     uint32_t* argv)
{
    uint32_t result = 0;
    callModuleChecked(name, argc, argv, &result);
    return result;
}

struct WasmScriptingVM::BudgetSlot
{
    std::atomic<int64_t> deadline{0};
    // Set when the watchdog interrupted the last budgeted call.
    std::atomic<bool> fired{false};
    wasm_exec_env_t env = nullptr;
};

namespace
{
// One thread bounds every VM's calls, so modules need no fuel counters: it
// polls each VM's deadline and, on an overrun, sets the call's terminate
// flag so the interpreter or AOT code traps at its next loop back-edge.
// Calls only store and swap an atomic, so the script thread never waits.
constexpr int64_t kFiring = -1;

int64_t steadyNanos()
{
    return std::chrono::duration_cast<std::chrono::nanoseconds>(
               std::chrono::steady_clock::now().time_since_epoch())
        .count();
}

class ScriptWatchdog
{
public:
    // Leaked, with a detached thread, so no static destructor joins it or
    // frees the mutex a VM in another static still uses.
    static ScriptWatchdog& instance()
    {
        static ScriptWatchdog* watchdog = new ScriptWatchdog();
        return *watchdog;
    }

    void add(WasmScriptingVM::BudgetSlot* slot)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!m_started)
        {
            m_started = true;
            std::thread([this] { run(); }).detach();
        }
        m_slots.push_back(slot);
    }

    void remove(WasmScriptingVM::BudgetSlot* slot)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_slots.erase(std::remove(m_slots.begin(), m_slots.end(), slot),
                      m_slots.end());
    }

    // Calls arm without the lock; only an arm that finds the thread idle
    // takes it, to end a wait that has no deadline.
    void armed()
    {
        if (m_idle.load())
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            m_wake.notify_one();
        }
    }

private:
    void run()
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        while (true)
        {
            // Idle is published before the scan, so an arm either shows up
            // in it or sees idle and ends the wait.
            m_idle.store(true);
            int64_t now = steadyNanos();
            int64_t earliest = 0;
            for (WasmScriptingVM::BudgetSlot* slot : m_slots)
            {
                int64_t deadline = slot->deadline.load();
                if (deadline > 0 && now >= deadline &&
                    slot->deadline.compare_exchange_strong(deadline, kFiring))
                {
                    slot->fired.store(true);
                    wasm_runtime_rive_interrupt(slot->env);
                    slot->deadline.store(0);
                }
                else if (deadline > 0 && (earliest == 0 || deadline < earliest))
                {
                    earliest = deadline;
                }
            }
            if (earliest == 0)
            {
                m_wake.wait(lock);
                continue;
            }
            m_idle.store(false);
            m_wake.wait_until(lock,
                              std::chrono::steady_clock::time_point(
                                  std::chrono::duration_cast<
                                      std::chrono::steady_clock::duration>(
                                      std::chrono::nanoseconds(earliest))));
        }
    }

    std::mutex m_mutex;
    std::condition_variable m_wake;
    std::vector<WasmScriptingVM::BudgetSlot*> m_slots;
    std::atomic<bool> m_idle{false};
    bool m_started = false;
};
} // namespace

WasmScriptingVM::ScriptCallScope::ScriptCallScope(WasmScriptingVM* vm,
                                                  bool budgeted) :
    m_vm(vm)
{
    if (vm->m_debugHooks != nullptr)
    {
        vm->m_debugHooks->onCallBegin(*vm);
    }
    // The outermost scope sweeps what any nested call left open.
    if (vm->m_state->callDepth++ != 0)
    {
        return;
    }
    // A debugger pauses mid call, so its sessions run unbudgeted.
    if (budgeted && vm->m_hostBudget && vm->m_timeoutMs > 0 &&
        vm->m_debugHooks == nullptr)
    {
        if (vm->m_budgetSlot == nullptr)
        {
            vm->m_budgetSlot = std::make_unique<BudgetSlot>();
            ScriptWatchdog::instance().add(vm->m_budgetSlot.get());
        }
        BudgetSlot* slot = vm->m_budgetSlot.get();
        slot->env = vm->m_state->execEnv;
        slot->fired.store(false);
        slot->deadline.store(steadyNanos() +
                             (int64_t)vm->m_timeoutMs * 1000000);
        ScriptWatchdog::instance().armed();
        m_budgeted = true;
    }
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
    ore::Context* oreContext = gpuOreContext(vm);
    m_passToken = oreContext != nullptr ? oreContext->nextRenderPassToken() : 0;
#endif
#ifdef RIVE_CANVAS
    m_frameToken = vm->m_nextCanvasFrameToken;
#endif
}

WasmScriptingVM::ScriptCallScope::~ScriptCallScope()
{
    if (m_budgeted)
    {
        // Swapping out a zero means the watchdog claimed the deadline; wait
        // out its firing so the interrupt never lands on a later call.
        BudgetSlot* slot = m_vm->m_budgetSlot.get();
        int64_t deadline = slot->deadline.load();
        while (deadline == kFiring ||
               !slot->deadline.compare_exchange_weak(deadline, 0))
        {
            deadline = slot->deadline.load();
        }
        if (slot->fired.load())
        {
            fprintf(stderr,
                    "script error: execution exceeded %d millisecond timeout\n",
                    m_vm->m_timeoutMs);
            // The interrupt can land inside the module's allocator or
            // collector, so its heap is no longer trusted.
            m_vm->m_poisoned = true;
            fprintf(stderr,
                    "script stopped: its module may have been interrupted "
                    "mid-update\n");
        }
        wasm_runtime_rive_clear_interrupt(slot->env);
    }
    if (--m_vm->m_state->callDepth == 0)
    {
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
        ore::Context* oreContext = gpuOreContext(m_vm);
        if (oreContext != nullptr &&
            oreContext->finishOpenRenderPassesFrom(m_passToken) != 0)
        {
            fprintf(stderr,
                    "GPU render pass left open at script return. Call finish() "
                    "on render passes before returning.\n");
        }
#endif
#ifdef RIVE_CANVAS
        std::vector<uint32_t> openFrames =
            m_vm->takeOpenCanvasFramesFrom(m_frameToken);
        for (uint32_t canvas : openFrames)
        {
            canvasEndFrameImpl(m_vm, canvas);
        }
        if (!openFrames.empty())
        {
            fprintf(stderr,
                    "Canvas frame left open at script return. Call endFrame() "
                    "before returning.\n");
        }
#endif
    }
    if (m_vm->m_debugHooks != nullptr)
    {
        // Still set here when the call trapped; the caller clears it.
        const char* trap =
            m_vm->m_state != nullptr && m_vm->m_state->instance != nullptr
                ? wasm_runtime_get_exception(m_vm->m_state->instance)
                : nullptr;
        m_vm->m_debugHooks->onCallEnd(*m_vm, trap);
    }
}

WasmScriptingVM::CallOutcome WasmScriptingVM::callModuleChecked(
    const char* name,
    uint32_t argc,
    uint32_t* argv,
    uint32_t* result)
{
    if (m_poisoned)
    {
        return CallOutcome::trapped;
    }
    wasm_function_inst_t f = m_state->lookupExport(name);
    if (f == nullptr)
    {
        // Callers probing optional exports read the outcome; a plain
        // callModule folds this to zero, so probe before relying on it.
        return CallOutcome::missing;
    }
    uint32_t buf[8] = {0};
    for (uint32_t i = 0; i < argc; i++)
    {
        buf[i] = argv[i];
    }
    bool ok;
    {
        // Runtime services, the collector among them, must never be cut off.
        ScriptCallScope callScope(this, strncmp(name, "__rive", 6) != 0);
        ok = m_state->callDepth > 1
                 ? wasm_runtime_call_wasm_nested(m_state->execEnv, f, argc, buf)
                 : wasm_runtime_call_wasm(m_state->execEnv, f, argc, buf);
    }
    if (!ok)
    {
        reportTrap(name);
        return CallOutcome::trapped;
    }
    *result = buf[0];
    return CallOutcome::ok;
}

void WasmScriptingVM::reportTrap(const char* where)
{
    wasm_module_inst_t inst = m_state->instance;
    // A silent fold hides real traps; name them so a script that dies
    // mid-call is diagnosable instead of a mystery no-op.
    const char* exception = fullTrapMessage(wasm_runtime_get_exception(inst));
    if (exception == nullptr)
    {
        return;
    }
    // AOT code traps as unreachable; both tiers name the timeout.
    if (m_budgetSlot != nullptr && m_budgetSlot->fired.load())
    {
        exception = "execution exceeded timeout";
    }
    fprintf(stderr, "wasm call trapped in %s: %s\n", where, exception);
#if WASM_ENABLE_DUMP_CALL_STACK != 0
    wasm_runtime_dump_call_stack(m_state->execEnv);
#endif
    if (m_leakWarningCount > 0 && !m_leakTrapContextPrinted)
    {
        // A bare trap after leak warnings is almost always the memory
        // ceiling; say so once for hosts that dropped the warning strings.
        m_leakTrapContextPrinted = true;
        fprintf(stderr,
                "wasm call trapped after %u script heap leak warnings; the "
                "module likely hit its wasmMaxPages ceiling\n",
                m_leakWarningCount);
    }
    // A pending exception makes WAMR refuse the next call, the collector's
    // included.
    wasm_runtime_clear_exception(inst);
}

void WasmScriptingVM::unregisterOpenCanvasFrame(uint32_t canvas)
{
    for (size_t i = 0; i < m_openCanvasFrames.size(); i++)
    {
        if (m_openCanvasFrames[i].canvas == canvas)
        {
            m_openCanvasFrames.erase(m_openCanvasFrames.begin() + i);
            return;
        }
    }
}

std::vector<uint32_t> WasmScriptingVM::takeOpenCanvasFramesFrom(uint64_t token)
{
    std::vector<uint32_t> taken;
    size_t keep = 0;
    for (size_t i = 0; i < m_openCanvasFrames.size(); i++)
    {
        if (m_openCanvasFrames[i].token >= token)
        {
            taken.push_back(m_openCanvasFrames[i].canvas);
        }
        else
        {
            m_openCanvasFrames[keep++] = m_openCanvasFrames[i];
        }
    }
    m_openCanvasFrames.resize(keep);
    return taken;
}

void* WasmScriptingVM::resolveModulePtr(uint32_t appAddr, uint32_t size)
{
    wasm_module_inst_t inst = m_state->instance;
    if (!wasm_runtime_validate_app_addr(inst, appAddr, size))
    {
        return nullptr;
    }
    return wasm_runtime_addr_app_to_native(inst, appAddr);
}

void WasmScriptingVM::raiseModuleError(const char* message)
{
    // The runtime's exception buffer truncates long messages (shader
    // compiler output); keep the full text for trap reporting.
    m_moduleErrorDetail = message;
    wasm_runtime_set_exception(m_state->instance, message);
}

const char* WasmScriptingVM::fullTrapMessage(const char* exception) const
{
    if (exception == nullptr || m_moduleErrorDetail.empty())
    {
        return exception;
    }
    const char* text = exception;
    constexpr char kPrefix[] = "Exception: ";
    if (strncmp(text, kPrefix, sizeof(kPrefix) - 1) == 0)
    {
        text += sizeof(kPrefix) - 1;
    }
    // Substitute only when the exception is a truncation of the detail, so
    // an unrelated later trap keeps its own message. An empty remainder
    // matches every prefix and must not adopt stale detail.
    if (*text != '\0' &&
        m_moduleErrorDetail.compare(0, strlen(text), text) == 0)
    {
        return m_moduleErrorDetail.c_str();
    }
    return exception;
}

void WasmScriptingVMNatives::print(WasmScriptingVM* vm,
                                   const char* data,
                                   size_t size)
{
    const std::function<void(const char*, size_t)>* sink =
        vm != nullptr ? &vm->m_print : s_bootPrint;
    if (sink != nullptr && *sink)
    {
        (*sink)(data, size);
    }
    else
    {
        fwrite(data, 1, size, stdout);
    }
}

namespace
{

// A string argument as the impl cores read it, UTF-8. A module that hands
// over its own UTF-16 has it transcoded here, on the stack for anything the
// size of a name.
class WasmStringArg
{
public:
    WasmStringArg(WasmScriptingVM* vm, const char* bytes, uint32_t byteCount) :
        m_data(bytes), m_size(byteCount)
    {
        // Module start calls in before the vm rides on the exec env.
        WasmScriptingVM* owner = vm != nullptr ? vm : s_booting;
        if (owner == nullptr || !owner->utf16Strings() || bytes == nullptr)
        {
            return;
        }
        auto in = reinterpret_cast<const uint8_t*>(bytes);
        uint32_t units = byteCount / 2;
        // A unit is three bytes at most, a surrogate pair four for its two.
        char* out = m_inline;
        if ((size_t)units * 3 > sizeof(m_inline))
        {
            m_heap.resize((size_t)units * 3);
            out = &m_heap[0];
        }
        m_data = out;
        auto unitAt = [in](uint32_t i) {
            return (uint32_t)in[i * 2] | (uint32_t)in[i * 2 + 1] << 8;
        };
        for (uint32_t i = 0; i < units; i++)
        {
            uint32_t code = unitAt(i);
            if (code >= 0xD800 && code < 0xDC00 && i + 1 < units)
            {
                uint32_t low = unitAt(i + 1);
                if (low >= 0xDC00 && low < 0xE000)
                {
                    code = 0x10000 + ((code - 0xD800) << 10) + (low - 0xDC00);
                    i++;
                }
            }
            // A lone surrogate encodes as it stands, as the module's own
            // encoder did.
            if (code < 0x80)
            {
                *out++ = (char)code;
            }
            else if (code < 0x800)
            {
                *out++ = (char)(0xC0 | code >> 6);
                *out++ = (char)(0x80 | (code & 0x3F));
            }
            else if (code < 0x10000)
            {
                *out++ = (char)(0xE0 | code >> 12);
                *out++ = (char)(0x80 | (code >> 6 & 0x3F));
                *out++ = (char)(0x80 | (code & 0x3F));
            }
            else
            {
                *out++ = (char)(0xF0 | code >> 18);
                *out++ = (char)(0x80 | (code >> 12 & 0x3F));
                *out++ = (char)(0x80 | (code >> 6 & 0x3F));
                *out++ = (char)(0x80 | (code & 0x3F));
            }
        }
        m_size = (uint32_t)(out - m_data);
    }

    const char* data() const { return m_data; }
    uint32_t size() const { return m_size; }

private:
    const char* m_data;
    uint32_t m_size;
    char m_inline[192];
    std::string m_heap;
};

// Transcodes UTF-8 the way the module's own decoder would, writing only the
// units that fit; returns the full UTF-16 byte length.
size_t encodeUtf16(const char* data, size_t size, uint8_t* out, size_t capacity)
{
    auto in = reinterpret_cast<const uint8_t*>(data);
    size_t written = 0;
    auto unit = [&](uint32_t value) {
        if (written + 2 <= capacity)
        {
            out[written] = (uint8_t)value;
            out[written + 1] = (uint8_t)(value >> 8);
        }
        written += 2;
    };
    size_t i = 0;
    while (i < size)
    {
        uint32_t code = in[i];
        if (code < 0x80)
        {
            unit(code);
            i++;
            continue;
        }
        size_t tail = (code & 0xE0) == 0xC0 ? 1 : (code & 0xF0) == 0xE0 ? 2 : 3;
        if (i + tail >= size)
        {
            break;
        }
        code &= 0x3F >> tail;
        for (size_t k = 1; k <= tail; k++)
        {
            code = code << 6 | (in[i + k] & 0x3F);
        }
        i += tail + 1;
        if (code < 0x10000)
        {
            unit(code);
        }
        else
        {
            code -= 0x10000;
            unit(0xD800 | code >> 10);
            unit(0xDC00 | (code & 0x3FF));
        }
    }
    return written;
}

bool moduleReadsUtf16(WasmScriptingVM* vm)
{
    WasmScriptingVM* owner = vm != nullptr ? vm : s_booting;
    return owner != nullptr && owner->utf16HostStrings();
}

// A host string in the encoding the module reads.
std::string moduleStringBytes(WasmScriptingVM* vm,
                              const char* data,
                              size_t size)
{
    if (!moduleReadsUtf16(vm))
    {
        return std::string(data, size);
    }
    std::string out(encodeUtf16(data, size, nullptr, 0), '\0');
    encodeUtf16(data, size, reinterpret_cast<uint8_t*>(&out[0]), out.size());
    return out;
}

// The retrying length contract in the module's encoding: copies what fits,
// returns the full byte length.
uint32_t fillModuleString(WasmScriptingVM* vm,
                          const std::string& value,
                          char* buffer,
                          uint32_t capacity)
{
    if (!moduleReadsUtf16(vm))
    {
        memcpy(buffer, value.data(), std::min<size_t>(value.size(), capacity));
        return (uint32_t)value.size();
    }
    return (uint32_t)encodeUtf16(value.data(),
                                 value.size(),
                                 reinterpret_cast<uint8_t*>(buffer),
                                 capacity);
}

// Prototypes, descriptor PODs, and registration tables for the rive_*_v1
// namespaces come from the binding IDL (src/wasm/idl/bindings.py); the
// declarations pin each implementation below to the contract signature.
#include "wasm_natives_gen.hpp"

// --- emscripten setjmp/longjmp glue -----------------------------------------

void throwLongjmpNative(wasm_exec_env_t env)
{
    wasm_runtime_set_exception(wasm_runtime_get_module_inst(env), kLongjmpTag);
}

void invokeViiNative(wasm_exec_env_t env,
                     uint32_t index,
                     uint32_t a1,
                     uint32_t a2)
{
    WasmScriptingVM* vm = vmFromEnv(env);
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    uint32_t sp = vm->callModule("emscripten_stack_get_current", 0, nullptr);
    uint32_t argv[2] = {a1, a2};
    if (wasm_runtime_call_indirect(env, index, 2, argv))
    {
        return;
    }
    const char* exception = wasm_runtime_get_exception(inst);
    if (exception != nullptr && strstr(exception, kLongjmpTag) != nullptr)
    {
        wasm_runtime_clear_exception(inst);
        uint32_t restoreArgs[1] = {sp};
        vm->callModule("_emscripten_stack_restore", 1, restoreArgs);
        uint32_t threwArgs[2] = {1, 0};
        vm->callModule("setThrew", 2, threwArgs);
        return;
    }
    // Genuine trap: leave the exception set so it propagates outward.
}

// --- remaining emscripten env imports ---------------------------------------

void abortJs(wasm_exec_env_t env)
{
    wasm_runtime_set_exception(wasm_runtime_get_module_inst(env),
                               "script module abort");
}

void memcpyJs(wasm_exec_env_t env, uint32_t dst, uint32_t src, uint32_t n)
{
    WasmScriptingVM* vm = vmFromEnv(env);
    void* dstPtr = vm->resolveModulePtr(dst, n);
    void* srcPtr = vm->resolveModulePtr(src, n);
    if (dstPtr == nullptr || srcPtr == nullptr)
    {
        wasm_runtime_set_exception(wasm_runtime_get_module_inst(env),
                                   "script module memcpy out of bounds");
        return;
    }
    memmove(dstPtr, srcPtr, n);
}

double getNow(wasm_exec_env_t env)
{
    // Same dev hook as dateNow: clock() feeds Luau's default RNG seed. A
    // pinned clock also parks the module's execution budget.
    if (getenv("RIVE_WASM_FIXED_DATE") != nullptr)
    {
        return 0;
    }
    auto now = std::chrono::steady_clock::now().time_since_epoch();
    return std::chrono::duration<double, std::milli>(now).count();
}

double dateNow(wasm_exec_env_t env)
{
    // Dev hook: a pinned date (epoch ms) keeps wasm lanes reproducible when
    // harnesses A/B the same module over wall-clock-seeded content.
    static const char* fixed = getenv("RIVE_WASM_FIXED_DATE");
    if (fixed != nullptr)
    {
        return atof(fixed);
    }
    auto now = std::chrono::system_clock::now().time_since_epoch();
    return std::chrono::duration<double, std::milli>(now).count();
}

// sbrk's growth request: enlarge linear memory to cover `size` bytes.
// The module's declared maximum still caps the growth.
uint32_t resizeHeap(wasm_exec_env_t env, uint32_t size)
{
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    wasm_memory_inst_t memory = wasm_runtime_get_memory(inst, 0);
    if (memory == nullptr)
    {
        return 0;
    }
    const uint64_t kPageSize = 65536;
    uint64_t wantPages = ((uint64_t)size + kPageSize - 1) / kPageSize;
    uint64_t curPages = wasm_memory_get_cur_page_count(memory);
    if (wantPages <= curPages)
    {
        return 1;
    }
    return wasm_runtime_enlarge_memory(inst, wantPages - curPages) ? 1 : 0;
}

static bool localTime(double epochSeconds, time_t& at, struct tm& local)
{
    at = (time_t)epochSeconds;
#ifdef _WIN32
    return localtime_s(&local, &at) == 0;
#else
    return localtime_r(&at, &local) != nullptr;
#endif
}

// Seconds the local rendering sits ahead of UTC.
static int32_t utcOffsetOf(struct tm local, time_t at)
{
#ifdef _WIN32
    return (int32_t)(_mkgmtime(&local) - at);
#else
    return (int32_t)(timegm(&local) - at);
#endif
}

// --- emscripten time imports: the Luau VM blob's os.date and os.time walk
// through these, so they serve the host's real calendar. Without WASM_BIGINT
// the module passes time_t as two i32 halves. struct tm is musl's wasm32
// layout: nine ints, the gmtoff long, then tm_zone, which the module's own
// libc fills.

static time_t moduleTime(uint32_t low, uint32_t high)
{
    return (time_t)(((uint64_t)high << 32) | low);
}

static void writeTm(wasm_exec_env_t env,
                    uint32_t tmPtr,
                    const struct tm& time,
                    int32_t gmtoff)
{
    int32_t* fields = (int32_t*)vmFromEnv(env)->resolveModulePtr(tmPtr, 44);
    if (fields == nullptr)
    {
        return;
    }
    fields[0] = time.tm_sec;
    fields[1] = time.tm_min;
    fields[2] = time.tm_hour;
    fields[3] = time.tm_mday;
    fields[4] = time.tm_mon;
    fields[5] = time.tm_year;
    fields[6] = time.tm_wday;
    fields[7] = time.tm_yday;
    fields[8] = time.tm_isdst;
    fields[9] = gmtoff;
}

void gmtimeJs(wasm_exec_env_t env, uint32_t low, uint32_t high, uint32_t tmPtr)
{
    time_t at = moduleTime(low, high);
    struct tm utc;
#ifdef _WIN32
    if (gmtime_s(&utc, &at) != 0)
#else
    if (gmtime_r(&at, &utc) == nullptr)
#endif
    {
        return;
    }
    writeTm(env, tmPtr, utc, 0);
}

void localtimeJs(wasm_exec_env_t env,
                 uint32_t low,
                 uint32_t high,
                 uint32_t tmPtr)
{
    time_t at;
    struct tm local;
    if (!localTime((double)moduleTime(low, high), at, local))
    {
        return;
    }
    writeTm(env, tmPtr, local, utcOffsetOf(local, at));
}

// The module's tzset: seconds west of UTC, whether the zone observes
// daylight saving, and the two zone names into its 17 byte buffers.
void tzsetJs(wasm_exec_env_t env,
             uint32_t timezonePtr,
             uint32_t daylightPtr,
             uint32_t stdNamePtr,
             uint32_t dstNamePtr)
{
    WasmScriptingVM* vm = vmFromEnv(env);
#ifdef _WIN32
    _tzset();
    long west = 0;
    int observesDst = 0;
    _get_timezone(&west);
    _get_daylight(&observesDst);
    const char* names[2] = {_tzname[0], _tzname[1]};
#elif defined(RIVE_NX)
    // nnSdk's libc has no tz globals, so read the zone off January and July
    // of this year, standard time being whichever sits further west.
    long west = 0;
    int observesDst = 0;
    const char* names[2] = {"", ""};
    time_t at;
    struct tm probe[2];
    if (localTime((double)time(nullptr), at, probe[0]))
    {
        int year = probe[0].tm_year;
        int32_t offset[2];
        bool ok = true;
        for (int i = 0; i < 2 && ok; i++)
        {
            struct tm start{};
            start.tm_year = year;
            start.tm_mon = i * 6;
            start.tm_mday = 1;
            ok = localTime((double)timegm(&start), at, probe[i]);
            offset[i] = utcOffsetOf(probe[i], at);
        }
        if (ok)
        {
            int std = offset[1] < offset[0] ? 1 : 0;
            west = -offset[std];
            observesDst = offset[0] != offset[1];
            names[0] = probe[std].tm_zone;
            names[1] = probe[observesDst ? 1 - std : std].tm_zone;
        }
    }
#else
    tzset();
    long west = timezone;
    int observesDst = daylight;
    const char* names[2] = {tzname[0], tzname[1]};
#endif
    if (int32_t* out = (int32_t*)vm->resolveModulePtr(timezonePtr, 4))
    {
        *out = (int32_t)west;
    }
    if (int32_t* out = (int32_t*)vm->resolveModulePtr(daylightPtr, 4))
    {
        *out = observesDst;
    }
    uint32_t namePtrs[2] = {stdNamePtr, dstNamePtr};
    for (int i = 0; i < 2; i++)
    {
        if (char* out = (char*)vm->resolveModulePtr(namePtrs[i], 17))
        {
            strncpy(out, names[i] != nullptr ? names[i] : "", 16);
            out[16] = '\0';
        }
    }
}

uint32_t strftimeNative(wasm_exec_env_t env,
                        uint32_t out,
                        uint32_t capacity,
                        uint32_t format,
                        uint32_t tmPtr)
{
    WasmScriptingVM* vm = vmFromEnv(env);
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    char* outPtr = (char*)vm->resolveModulePtr(out, capacity);
    const int32_t* fields = (const int32_t*)vm->resolveModulePtr(tmPtr, 44);
    if (outPtr == nullptr || fields == nullptr ||
        !wasm_runtime_validate_app_str_addr(inst, format))
    {
        return 0;
    }
    struct tm time = {};
    time.tm_sec = fields[0];
    time.tm_min = fields[1];
    time.tm_hour = fields[2];
    time.tm_mday = fields[3];
    time.tm_mon = fields[4];
    time.tm_year = fields[5];
    time.tm_wday = fields[6];
    time.tm_yday = fields[7];
    time.tm_isdst = fields[8];
#ifndef _WIN32
    time.tm_gmtoff = fields[9];
    // The zone name lives in module memory, so it must be translated before
    // the host's %Z reads it.
    uint32_t zone = (uint32_t)fields[10];
    if (zone != 0 && wasm_runtime_validate_app_str_addr(inst, zone))
    {
        time.tm_zone = (char*)wasm_runtime_addr_app_to_native(inst, zone);
    }
#endif
    return (uint32_t)strftime(
        outPtr,
        capacity,
        (const char*)wasm_runtime_addr_app_to_native(inst, format),
        &time);
}

// Older libc++ routes stream formatting through the locale variant.
uint32_t strftimeLNative(wasm_exec_env_t env,
                         uint32_t out,
                         uint32_t capacity,
                         uint32_t format,
                         uint32_t tmPtr,
                         uint32_t locale)
{
    return strftimeNative(env, out, capacity, format, tmPtr);
}

// A module assert would otherwise trap with no message.
void assertFail(wasm_exec_env_t env,
                uint32_t message,
                uint32_t file,
                uint32_t line,
                uint32_t function)
{
    WasmScriptingVM* vm = vmFromEnv(env);
    auto text = [vm](uint32_t ptr) {
        const char* str =
            ptr != 0 ? (const char*)vm->resolveModulePtr(ptr, 1) : nullptr;
        return str != nullptr ? str : "?";
    };
    fprintf(stderr,
            "module assertion failed: %s (%s:%u, %s)\n",
            text(message),
            text(file),
            line,
            text(function));
    wasm_runtime_set_exception(wasm_runtime_get_module_inst(env),
                               "module assertion failed");
}

// The blob's print goes through fd_write; intercept it so script output
// reaches the host's sink instead of the process stdout. The signature must
// match the libc-wasi builtin's "(i*i*)i": wamrc resolves WASI imports
// against the builtin table at compile time and inlines the app-to-native
// conversion for the '*' params, so an int-only registration receives
// native pointers under AOT while the interpreter honors the raw ints.
uint32_t fdWrite(wasm_exec_env_t env,
                 uint32_t fd,
                 uint32_t* iovs,
                 uint32_t iovcnt,
                 uint32_t* nwritten)
{
    WasmScriptingVM* vm = vmFromEnv(env);
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    if (!wasm_runtime_validate_native_addr(inst, iovs, (uint64_t)iovcnt * 8) ||
        !wasm_runtime_validate_native_addr(inst, nwritten, 4))
    {
        return 28; // EINVAL
    }
    uint32_t total = 0;
    for (uint32_t i = 0; i < iovcnt; i++)
    {
        uint32_t* io = iovs + i * 2;
        uint32_t ptr = io[0], len = io[1];
        const char* data =
            len != 0 ? (const char*)vm->resolveModulePtr(ptr, len) : nullptr;
        if (data != nullptr)
        {
            // Module stderr carries script errors; keep it out of the print
            // sink so a capturing harness cannot swallow them.
            if (fd == 2)
            {
                fwrite(data, 1, len, stderr);
            }
            else
            {
                WasmScriptingVMNatives::print(vm, data, len);
            }
            total += len;
        }
    }
    *nwritten = total;
    return 0;
}

// vm_host externalizes a handful of rive C++ methods as env imports that
// the runtime path never reaches (the live GPU path goes through the
// rive_gpu_v1 natives, not these direct calls). The fast interpreter
// tolerates an unresolved import, trapping only on an actual call, but
// wamrc bakes a null call target into the AOT that faults the moment a
// static initializer takes its address. Registering inert stubs gives the
// AOT valid pointers. Signatures mirror vm_host's import types.
uint32_t deadEnvImport_i_i(wasm_exec_env_t, uint32_t) { return 0; }
void deadCoreBytesDeserialize(wasm_exec_env_t, uint32_t, uint32_t) {}
void deadCoreStringDeserialize(wasm_exec_env_t, uint32_t, uint32_t) {}
void deadBeginFrame(wasm_exec_env_t, uint32_t, uint32_t) {}
void deadFlush(wasm_exec_env_t, uint32_t, uint32_t) {}
void deadAddFileAsset(wasm_exec_env_t, uint32_t, uint32_t) {}
uint32_t deadEnvImport_ii_i(wasm_exec_env_t, uint32_t, uint32_t) { return 0; }
void deadEnvImport_iiii(wasm_exec_env_t, uint32_t, uint32_t, uint32_t, uint32_t)
{}

// __cxa_throw never returns; a no-op stub falls through to the module's
// `unreachable` and corrupts the shadow stack under AOT. Trap instead so
// the call unwinds like the interpreter's unlinked-import path, and name
// the thrown type from its Itanium type_info (wasm32: __type_name at +4).
// Registered with libc-builtin's "(**i)": wamrc knows that table and
// inlines the pointer conversion, so an int-only registration would
// receive native pointers under AOT.
void cxaThrowNative(wasm_exec_env_t env,
                    void* thrown,
                    void* tinfo,
                    uint32_t dest)
{
    (void)thrown;
    (void)dest;
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    const char* typeName = "?";
    if (tinfo != nullptr && wasm_runtime_validate_native_addr(inst, tinfo, 8))
    {
        uint32_t nameApp = ((uint32_t*)tinfo)[1];
        if (wasm_runtime_validate_app_str_addr(inst, nameApp))
        {
            typeName =
                (const char*)wasm_runtime_addr_app_to_native(inst, nameApp);
        }
    }
    fprintf(stderr, "[wasm] C++ exception thrown: %s\n", typeName);
    wasm_runtime_set_exception(inst, "c++ exception");
}

// Math.random's seed; the fixed date env that pins script time pins it too.
double envSeed(wasm_exec_env_t)
{
    if (getenv("RIVE_WASM_FIXED_DATE") != nullptr)
    {
        return 1.0;
    }
    return (double)std::chrono::steady_clock::now().time_since_epoch().count();
}

NativeSymbol kEnvNatives[] = {
    {"invoke_vii", (void*)invokeViiNative, "(iii)", nullptr},
    {"seed", (void*)envSeed, "()F", nullptr},
    {"_ZN4rive12CoreUintType11deserializeERNS_12BinaryReaderE",
     (void*)deadEnvImport_i_i,
     "(i)i",
     nullptr},
    {"_ZN4rive13CoreBytesType11deserializeERNS_12BinaryReaderE",
     (void*)deadCoreBytesDeserialize,
     "(ii)",
     nullptr},
    {"_ZN4rive14CoreStringType11deserializeERNS_12BinaryReaderE",
     (void*)deadCoreStringDeserialize,
     "(ii)",
     nullptr},
    {"_ZN4rive3gpu13RenderContext24makeDeferredRenderCanvasEjj",
     (void*)deadEnvImport_iiii,
     "(iiii)",
     nullptr},
    {"_ZN4rive3gpu13RenderContext16makeRenderCanvasEjj",
     (void*)deadEnvImport_iiii,
     "(iiii)",
     nullptr},
    {"_ZN4rive3gpu13RenderContext10beginFrameERKNS1_15FrameDescriptorE",
     (void*)deadBeginFrame,
     "(ii)",
     nullptr},
    {"_ZN4rive12RiveRendererC1EPNS_3gpu13RenderContextE",
     (void*)deadEnvImport_ii_i,
     "(ii)i",
     nullptr},
    {"_ZN4rive3gpu13RenderContext5flushERKNS1_14FlushResourcesE",
     (void*)deadFlush,
     "(ii)",
     nullptr},
    {"_ZN4rive17BackboardImporter12addFileAssetENS_3rcpINS_9FileAssetEEE",
     (void*)deadAddFileAsset,
     "(ii)",
     nullptr},
    {"__cxa_throw", (void*)cxaThrowNative, "(**i)", nullptr},
    {"_emscripten_throw_longjmp", (void*)throwLongjmpNative, "()", nullptr},
    {"_abort_js", (void*)abortJs, "()", nullptr},
    {"_emscripten_memcpy_js", (void*)memcpyJs, "(iii)", nullptr},
    {"emscripten_get_now", (void*)getNow, "()F", nullptr},
    {"emscripten_date_now", (void*)dateNow, "()F", nullptr},
    {"emscripten_resize_heap", (void*)resizeHeap, "(i)i", nullptr},
    {"strftime", (void*)strftimeNative, "(iiii)i", nullptr},
    {"strftime_l", (void*)strftimeLNative, "(iiiii)i", nullptr},
    {"_tzset_js", (void*)tzsetJs, "(iiii)", nullptr},
    {"_localtime_js", (void*)localtimeJs, "(iii)", nullptr},
    {"_gmtime_js", (void*)gmtimeJs, "(iii)", nullptr},
    {"__assert_fail", (void*)assertFail, "(iiii)", nullptr},
};

// Module streams are not seekable. The blob imports the emscripten-legalized
// form, offset i64 split across two i32s.
uint32_t fdSeek(wasm_exec_env_t env,
                uint32_t fd,
                uint32_t offsetLow,
                uint32_t offsetHigh,
                uint32_t whence,
                uint32_t newOffsetPtr)
{
    return 70; // WASI ESPIPE
}

// The blob's libc asks for the environment at start and closes its streams
// at exit; there is no environment and the streams are the log.
uint32_t environSizesGet(wasm_exec_env_t env, uint32_t* count, uint32_t* size)
{
    wasm_module_inst_t inst = wasm_runtime_get_module_inst(env);
    if (!wasm_runtime_validate_native_addr(inst, count, 4) ||
        !wasm_runtime_validate_native_addr(inst, size, 4))
    {
        return 21; // WASI EFAULT
    }
    *count = 0;
    *size = 0;
    return 0;
}

uint32_t environGet(wasm_exec_env_t env, uint32_t* environ, char* buffer)
{
    return 0;
}

uint32_t fdClose(wasm_exec_env_t env, uint32_t fd) { return 0; }

NativeSymbol kWasiNatives[] = {
    {"fd_write", (void*)fdWrite, "(i*i*)i", nullptr},
    {"fd_seek", (void*)fdSeek, "(iiiii)i", nullptr},
    {"environ_sizes_get", (void*)environSizesGet, "(**)i", nullptr},
    {"environ_get", (void*)environGet, "(**)i", nullptr},
    {"fd_close", (void*)fdClose, "(i)i", nullptr},
};

// --- rive_path/paint/renderer_v1: handle-backed render objects --------------

// The module's ModuleRenderPath mirror; geometry arrives through update and
// rebuilds the real render path.
// Size then fill: copies when it fits, always answers the full count.
template <typename T>
uint32_t fillOut(Span<const T> words, T* out, uint32_t outCount)
{
    if (out != nullptr && words.size() <= outCount)
    {
        memcpy(out, words.data(), words.size() * sizeof(T));
    }
    return (uint32_t)words.size();
}

template <typename T>
uint32_t fillOut(const std::vector<T>& words, T* out, uint32_t outCount)
{
    return fillOut(Span<const T>(words.data(), words.size()), out, outCount);
}

// A RawPath's points as the flat float stream the modules read.
Span<const float> pathFloats(const RawPath& path)
{
    return Span<const float>((const float*)path.points().data(),
                             path.points().size() * 2);
}

Span<const uint8_t> pathVerbBytes(const RawPath& path)
{
    return Span<const uint8_t>((const uint8_t*)path.verbs().data(),
                               path.verbs().size());
}

// The geometry stays host side so paths composed from other paths never
// cross back; the render path rebuilds lazily after a host side append.
struct HostPath
{
    RawPath raw;
    FillRule fillRule = FillRule::clockwise;
    rcp<RenderPath> path;
    bool renderDirty = false;
};

HostPath* resolvePath(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostPath*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::path));
}

RenderPath* hostRenderPath(WasmScriptingVM* vm, HostPath* hostPath)
{
    if (hostPath == nullptr)
    {
        return nullptr;
    }
    if (hostPath->renderDirty)
    {
        hostPath->path =
            vm->factory()->makeRenderPath(hostPath->raw, hostPath->fillRule);
        hostPath->renderDirty = false;
    }
    return hostPath->path.get();
}

struct HostPaint
{
    rcp<RenderPaint> paint;
};

uint32_t pathNewImpl(WasmScriptingVM* vm)
{
    if (vm == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::path,
                              new HostPath());
}

void pathUpdateImpl(WasmScriptingVM* vm,
                    uint32_t handle,
                    const uint8_t* verbs,
                    uint32_t verbCount,
                    const float* points,
                    uint32_t floatCount,
                    uint32_t fillRule)
{
    if (vm == nullptr)
    {
        return;
    }
    auto hostPath = static_cast<HostPath*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::path));
    if (hostPath == nullptr)
    {
        return;
    }
    hostPath->raw =
        RawPath(Span<const PathVerb>((const PathVerb*)verbs, verbCount),
                Span<const Vec2D>((const Vec2D*)points, floatCount / 2));
    hostPath->fillRule = (FillRule)fillRule;
    hostPath->path =
        vm->factory()->makeRenderPath(hostPath->raw, hostPath->fillRule);
    hostPath->renderDirty = false;
}

void pathAddImpl(WasmScriptingVM* vm,
                 uint32_t handle,
                 uint32_t otherHandle,
                 float xx,
                 float xy,
                 float yx,
                 float yy,
                 float tx,
                 float ty)
{
    auto hostPath = resolvePath(vm, handle);
    auto other = resolvePath(vm, otherHandle);
    if (hostPath == nullptr || other == nullptr)
    {
        return;
    }
    Mat2D transform(xx, xy, yx, yy, tx, ty);
    hostPath->raw.addPath(other->raw, &transform);
    hostPath->renderDirty = true;
}

uint32_t pathVerbsImpl(WasmScriptingVM* vm,
                       uint32_t handle,
                       uint8_t* out,
                       uint32_t outCount)
{
    auto hostPath = resolvePath(vm, handle);
    if (hostPath == nullptr)
    {
        return 0;
    }
    return fillOut(pathVerbBytes(hostPath->raw), out, outCount);
}

uint32_t pathPointsImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        float* out,
                        uint32_t outCount)
{
    auto hostPath = resolvePath(vm, handle);
    if (hostPath == nullptr)
    {
        return 0;
    }
    return fillOut(pathFloats(hostPath->raw), out, outCount);
}

void pathEffectResultImpl(WasmScriptingVM* vm,
                          const uint8_t* verbs,
                          uint32_t verbCount,
                          const float* points,
                          uint32_t floatCount)
{
    if (vm == nullptr || vm->pathEffectOut() == nullptr)
    {
        return;
    }
    RawPath rawPath(Span<const PathVerb>((const PathVerb*)verbs, verbCount),
                    Span<const Vec2D>((const Vec2D*)points, floatCount / 2));
    vm->pathEffectOut()->addPath(rawPath);
}

// One handle kind for the three measure shapes: a whole path measure, a
// contour iterator (measures nothing itself) and a contour it produced.
// The geometry is copied so the module's path can change underneath.
struct HostMeasure
{
    std::unique_ptr<RawPath> source;
    std::unique_ptr<PathMeasure> path;
    std::unique_ptr<ContourMeasureIter> iter;
    rcp<ContourMeasure> contour;
    RawPath segment;

    float length() const
    {
        return path ? path->length() : contour ? contour->length() : 0.0f;
    }

    bool isClosed() const
    {
        return path ? path->isClosed() : contour ? contour->isClosed() : false;
    }

    ContourMeasure::PosTan posTan(float distance) const
    {
        if (path)
        {
            auto at = path->atDistance(distance);
            return {at.pos, at.tan};
        }
        if (contour)
        {
            return contour->getPosTan(distance);
        }
        return {};
    }

    void getSegment(float start, float end, RawPath* dst, bool startWithMove)
    {
        if (path)
        {
            path->getSegment(start, end, dst, startWithMove);
        }
        else if (contour)
        {
            contour->getSegment(start, end, dst, startWithMove);
        }
    }
};

HostMeasure* resolveMeasure(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostMeasure*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::measure));
}

std::unique_ptr<RawPath> copyGeometry(const uint8_t* verbs,
                                      uint32_t verbCount,
                                      const float* points,
                                      uint32_t floatCount)
{
    return std::make_unique<RawPath>(
        Span<const PathVerb>((const PathVerb*)verbs, verbCount),
        Span<const Vec2D>((const Vec2D*)points, floatCount / 2));
}

uint32_t measurePathNewImpl(WasmScriptingVM* vm,
                            const uint8_t* verbs,
                            uint32_t verbCount,
                            const float* points,
                            uint32_t floatCount)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto measure = new HostMeasure();
    measure->source = copyGeometry(verbs, verbCount, points, floatCount);
    measure->path = std::make_unique<PathMeasure>(measure->source.get());
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::measure,
                              measure);
}

uint32_t measureContoursNewImpl(WasmScriptingVM* vm,
                                const uint8_t* verbs,
                                uint32_t verbCount,
                                const float* points,
                                uint32_t floatCount)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto measure = new HostMeasure();
    measure->source = copyGeometry(verbs, verbCount, points, floatCount);
    measure->iter = std::make_unique<ContourMeasureIter>(measure->source.get());
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::measure,
                              measure);
}

uint32_t measureContourNextImpl(WasmScriptingVM* vm, uint32_t handle)
{
    HostMeasure* iter = resolveMeasure(vm, handle);
    if (iter == nullptr || !iter->iter)
    {
        return 0;
    }
    rcp<ContourMeasure> next = iter->iter->next();
    if (next == nullptr)
    {
        return 0;
    }
    auto measure = new HostMeasure();
    measure->contour = std::move(next);
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::measure,
                              measure);
}

float measureLengthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    return measure != nullptr ? measure->length() : 0.0f;
}

uint32_t measureIsClosedImpl(WasmScriptingVM* vm, uint32_t handle)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    return measure != nullptr && measure->isClosed() ? 1 : 0;
}

void measurePosTanImpl(WasmScriptingVM* vm,
                       uint32_t handle,
                       float distance,
                       float* out,
                       uint32_t outCount)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    if (measure == nullptr || out == nullptr || outCount < 4)
    {
        return;
    }
    auto posTan = measure->posTan(distance);
    out[0] = posTan.pos.x;
    out[1] = posTan.pos.y;
    out[2] = posTan.tan.x;
    out[3] = posTan.tan.y;
}

void measureWarpImpl(WasmScriptingVM* vm,
                     uint32_t handle,
                     float x,
                     float y,
                     float* out,
                     uint32_t outCount)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    if (measure == nullptr || out == nullptr || outCount < 2)
    {
        return;
    }
    auto posTan = measure->posTan(x);
    out[0] = posTan.pos.x - posTan.tan.y * y;
    out[1] = posTan.pos.y + posTan.tan.x * y;
}

uint32_t measureExtractImpl(WasmScriptingVM* vm,
                            uint32_t handle,
                            float startDistance,
                            float endDistance,
                            uint32_t startWithMove)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    if (measure == nullptr)
    {
        return 0;
    }
    measure->segment.rewind();
    measure->getSegment(startDistance,
                        endDistance,
                        &measure->segment,
                        startWithMove != 0);
    return (uint32_t)measure->segment.verbs().size();
}

uint32_t measureExtractReadImpl(WasmScriptingVM* vm,
                                uint32_t handle,
                                uint8_t* verbs,
                                uint32_t verbCount,
                                float* points,
                                uint32_t floatCount)
{
    HostMeasure* measure = resolveMeasure(vm, handle);
    if (measure == nullptr)
    {
        return 0;
    }
    const RawPath& segment = measure->segment;
    uint32_t floats = (uint32_t)segment.points().size() * 2;
    if (verbCount < segment.verbs().size() || floatCount < floats)
    {
        return 0;
    }
    memcpy(verbs, segment.verbs().data(), segment.verbs().size());
    memcpy(points, segment.points().data(), floats * sizeof(float));
    return floats;
}

void measureReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete resolveMeasure(vm, handle);
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::measure);
}

void pathReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostPath*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::path));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::path);
}

uint32_t paintNewImpl(WasmScriptingVM* vm)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto hostPaint = new HostPaint{vm->factory()->makeRenderPaint()};
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::paint,
                              hostPaint);
}

void paintReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostPaint*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::paint));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::paint);
}

RenderPaint* resolvePaint(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    auto hostPaint = static_cast<HostPaint*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::paint));
    return hostPaint != nullptr ? hostPaint->paint.get() : nullptr;
}

void paintStyleImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->style((RenderPaintStyle)value);
    }
}
void paintColorImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->color(value);
    }
}
void paintThicknessImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->thickness(value);
    }
}
void paintJoinImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->join((StrokeJoin)value);
    }
}
void paintCapImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->cap((StrokeCap)value);
    }
}
void paintBlendModeImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->blendMode((BlendMode)value);
    }
}
void paintFeatherImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
    if (auto paint = resolvePaint(vm, handle))
    {
        paint->feather(value);
    }
}

struct HostShader
{
    rcp<RenderShader> shader;
};

uint32_t shaderLinearImpl(WasmScriptingVM* vm,
                          float sx,
                          float sy,
                          float ex,
                          float ey,
                          uint32_t colorsPtr,
                          uint32_t stopsPtr,
                          uint32_t count)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto colors = (const ColorInt*)vm->resolveModulePtr(colorsPtr, count * 4);
    auto stops = (const float*)vm->resolveModulePtr(stopsPtr, count * 4);
    if (colors == nullptr || stops == nullptr)
    {
        return 0;
    }
    auto shader =
        vm->factory()->makeLinearGradient(sx, sy, ex, ey, colors, stops, count);
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::shader,
                              new HostShader{std::move(shader)});
}

uint32_t shaderRadialImpl(WasmScriptingVM* vm,
                          float cx,
                          float cy,
                          float radius,
                          uint32_t colorsPtr,
                          uint32_t stopsPtr,
                          uint32_t count)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto colors = (const ColorInt*)vm->resolveModulePtr(colorsPtr, count * 4);
    auto stops = (const float*)vm->resolveModulePtr(stopsPtr, count * 4);
    if (colors == nullptr || stops == nullptr)
    {
        return 0;
    }
    auto shader =
        vm->factory()->makeRadialGradient(cx, cy, radius, colors, stops, count);
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::shader,
                              new HostShader{std::move(shader)});
}

void shaderReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostShader*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::shader));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::shader);
}

void paintShaderImpl(WasmScriptingVM* vm,
                     uint32_t paintHandle,
                     uint32_t shaderHandle)
{
    auto paint = resolvePaint(vm, paintHandle);
    if (vm == nullptr || paint == nullptr)
    {
        return;
    }
    auto hostShader = static_cast<HostShader*>(
        vm->handles().resolve(shaderHandle,
                              WasmScriptingVM::HandleTable::Tag::shader));
    paint->shader(hostShader != nullptr ? hostShader->shader : nullptr);
}

// The object's file asset of type T by name; accept skips matches that
// carry nothing, the way the Luau lookups keep scanning past them.
template <typename T>
T* findFileAsset(WasmScriptingVM* vm,
                 uint32_t objectHandle,
                 const char* name,
                 uint32_t length,
                 bool (*accept)(T*) = nullptr)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    if (object == nullptr || object->scriptAsset() == nullptr ||
        object->scriptAsset()->file() == nullptr)
    {
        return nullptr;
    }
    std::string key(name, length);
    for (const auto& asset : object->scriptAsset()->file()->assets())
    {
        if (!asset->is<T>() || asset->name() != key)
        {
            continue;
        }
        T* match = asset->template as<T>();
        if (accept == nullptr || accept(match))
        {
            return match;
        }
    }
    return nullptr;
}

struct HostImage
{
    rcp<RenderImage> image;
#ifdef RIVE_CANVAS
    // A canvas image outlives its canvas only through this.
    rcp<gpu::RenderCanvas> sourceCanvas;
#endif
};

HostImage* resolveImage(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostImage*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::image));
}

uint32_t imageFromAssetImpl(WasmScriptingVM* vm,
                            uint32_t objectHandle,
                            const char* name,
                            uint32_t length)
{
    auto asset = findFileAsset<ImageAsset>(vm, objectHandle, name, length);
    if (asset == nullptr || asset->renderImage() == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::image,
                              new HostImage{ref_rcp(asset->renderImage())});
}

uint32_t imageWidthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveImage(vm, handle);
    return host != nullptr ? (uint32_t)host->image->width() : 0;
}

uint32_t imageHeightImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveImage(vm, handle);
    return host != nullptr ? (uint32_t)host->image->height() : 0;
}

void imageReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostImage*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::image));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::image);
}

uint32_t imageDecodeImpl(WasmScriptingVM* vm,
                         const uint8_t* bytes,
                         uint32_t byteCount,
                         uint32_t token)
{
    if (vm == nullptr || bytes == nullptr || byteCount == 0)
    {
        return 0;
    }
    return vm->startImageDecode(bytes, byteCount, token) ? 1 : 0;
}

void imageDecodeCancelImpl(WasmScriptingVM* vm, uint32_t token)
{
    if (vm != nullptr)
    {
        vm->cancelImageDecode(token);
    }
}

#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
struct HostGpuCanvas
{
    rcp<gpu::RenderCanvas> canvas;
    rcp<ore::TextureView> colorView;
};

struct HostGpuPass
{
    std::unique_ptr<ore::RenderPass> pass;
    bool pipelineSet = false;
};

struct HostGpuBuffer
{
    rcp<ore::Buffer> buffer;
};

struct HostGpuTexture
{
    rcp<ore::Texture> texture;
};

struct HostGpuSampler
{
    rcp<ore::Sampler> sampler;
};

struct HostGpuTextureView
{
    rcp<ore::TextureView> view;
};

struct HostGpuShaderModule
{
    rcp<ore::ShaderModule> shaderModule;
};

struct HostGpuBindGroupLayout
{
    rcp<ore::BindGroupLayout> layout;
};

struct HostGpuBindGroup
{
    rcp<ore::BindGroup> bindGroup;
};

struct HostGpuPipeline
{
    rcp<ore::Pipeline> pipeline;
};

ore::Context* gpuOreContext(WasmScriptingVM* vm)
{
    if (vm == nullptr || vm->factory() == nullptr)
    {
        return nullptr;
    }
    if (auto* recording = vm->factory()->ore())
    {
        return recording;
    }
    Factory* renderContext = vm->factory()->renderContext();
    return renderContext != nullptr ? renderContext->ore() : nullptr;
}

// The Lua bindings raise lastError as a script error; the module lane traps
// with the same text so the author reads the cause instead of a 0 handle.
uint32_t gpuRejected(WasmScriptingVM* vm,
                     ore::Context* context,
                     const char* what)
{
    std::string message = std::string(what) + ": " +
                          (context->lastError().empty() ? "creation failed"
                                                        : context->lastError());
    vm->raiseModuleError(message.c_str());
    return 0;
}

uint32_t gpuCanvasNewImpl(WasmScriptingVM* vm, uint32_t width, uint32_t height)
{
    if (vm == nullptr || vm->factory() == nullptr)
    {
        return 0;
    }
    // Like the Luau lane, a zero size gives a canvas without backing that
    // resize allocates once the layout size is known.
    if (width == 0 || height == 0)
    {
        return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuCanvas,
                                  new HostGpuCanvas{});
    }
    auto* renderContext =
        static_cast<gpu::RenderContext*>(vm->factory()->renderContext());
    ore::Context* oreContext = gpuOreContext(vm);
    if (renderContext == nullptr || oreContext == nullptr)
    {
        return 0;
    }
    auto* deferredHost = vm->factory()->deferredCanvasHost();
    auto canvas = deferredHost != nullptr
                      ? deferredHost->makeContentCanvas(width, height)
                      : renderContext->makeRenderCanvas(width, height);
    if (canvas == nullptr)
    {
        return 0;
    }
    auto colorView = oreContext->wrapCanvasTexture(canvas.get());
    if (colorView == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::gpuCanvas,
        new HostGpuCanvas{std::move(canvas), std::move(colorView)});
}

void gpuCanvasReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuCanvas*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuCanvas));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::gpuCanvas);
}

uint32_t gpuCanvasColorViewImpl(WasmScriptingVM* vm,
                                uint32_t canvasHandle,
                                uint32_t* props,
                                uint32_t propCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (vm == nullptr || oreContext == nullptr || propCount < 4)
    {
        return 0;
    }
    auto host = static_cast<HostGpuCanvas*>(
        vm->handles().resolve(canvasHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuCanvas));
    if (host == nullptr)
    {
        return 0;
    }
    props[2] = (uint32_t)oreContext->canvasTargetFormat();
    props[3] = 1;
    if (host->canvas == nullptr)
    {
        props[0] = 0;
        props[1] = 0;
        return 0;
    }
    props[0] = host->canvas->width();
    props[1] = host->canvas->height();
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuTextureView,
                              new HostGpuTextureView{host->colorView});
}

uint32_t gpuCanvasImageImpl(WasmScriptingVM* vm, uint32_t canvasHandle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostGpuCanvas*>(
        vm->handles().resolve(canvasHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuCanvas));
    if (host == nullptr || host->canvas == nullptr ||
        host->canvas->renderImage() == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::image,
                              new HostImage{ref_rcp(static_cast<RenderImage*>(
                                                host->canvas->renderImage())),
                                            host->canvas});
}

uint32_t gpuCanvasResizeImpl(WasmScriptingVM* vm,
                             uint32_t canvasHandle,
                             uint32_t width,
                             uint32_t height,
                             uint32_t* props,
                             uint32_t propCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (vm == nullptr || vm->factory() == nullptr || oreContext == nullptr ||
        width == 0 || height == 0 || propCount < 4)
    {
        return 0;
    }
    auto host = static_cast<HostGpuCanvas*>(
        vm->handles().resolve(canvasHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuCanvas));
    if (host == nullptr)
    {
        return 0;
    }
    auto* renderContext =
        static_cast<gpu::RenderContext*>(vm->factory()->renderContext());
    if (renderContext == nullptr)
    {
        return 0;
    }
    auto* deferredHost = vm->factory()->deferredCanvasHost();
    auto canvas = deferredHost != nullptr
                      ? deferredHost->makeContentCanvas(width, height)
                      : renderContext->makeRenderCanvas(width, height);
    if (canvas == nullptr)
    {
        return 0;
    }
    auto colorView = oreContext->wrapCanvasTexture(canvas.get());
    if (colorView == nullptr)
    {
        return 0;
    }
    host->canvas = std::move(canvas);
    host->colorView = std::move(colorView);
    props[0] = host->canvas->width();
    props[1] = host->canvas->height();
    props[2] = (uint32_t)oreContext->canvasTargetFormat();
    props[3] = 1;
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuTextureView,
                              new HostGpuTextureView{host->colorView});
}

uint32_t gpuFeaturesImpl(WasmScriptingVM* vm, uint32_t* out, uint32_t outCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (vm == nullptr || oreContext == nullptr || outCount < 19)
    {
        return 0;
    }
    // With ReplayCaps a recording context answers from shipped data; an
    // unknown snapshot must raise module-side instead of guessing.
    if (!oreContext->featuresKnown())
    {
        return ~0u;
    }
    const ore::Features& f = oreContext->features();
    out[0] = f.bc ? 1 : 0;
    out[1] = f.etc2 ? 1 : 0;
    out[2] = f.astc ? 1 : 0;
    out[3] = (uint32_t)f.maxTextureSize2D;
    out[4] = (uint32_t)f.maxTextureSizeCube;
    out[5] = (uint32_t)f.maxTextureSize3D;
    out[6] = f.anisotropicFiltering ? 1 : 0;
    out[7] = f.texture3D ? 1 : 0;
    out[8] = f.textureArrays ? 1 : 0;
    out[9] = f.colorBufferFloat ? 1 : 0;
    out[10] = f.colorBufferHalfFloat ? 1 : 0;
    out[11] = f.perTargetBlend ? 1 : 0;
    out[12] = f.perTargetWriteMask ? 1 : 0;
    out[13] = f.drawBaseInstance ? 1 : 0;
    out[14] = f.depthBiasClamp ? 1 : 0;
    out[15] = (uint32_t)f.maxColorAttachments;
    out[16] = (uint32_t)f.maxUniformBufferSize;
    out[17] = (uint32_t)f.maxSamplers;
    out[18] = (uint32_t)f.maxSamples;
    return 19;
}

uint32_t gpuPassBeginImpl(WasmScriptingVM* vm,
                          const rive_gpu_pass_desc_v1* podDesc,
                          uint32_t descByteCount,
                          const rive_gpu_pass_color_attachment_v1* colors,
                          uint32_t colorByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (vm == nullptr || oreContext == nullptr ||
        descByteCount < sizeof(*podDesc) ||
        colorByteCount % sizeof(*colors) != 0 ||
        podDesc->colorCount != colorByteCount / sizeof(*colors) ||
        podDesc->colorCount > 4)
    {
        return 0;
    }
    auto resolveView = [vm](uint32_t handle) -> ore::TextureView* {
        auto host = static_cast<HostGpuTextureView*>(vm->handles().resolve(
            handle,
            WasmScriptingVM::HandleTable::Tag::gpuTextureView));
        return host != nullptr ? host->view.get() : nullptr;
    };
    ore::RenderPassDesc desc;
    desc.colorCount = podDesc->colorCount;
    for (uint32_t i = 0; i < podDesc->colorCount; i++)
    {
        auto& out = desc.colorAttachments[i];
        out.view = resolveView(colors[i].view);
        if (out.view == nullptr)
        {
            return 0;
        }
        out.resolveTarget = colors[i].resolveTarget != 0
                                ? resolveView(colors[i].resolveTarget)
                                : nullptr;
        out.loadOp = (ore::LoadOp)colors[i].loadOp;
        out.storeOp = (ore::StoreOp)colors[i].storeOp;
        out.clearColor = {colors[i].clearR,
                          colors[i].clearG,
                          colors[i].clearB,
                          colors[i].clearA};
    }
    if (podDesc->depthView != 0)
    {
        desc.depthStencil.view = resolveView(podDesc->depthView);
        if (desc.depthStencil.view == nullptr)
        {
            return 0;
        }
    }
    desc.depthStencil.depthLoadOp = (ore::LoadOp)podDesc->depthLoadOp;
    desc.depthStencil.depthStoreOp = (ore::StoreOp)podDesc->depthStoreOp;
    desc.depthStencil.depthClearValue = podDesc->depthClearValue;
    desc.depthStencil.stencilLoadOp = (ore::LoadOp)podDesc->stencilLoadOp;
    desc.depthStencil.stencilStoreOp = (ore::StoreOp)podDesc->stencilStoreOp;
    desc.depthStencil.stencilClearValue = podDesc->stencilClearValue;
    auto pass = ore::cmd::beginRecordedRenderPass(*oreContext, desc);
    if (pass == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuPass,
                              new HostGpuPass{std::move(pass)});
}

uint32_t gpuImageViewImpl(WasmScriptingVM* vm,
                          uint32_t imageHandle,
                          uint32_t width,
                          uint32_t height)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (vm == nullptr || oreContext == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostImage*>(
        vm->handles().resolve(imageHandle,
                              WasmScriptingVM::HandleTable::Tag::image));
    if (host == nullptr)
    {
        return 0;
    }
    // Same dispatch as Image:view() in the Luau binding.
    rcp<ore::TextureView> view;
    if (!oreContext->isRecording())
    {
        if (host->sourceCanvas != nullptr)
        {
            view = oreContext->wrapCanvasSampleView(host->sourceCanvas.get());
        }
        else if (auto* riveImage =
                     lite_rtti_cast<RiveRenderImage*>(host->image.get());
                 riveImage != nullptr && riveImage->getTexture() != nullptr)
        {
            view = oreContext->wrapRiveTexture(riveImage->getTexture(),
                                               host->image->width(),
                                               host->image->height());
        }
    }
    else if (host->sourceCanvas != nullptr)
    {
        view = oreContext->recordWrapCanvasImage(host->sourceCanvas.get(),
                                                 host->image->width(),
                                                 host->image->height());
    }
    else if (auto* deferredImage =
                 lite_rtti_cast<cmd::DeferredRenderImage*>(host->image.get()))
    {
        view = oreContext->recordWrapImageView(deferredImage->id(),
                                               host->image->width(),
                                               host->image->height());
    }
    else
    {
        // A foreign image the recorder was handed rather than created.
        view = oreContext->recordWrapForeignImageView(host->image.get(),
                                                      host->image->width(),
                                                      host->image->height());
    }
    if (view == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuTextureView,
                              new HostGpuTextureView{std::move(view)});
}

HostGpuPass* resolveHostPass(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostGpuPass*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuPass));
}

ore::RenderPass* resolvePass(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveHostPass(vm, handle);
    return host != nullptr ? host->pass.get() : nullptr;
}

// The draw guards the Luau binding raises, with the same text so both lanes
// read the same cause. Returns false after raising.
bool gpuPassDrawAllowed(WasmScriptingVM* vm,
                        HostGpuPass* host,
                        const char* what,
                        int32_t baseVertex,
                        uint32_t firstInstance)
{
    if (!host->pipelineSet)
    {
        vm->raiseModuleError(ore::kGuardSetPipelineBeforeDraw);
        return false;
    }
    ore::Context* oreContext = gpuOreContext(vm);
    bool featuresKnown = oreContext != nullptr && oreContext->featuresKnown();
    if (featuresKnown && !oreContext->features().drawBaseInstance)
    {
        char message[160];
        if (baseVertex != 0)
        {
            snprintf(message,
                     sizeof(message),
                     ore::kGuardBaseVertexFormat,
                     what,
                     baseVertex);
            vm->raiseModuleError(message);
            return false;
        }
        if (firstInstance > 0)
        {
            snprintf(message,
                     sizeof(message),
                     ore::kGuardFirstInstanceFormat,
                     what,
                     firstInstance);
            vm->raiseModuleError(message);
            return false;
        }
    }
    return true;
}

void gpuPassSetPipelineImpl(WasmScriptingVM* vm,
                            uint32_t passHandle,
                            uint32_t pipelineHandle)
{
    auto* host = resolveHostPass(vm, passHandle);
    auto pipeline = static_cast<HostGpuPipeline*>(
        vm->handles().resolve(pipelineHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuPipeline));
    if (host == nullptr || pipeline == nullptr)
    {
        return;
    }
    // An attachment compat failure no-ops the backend and later draws crash
    // in the driver, so it surfaces here the way the Luau binding raises it.
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext != nullptr)
    {
        oreContext->clearLastError();
    }
    host->pass->setPipeline(pipeline->pipeline.get());
    if (oreContext != nullptr && !oreContext->lastError().empty())
    {
        gpuRejected(vm, oreContext, "setPipeline");
        return;
    }
    host->pipelineSet = true;
}

void gpuPassSetVertexBufferImpl(WasmScriptingVM* vm,
                                uint32_t passHandle,
                                uint32_t slot,
                                uint32_t bufferHandle,
                                uint32_t offset)
{
    auto* pass = resolvePass(vm, passHandle);
    auto buffer = static_cast<HostGpuBuffer*>(
        vm->handles().resolve(bufferHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuBuffer));
    if (pass == nullptr || buffer == nullptr)
    {
        return;
    }
    if (slot >= ore::kMaxVertexBufferSlots)
    {
        char message[96];
        snprintf(message,
                 sizeof(message),
                 ore::kGuardVertexSlotRangeFormat,
                 ore::kMaxVertexBufferSlots - 1,
                 slot);
        vm->raiseModuleError(message);
        return;
    }
    pass->setVertexBuffer(slot, buffer->buffer.get(), offset);
}

void gpuPassSetIndexBufferImpl(WasmScriptingVM* vm,
                               uint32_t passHandle,
                               uint32_t bufferHandle,
                               uint32_t indexFormat,
                               uint32_t offset)
{
    auto* pass = resolvePass(vm, passHandle);
    auto buffer = static_cast<HostGpuBuffer*>(
        vm->handles().resolve(bufferHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuBuffer));
    if (pass == nullptr || buffer == nullptr)
    {
        return;
    }
    pass->setIndexBuffer(buffer->buffer.get(),
                         (ore::IndexFormat)indexFormat,
                         offset);
}

void gpuPassSetBindGroupImpl(WasmScriptingVM* vm,
                             uint32_t passHandle,
                             uint32_t groupIndex,
                             uint32_t bindGroupHandle,
                             const uint32_t* dynamicOffsets,
                             uint32_t dynamicOffsetByteCount)
{
    auto* pass = resolvePass(vm, passHandle);
    auto bindGroup = static_cast<HostGpuBindGroup*>(
        vm->handles().resolve(bindGroupHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuBindGroup));
    if (pass == nullptr || bindGroup == nullptr ||
        dynamicOffsetByteCount % sizeof(uint32_t) != 0)
    {
        return;
    }
    uint32_t count = dynamicOffsetByteCount / (uint32_t)sizeof(uint32_t);
    pass->setBindGroup(groupIndex,
                       bindGroup->bindGroup.get(),
                       count != 0 ? dynamicOffsets : nullptr,
                       count);
}

void gpuPassSetViewportImpl(WasmScriptingVM* vm,
                            uint32_t passHandle,
                            float x,
                            float y,
                            float width,
                            float height,
                            float minDepth,
                            float maxDepth)
{
    if (auto* pass = resolvePass(vm, passHandle))
    {
        pass->setViewport(x, y, width, height, minDepth, maxDepth);
    }
}

void gpuPassSetScissorImpl(WasmScriptingVM* vm,
                           uint32_t passHandle,
                           uint32_t x,
                           uint32_t y,
                           uint32_t width,
                           uint32_t height)
{
    if (auto* pass = resolvePass(vm, passHandle))
    {
        pass->setScissorRect(x, y, width, height);
    }
}

void gpuPassSetStencilReferenceImpl(WasmScriptingVM* vm,
                                    uint32_t passHandle,
                                    uint32_t ref)
{
    if (auto* pass = resolvePass(vm, passHandle))
    {
        pass->setStencilReference(ref);
    }
}

void gpuPassSetBlendColorImpl(WasmScriptingVM* vm,
                              uint32_t passHandle,
                              float r,
                              float g,
                              float b,
                              float a)
{
    if (auto* pass = resolvePass(vm, passHandle))
    {
        pass->setBlendColor(r, g, b, a);
    }
}

void gpuPassDrawImpl(WasmScriptingVM* vm,
                     uint32_t passHandle,
                     uint32_t vertexCount,
                     uint32_t instanceCount,
                     uint32_t firstVertex,
                     uint32_t firstInstance)
{
    auto* host = resolveHostPass(vm, passHandle);
    if (host == nullptr ||
        !gpuPassDrawAllowed(vm, host, "draw", 0, firstInstance))
    {
        return;
    }
    host->pass->draw(vertexCount, instanceCount, firstVertex, firstInstance);
}

void gpuPassDrawIndexedImpl(WasmScriptingVM* vm,
                            uint32_t passHandle,
                            uint32_t indexCount,
                            uint32_t instanceCount,
                            uint32_t firstIndex,
                            int32_t baseVertex,
                            uint32_t firstInstance)
{
    auto* host = resolveHostPass(vm, passHandle);
    if (host == nullptr ||
        !gpuPassDrawAllowed(vm, host, "drawIndexed", baseVertex, firstInstance))
    {
        return;
    }
    host->pass->drawIndexed(indexCount,
                            instanceCount,
                            firstIndex,
                            baseVertex,
                            firstInstance);
}

void gpuPassFinishImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    auto host = static_cast<HostGpuPass*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuPass));
    if (host == nullptr || host->pass == nullptr)
    {
        return;
    }
    if (!host->pass->isFinished())
    {
        host->pass->finish();
    }
}

void gpuPassReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuPass*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuPass));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::gpuPass);
}

uint32_t gpuBufferNewImpl(WasmScriptingVM* vm,
                          uint32_t usage,
                          uint32_t sizeInBytes,
                          uint32_t immutable,
                          const uint8_t* data,
                          uint32_t dataCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || sizeInBytes == 0 ||
        (dataCount != 0 && dataCount != sizeInBytes))
    {
        return 0;
    }
    ore::BufferDesc desc;
    desc.usage = (ore::BufferUsage)usage;
    desc.size = sizeInBytes;
    desc.immutable = immutable != 0;
    desc.data = dataCount != 0 ? data : nullptr;
    oreContext->clearLastError();
    auto buffer = oreContext->makeBuffer(desc);
    if (buffer == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUBuffer");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuBuffer,
                              new HostGpuBuffer{std::move(buffer)});
}

void gpuBufferUpdateImpl(WasmScriptingVM* vm,
                         uint32_t handle,
                         uint32_t dstOffset,
                         const uint8_t* data,
                         uint32_t dataCount)
{
    if (vm == nullptr)
    {
        return;
    }
    auto host = static_cast<HostGpuBuffer*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuBuffer));
    if (host == nullptr || dataCount == 0 ||
        uint64_t(dstOffset) + dataCount > host->buffer->size())
    {
        return;
    }
    host->buffer->update(data, dataCount, dstOffset);
}

void gpuBufferReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuBuffer*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuBuffer));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::gpuBuffer);
}

uint32_t gpuTextureNewImpl(WasmScriptingVM* vm,
                           const rive_gpu_texture_desc_v1* podDesc,
                           uint32_t descByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || descByteCount < sizeof(*podDesc))
    {
        return 0;
    }
    ore::TextureDesc desc;
    desc.width = podDesc->width;
    desc.height = podDesc->height;
    desc.depthOrArrayLayers = podDesc->depthOrArrayLayers;
    desc.format = (ore::TextureFormat)podDesc->format;
    desc.type = (ore::TextureType)podDesc->textureType;
    desc.renderTarget = podDesc->renderTarget != 0;
    desc.numMipmaps = podDesc->numMipmaps;
    desc.sampleCount = podDesc->sampleCount;
    oreContext->clearLastError();
    auto texture = oreContext->makeTexture(desc);
    if (texture == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUTexture");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuTexture,
                              new HostGpuTexture{std::move(texture)});
}

void gpuTextureUploadImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          const rive_gpu_texture_upload_v1* region,
                          uint32_t regionByteCount,
                          const uint8_t* data,
                          uint32_t dataCount)
{
    if (vm == nullptr || regionByteCount < sizeof(*region) || dataCount == 0)
    {
        return;
    }
    auto host = static_cast<HostGpuTexture*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuTexture));
    if (host == nullptr)
    {
        return;
    }
    ore::TextureDataDesc upload;
    upload.data = data;
    upload.dataSize = dataCount;
    upload.bytesPerRow = region->bytesPerRow;
    upload.rowsPerImage = region->rowsPerImage;
    upload.mipLevel = region->mipLevel;
    upload.layer = region->layer;
    upload.x = region->x;
    upload.y = region->y;
    upload.z = region->z;
    upload.width = region->width;
    upload.height = region->height;
    upload.depth = region->depth;
    std::string error;
    if (!host->texture->upload(upload, &error))
    {
        vm->raiseModuleError(error.c_str());
    }
}

void gpuTextureReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuTexture*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuTexture));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuTexture);
}

uint32_t gpuSamplerNewImpl(WasmScriptingVM* vm,
                           const rive_gpu_sampler_desc_v1* podDesc,
                           uint32_t descByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || descByteCount < sizeof(*podDesc))
    {
        return 0;
    }
    ore::SamplerDesc desc;
    desc.minFilter = (ore::Filter)podDesc->minFilter;
    desc.magFilter = (ore::Filter)podDesc->magFilter;
    desc.mipmapFilter = (ore::Filter)podDesc->mipmapFilter;
    desc.wrapU = (ore::WrapMode)podDesc->wrapU;
    desc.wrapV = (ore::WrapMode)podDesc->wrapV;
    desc.wrapW = (ore::WrapMode)podDesc->wrapW;
    // The guest sends ~0 for "no comparison sampler".
    desc.compare = podDesc->compare == 0xFFFFFFFFu
                       ? ore::CompareFunction::none
                       : (ore::CompareFunction)podDesc->compare;
    desc.minLod = podDesc->minLod;
    desc.maxLod = podDesc->maxLod;
    desc.maxAnisotropy = podDesc->maxAnisotropy;
    oreContext->clearLastError();
    auto sampler = oreContext->makeSampler(desc);
    if (sampler == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUSampler");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuSampler,
                              new HostGpuSampler{std::move(sampler)});
}

void gpuSamplerReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuSampler*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuSampler));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuSampler);
}

uint32_t gpuTextureViewNewImpl(WasmScriptingVM* vm,
                               uint32_t textureHandle,
                               const rive_gpu_texture_view_desc_v1* podDesc,
                               uint32_t descByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || descByteCount < sizeof(*podDesc))
    {
        return 0;
    }
    auto texture = static_cast<HostGpuTexture*>(
        vm->handles().resolve(textureHandle,
                              WasmScriptingVM::HandleTable::Tag::gpuTexture));
    if (texture == nullptr)
    {
        return 0;
    }
    ore::TextureViewDesc desc;
    desc.texture = texture->texture.get();
    desc.dimension = (ore::TextureViewDimension)podDesc->dimension;
    desc.aspect = (ore::TextureAspect)podDesc->aspect;
    desc.baseMipLevel = podDesc->baseMipLevel;
    desc.mipCount = podDesc->mipCount;
    desc.baseLayer = podDesc->baseLayer;
    desc.layerCount = podDesc->layerCount;
    oreContext->clearLastError();
    auto view = oreContext->makeTextureView(desc);
    if (view == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUTextureView");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuTextureView,
                              new HostGpuTextureView{std::move(view)});
}

void gpuTextureViewReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuTextureView*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::gpuTextureView));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuTextureView);
}

uint32_t gpuShaderTargetImpl(WasmScriptingVM* vm)
{
    ore::Context* oreContext = gpuOreContext(vm);
    return oreContext != nullptr ? (uint32_t)oreContext->shaderTarget()
                                 : (uint32_t)ore::ShaderTarget::wgsl;
}

uint32_t gpuShaderAssetBytesImpl(WasmScriptingVM* vm,
                                 uint32_t objectHandle,
                                 const char* name,
                                 uint32_t nameLength,
                                 uint8_t* out,
                                 uint32_t outCount)
{
    if (vm == nullptr)
    {
        return 0;
    }
#ifdef WITH_RIVE_TOOLS
    // Editor path first, matching the Luau lane: RSTBs compiled during
    // requestWasmVM shadow whatever a file asset carries.
    {
        const std::vector<uint8_t>* rstb =
            vm->findShaderRstb(std::string(name, nameLength));
        if (rstb != nullptr)
        {
            if (rstb->size() <= outCount)
            {
                memcpy(out, rstb->data(), rstb->size());
            }
            return (uint32_t)rstb->size();
        }
    }
#endif
    auto asset = findFileAsset<ShaderAsset>(vm, objectHandle, name, nameLength);
    if (asset == nullptr)
    {
        return 0;
    }
    auto rstb = asset->rstb();
    if (rstb.size() <= outCount)
    {
        memcpy(out, rstb.data(), rstb.size());
    }
    return (uint32_t)rstb.size();
}

uint32_t gpuShaderAssetIdImpl(WasmScriptingVM* vm,
                              uint32_t objectHandle,
                              const char* name,
                              uint32_t nameLength)
{
    auto asset = findFileAsset<ShaderAsset>(vm, objectHandle, name, nameLength);
    return asset != nullptr ? asset->assetId() : 0;
}

uint32_t gpuShaderModuleNewImpl(WasmScriptingVM* vm,
                                const rive_gpu_shader_module_desc_v1* podDesc,
                                uint32_t descByteCount,
                                const uint8_t* blob,
                                uint32_t blobCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || descByteCount < sizeof(*podDesc))
    {
        return 0;
    }
    uint64_t total = uint64_t(podDesc->codeSize) + podDesc->hlslSourceSize +
                     podDesc->hlslEntryPointSize + podDesc->bindingMapSize +
                     podDesc->glFixupSize;
    if (total > blobCount)
    {
        return 0;
    }
    const uint8_t* cursor = blob;
    auto slice = [&cursor](uint32_t size) {
        const uint8_t* begin = cursor;
        cursor += size;
        return size != 0 ? begin : nullptr;
    };
    ore::ShaderModuleDesc desc;
    desc.code = slice(podDesc->codeSize);
    desc.codeSize = podDesc->codeSize;
    desc.language = (ore::ShaderLanguage)podDesc->language;
    desc.stage = (ore::ShaderStage)podDesc->stage;
    // hlslSource and entry point are null-terminated strings host side.
    std::string hlslSource;
    std::string hlslEntryPoint;
    if (const uint8_t* bytes = slice(podDesc->hlslSourceSize))
    {
        hlslSource.assign((const char*)bytes, podDesc->hlslSourceSize);
        desc.hlslSource = hlslSource.c_str();
        desc.hlslSourceSize = podDesc->hlslSourceSize;
    }
    if (const uint8_t* bytes = slice(podDesc->hlslEntryPointSize))
    {
        hlslEntryPoint.assign((const char*)bytes, podDesc->hlslEntryPointSize);
        desc.hlslEntryPoint = hlslEntryPoint.c_str();
    }
    desc.bindingMapBytes = slice(podDesc->bindingMapSize);
    desc.bindingMapSize = podDesc->bindingMapSize;
    desc.glFixupBytes = slice(podDesc->glFixupSize);
    desc.glFixupSize = podDesc->glFixupSize;
    desc.shaderAssetId = podDesc->shaderAssetId;
    // Texture-sampler pairs ride the desc so deferred replay rebuilds them;
    // resolved host side from the asset like the Luau lane, not the wire.
    std::vector<uint8_t> pairBytes;
    if (podDesc->shaderAssetId != 0 && vm->file() != nullptr)
    {
        for (const auto& asset : vm->file()->assets())
        {
            if (asset->is<ShaderAsset>() &&
                asset->assetId() == podDesc->shaderAssetId)
            {
                auto pairs = asset->as<ShaderAsset>()->textureSamplerPairs();
                pairBytes.reserve(pairs.size() * 4);
                for (size_t i = 0; i < pairs.size(); i++)
                {
                    pairBytes.push_back(pairs[i].texGroup);
                    pairBytes.push_back(pairs[i].texBinding);
                    pairBytes.push_back(pairs[i].sampGroup);
                    pairBytes.push_back(pairs[i].sampBinding);
                }
                break;
            }
        }
    }
    desc.texSamplerPairBytes = pairBytes.empty() ? nullptr : pairBytes.data();
    desc.texSamplerPairSize = (uint32_t)pairBytes.size();
    oreContext->clearLastError();
    auto shaderModule = oreContext->makeShaderModule(desc);
    if (shaderModule == nullptr)
    {
        return gpuRejected(vm, oreContext, "Shader");
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::gpuShaderModule,
        new HostGpuShaderModule{std::move(shaderModule)});
}

void gpuShaderModuleReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuShaderModule*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::gpuShaderModule));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuShaderModule);
}

uint32_t gpuBindGroupLayoutNewImpl(
    WasmScriptingVM* vm,
    uint32_t groupIndex,
    const rive_gpu_bind_group_layout_entry_v1* entries,
    uint32_t entryByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || entryByteCount % sizeof(*entries) != 0)
    {
        return 0;
    }
    uint32_t count = entryByteCount / (uint32_t)sizeof(*entries);
    std::vector<ore::BindGroupLayoutEntry> resolved(count);
    for (uint32_t i = 0; i < count; i++)
    {
        auto& out = resolved[i];
        const auto& in = entries[i];
        out.binding = in.binding;
        out.kind = (ore::BindingKind)in.kind;
        out.visibility.mask = (uint8_t)in.visibility;
        out.hasDynamicOffset = in.hasDynamicOffset != 0;
        out.textureViewDim = (ore::TextureViewDimension)in.textureViewDim;
        out.textureSampleType =
            (ore::BindGroupLayoutEntry::SampleType)in.textureSampleType;
        out.textureMultisampled = in.textureMultisampled != 0;
        out.minBindingSize = in.minBindingSize;
        out.nativeSlotVS = in.nativeSlotVS;
        out.nativeSlotFS = in.nativeSlotFS;
        out.nativeSlotCS = in.nativeSlotCS;
        out.samplerNonFiltering = in.samplerNonFiltering != 0;
    }
    ore::BindGroupLayoutDesc desc;
    desc.groupIndex = groupIndex;
    desc.entries = resolved.data();
    desc.entryCount = count;
    oreContext->clearLastError();
    auto layout = oreContext->makeBindGroupLayout(desc);
    if (layout == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUBindGroupLayout");
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout,
        new HostGpuBindGroupLayout{std::move(layout)});
}

void gpuBindGroupLayoutReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuBindGroupLayout*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout));
    vm->handles().release(
        handle,
        WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout);
}

uint32_t gpuBindGroupLayoutFromShaderImpl(WasmScriptingVM* vm,
                                          uint32_t shaderModule,
                                          uint32_t groupIndex,
                                          const uint32_t* dynamicUBOs,
                                          uint32_t dynamicUBOCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostGpuShaderModule*>(vm->handles().resolve(
        shaderModule,
        WasmScriptingVM::HandleTable::Tag::gpuShaderModule));
    if (host == nullptr)
    {
        return 0;
    }
    auto layout = ore::makeBindGroupLayoutFromShader(*oreContext,
                                                     host->shaderModule.get(),
                                                     groupIndex,
                                                     dynamicUBOs,
                                                     dynamicUBOCount);
    if (layout == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout,
        new HostGpuBindGroupLayout{std::move(layout)});
}

uint32_t gpuBindGroupNewImpl(WasmScriptingVM* vm,
                             uint32_t layoutHandle,
                             const rive_gpu_bind_group_ubo_v1* ubos,
                             uint32_t uboByteCount,
                             const rive_gpu_bind_group_texture_v1* textures,
                             uint32_t textureByteCount,
                             const rive_gpu_bind_group_sampler_v1* samplers,
                             uint32_t samplerByteCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || uboByteCount % sizeof(*ubos) != 0 ||
        textureByteCount % sizeof(*textures) != 0 ||
        samplerByteCount % sizeof(*samplers) != 0)
    {
        return 0;
    }
    auto layout = static_cast<HostGpuBindGroupLayout*>(vm->handles().resolve(
        layoutHandle,
        WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout));
    if (layout == nullptr)
    {
        return 0;
    }
    ore::BindGroupDesc desc;
    desc.layout = layout->layout.get();

    uint32_t uboCount = uboByteCount / (uint32_t)sizeof(*ubos);
    std::vector<ore::BindGroupDesc::UBOEntry> uboEntries(uboCount);
    for (uint32_t i = 0; i < uboCount; i++)
    {
        auto buffer = static_cast<HostGpuBuffer*>(vm->handles().resolve(
            ubos[i].buffer,
            WasmScriptingVM::HandleTable::Tag::gpuBuffer));
        if (buffer == nullptr)
        {
            return 0;
        }
        uboEntries[i].slot = ubos[i].slot;
        uboEntries[i].buffer = buffer->buffer.get();
        uboEntries[i].offset = ubos[i].offset;
        uboEntries[i].size = ubos[i].size;
    }
    desc.ubos = uboEntries.data();
    desc.uboCount = uboCount;

    uint32_t texCount = textureByteCount / (uint32_t)sizeof(*textures);
    std::vector<ore::BindGroupDesc::TexEntry> texEntries(texCount);
    for (uint32_t i = 0; i < texCount; i++)
    {
        auto view = static_cast<HostGpuTextureView*>(vm->handles().resolve(
            textures[i].view,
            WasmScriptingVM::HandleTable::Tag::gpuTextureView));
        if (view == nullptr)
        {
            return 0;
        }
        texEntries[i].slot = textures[i].slot;
        texEntries[i].view = view->view.get();
    }
    desc.textures = texEntries.data();
    desc.textureCount = texCount;

    uint32_t sampCount = samplerByteCount / (uint32_t)sizeof(*samplers);
    std::vector<ore::BindGroupDesc::SampEntry> sampEntries(sampCount);
    for (uint32_t i = 0; i < sampCount; i++)
    {
        auto sampler = static_cast<HostGpuSampler*>(vm->handles().resolve(
            samplers[i].sampler,
            WasmScriptingVM::HandleTable::Tag::gpuSampler));
        if (sampler == nullptr)
        {
            return 0;
        }
        sampEntries[i].slot = samplers[i].slot;
        sampEntries[i].sampler = sampler->sampler.get();
    }
    desc.samplers = sampEntries.data();
    desc.samplerCount = sampCount;

    oreContext->clearLastError();
    auto bindGroup = oreContext->makeBindGroup(desc);
    if (bindGroup == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUBindGroup");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuBindGroup,
                              new HostGpuBindGroup{std::move(bindGroup)});
}

void gpuBindGroupReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuBindGroup*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuBindGroup));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuBindGroup);
}

uint32_t gpuPipelineNewImpl(WasmScriptingVM* vm,
                            const rive_gpu_pipeline_desc_v1* podDesc,
                            uint32_t descByteCount,
                            const uint8_t* blob,
                            uint32_t blobCount)
{
    ore::Context* oreContext = gpuOreContext(vm);
    if (oreContext == nullptr || descByteCount < sizeof(*podDesc))
    {
        return 0;
    }
    uint64_t total =
        uint64_t(podDesc->vertexEntrySize) + podDesc->fragmentEntrySize +
        uint64_t(podDesc->colorCount) * sizeof(rive_gpu_color_target_v1) +
        uint64_t(podDesc->vertexBufferCount) *
            sizeof(rive_gpu_vertex_buffer_layout_v1) +
        uint64_t(podDesc->attributeCount) *
            sizeof(rive_gpu_vertex_attribute_v1) +
        uint64_t(podDesc->bindGroupLayoutCount) * sizeof(uint32_t);
    if (total > blobCount || podDesc->colorCount > 4 ||
        podDesc->bindGroupLayoutCount > ore::kMaxBindGroups)
    {
        return 0;
    }
    const uint8_t* cursor = blob;
    auto slice = [&cursor](uint32_t size) {
        const uint8_t* begin = cursor;
        cursor += size;
        return size != 0 ? begin : nullptr;
    };

    ore::PipelineDesc desc;
    auto vertexModule = static_cast<HostGpuShaderModule*>(vm->handles().resolve(
        podDesc->vertexModule,
        WasmScriptingVM::HandleTable::Tag::gpuShaderModule));
    auto fragmentModule =
        static_cast<HostGpuShaderModule*>(vm->handles().resolve(
            podDesc->fragmentModule,
            WasmScriptingVM::HandleTable::Tag::gpuShaderModule));
    desc.vertexModule =
        vertexModule != nullptr ? vertexModule->shaderModule.get() : nullptr;
    desc.fragmentModule = fragmentModule != nullptr
                              ? fragmentModule->shaderModule.get()
                              : nullptr;

    std::string vertexEntry;
    std::string fragmentEntry;
    if (const uint8_t* bytes = slice(podDesc->vertexEntrySize))
    {
        vertexEntry.assign((const char*)bytes, podDesc->vertexEntrySize);
        desc.vertexEntryPoint = vertexEntry.c_str();
    }
    if (const uint8_t* bytes = slice(podDesc->fragmentEntrySize))
    {
        fragmentEntry.assign((const char*)bytes, podDesc->fragmentEntrySize);
        desc.fragmentEntryPoint = fragmentEntry.c_str();
    }

    auto colorTargets = (const rive_gpu_color_target_v1*)slice(
        podDesc->colorCount * (uint32_t)sizeof(rive_gpu_color_target_v1));
    desc.colorCount = podDesc->colorCount;
    for (uint32_t i = 0; i < podDesc->colorCount; i++)
    {
        auto& out = desc.colorTargets[i];
        out.format = (ore::TextureFormat)colorTargets[i].format;
        out.blendEnabled = colorTargets[i].blendEnabled != 0;
        out.blend.srcColor = (ore::BlendFactor)colorTargets[i].srcColor;
        out.blend.dstColor = (ore::BlendFactor)colorTargets[i].dstColor;
        out.blend.colorOp = (ore::BlendOp)colorTargets[i].colorOp;
        out.blend.srcAlpha = (ore::BlendFactor)colorTargets[i].srcAlpha;
        out.blend.dstAlpha = (ore::BlendFactor)colorTargets[i].dstAlpha;
        out.blend.alphaOp = (ore::BlendOp)colorTargets[i].alphaOp;
        out.writeMask = (ore::ColorWriteMask)colorTargets[i].writeMask;
    }

    auto bufferPods = (const rive_gpu_vertex_buffer_layout_v1*)slice(
        podDesc->vertexBufferCount *
        (uint32_t)sizeof(rive_gpu_vertex_buffer_layout_v1));
    auto attributePods = (const rive_gpu_vertex_attribute_v1*)slice(
        podDesc->attributeCount *
        (uint32_t)sizeof(rive_gpu_vertex_attribute_v1));
    std::vector<ore::VertexAttribute> attributes(podDesc->attributeCount);
    for (uint32_t i = 0; i < podDesc->attributeCount; i++)
    {
        attributes[i].format = (ore::VertexFormat)attributePods[i].format;
        attributes[i].offset = attributePods[i].offset;
        attributes[i].shaderSlot = attributePods[i].shaderSlot;
    }
    std::vector<ore::VertexBufferLayout> buffers(podDesc->vertexBufferCount);
    uint32_t attributeCursor = 0;
    for (uint32_t i = 0; i < podDesc->vertexBufferCount; i++)
    {
        uint32_t count = bufferPods[i].attributeCount;
        if (uint64_t(attributeCursor) + count > podDesc->attributeCount)
        {
            return 0;
        }
        buffers[i].stride = bufferPods[i].stride;
        buffers[i].stepMode = (ore::VertexStepMode)bufferPods[i].stepMode;
        buffers[i].attributes = attributes.data() + attributeCursor;
        buffers[i].attributeCount = count;
        attributeCursor += count;
    }
    desc.vertexBuffers = buffers.data();
    desc.vertexBufferCount = podDesc->vertexBufferCount;

    auto layoutHandles = (const uint32_t*)slice(podDesc->bindGroupLayoutCount *
                                                (uint32_t)sizeof(uint32_t));
    ore::BindGroupLayout* layouts[ore::kMaxBindGroups] = {};
    for (uint32_t i = 0; i < podDesc->bindGroupLayoutCount; i++)
    {
        if (layoutHandles[i] == 0)
        {
            continue;
        }
        auto layout =
            static_cast<HostGpuBindGroupLayout*>(vm->handles().resolve(
                layoutHandles[i],
                WasmScriptingVM::HandleTable::Tag::gpuBindGroupLayout));
        if (layout == nullptr)
        {
            return 0;
        }
        layouts[i] = layout->layout.get();
    }
    desc.bindGroupLayouts = layouts;
    desc.bindGroupLayoutCount = podDesc->bindGroupLayoutCount;

    desc.topology = (ore::PrimitiveTopology)podDesc->topology;
    desc.indexFormat = (ore::IndexFormat)podDesc->indexFormat;
    desc.cullMode = (ore::CullMode)podDesc->cullMode;
    desc.winding = (ore::FaceWinding)podDesc->winding;
    desc.depthStencil.format = (ore::TextureFormat)podDesc->depthFormat;
    desc.depthStencil.depthCompare =
        (ore::CompareFunction)podDesc->depthCompare;
    desc.depthStencil.depthWriteEnabled = podDesc->depthWriteEnabled != 0;
    desc.depthStencil.depthBias = (int32_t)podDesc->depthBias;
    desc.depthStencil.depthBiasSlopeScale = podDesc->depthBiasSlopeScale;
    desc.depthStencil.depthBiasClamp = podDesc->depthBiasClamp;
    desc.stencilFront.compare =
        (ore::CompareFunction)podDesc->stencilFrontCompare;
    desc.stencilFront.failOp = (ore::StencilOp)podDesc->stencilFrontFailOp;
    desc.stencilFront.depthFailOp =
        (ore::StencilOp)podDesc->stencilFrontDepthFailOp;
    desc.stencilFront.passOp = (ore::StencilOp)podDesc->stencilFrontPassOp;
    desc.stencilBack.compare =
        (ore::CompareFunction)podDesc->stencilBackCompare;
    desc.stencilBack.failOp = (ore::StencilOp)podDesc->stencilBackFailOp;
    desc.stencilBack.depthFailOp =
        (ore::StencilOp)podDesc->stencilBackDepthFailOp;
    desc.stencilBack.passOp = (ore::StencilOp)podDesc->stencilBackPassOp;
    desc.stencilReadMask = (uint8_t)podDesc->stencilReadMask;
    desc.stencilWriteMask = (uint8_t)podDesc->stencilWriteMask;
    desc.sampleCount = podDesc->sampleCount;

    oreContext->clearLastError();
    auto pipeline = oreContext->makePipeline(desc);
    if (pipeline == nullptr)
    {
        return gpuRejected(vm, oreContext, "GPUPipeline");
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::gpuPipeline,
                              new HostGpuPipeline{std::move(pipeline)});
}

void gpuPipelineReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostGpuPipeline*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::gpuPipeline));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::gpuPipeline);
}
#else
// Builds without the canvas renderer keep the namespace linkable; scripts
// see the same nil/no-op surface the Luau backend presents there.
uint32_t gpuCanvasNewImpl(WasmScriptingVM*, uint32_t, uint32_t) { return 0; }
void gpuCanvasReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuCanvasColorViewImpl(WasmScriptingVM*, uint32_t, uint32_t*, uint32_t)
{
    return 0;
}
uint32_t gpuCanvasImageImpl(WasmScriptingVM*, uint32_t) { return 0; }
uint32_t gpuCanvasResizeImpl(WasmScriptingVM*,
                             uint32_t,
                             uint32_t,
                             uint32_t,
                             uint32_t*,
                             uint32_t)
{
    return 0;
}
uint32_t gpuFeaturesImpl(WasmScriptingVM*, uint32_t*, uint32_t) { return 0; }
uint32_t gpuPassBeginImpl(WasmScriptingVM*,
                          const rive_gpu_pass_desc_v1*,
                          uint32_t,
                          const rive_gpu_pass_color_attachment_v1*,
                          uint32_t)
{
    return 0;
}
void gpuPassSetPipelineImpl(WasmScriptingVM*, uint32_t, uint32_t) {}
void gpuPassSetVertexBufferImpl(WasmScriptingVM*,
                                uint32_t,
                                uint32_t,
                                uint32_t,
                                uint32_t)
{}
void gpuPassSetIndexBufferImpl(WasmScriptingVM*,
                               uint32_t,
                               uint32_t,
                               uint32_t,
                               uint32_t)
{}
void gpuPassSetBindGroupImpl(WasmScriptingVM*,
                             uint32_t,
                             uint32_t,
                             uint32_t,
                             const uint32_t*,
                             uint32_t)
{}
void gpuPassSetViewportImpl(WasmScriptingVM*,
                            uint32_t,
                            float,
                            float,
                            float,
                            float,
                            float,
                            float)
{}
void gpuPassSetScissorImpl(WasmScriptingVM*,
                           uint32_t,
                           uint32_t,
                           uint32_t,
                           uint32_t,
                           uint32_t)
{}
void gpuPassSetStencilReferenceImpl(WasmScriptingVM*, uint32_t, uint32_t) {}
void gpuPassSetBlendColorImpl(WasmScriptingVM*,
                              uint32_t,
                              float,
                              float,
                              float,
                              float)
{}
void gpuPassDrawImpl(WasmScriptingVM*,
                     uint32_t,
                     uint32_t,
                     uint32_t,
                     uint32_t,
                     uint32_t)
{}
void gpuPassDrawIndexedImpl(WasmScriptingVM*,
                            uint32_t,
                            uint32_t,
                            uint32_t,
                            uint32_t,
                            int32_t,
                            uint32_t)
{}
void gpuPassFinishImpl(WasmScriptingVM*, uint32_t) {}
void gpuPassReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuImageViewImpl(WasmScriptingVM*, uint32_t, uint32_t, uint32_t)
{
    return 0;
}
uint32_t gpuBufferNewImpl(WasmScriptingVM*,
                          uint32_t,
                          uint32_t,
                          uint32_t,
                          const uint8_t*,
                          uint32_t)
{
    return 0;
}
void gpuBufferUpdateImpl(WasmScriptingVM*,
                         uint32_t,
                         uint32_t,
                         const uint8_t*,
                         uint32_t)
{}
void gpuBufferReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuTextureNewImpl(WasmScriptingVM*,
                           const rive_gpu_texture_desc_v1*,
                           uint32_t)
{
    return 0;
}
void gpuTextureUploadImpl(WasmScriptingVM*,
                          uint32_t,
                          const rive_gpu_texture_upload_v1*,
                          uint32_t,
                          const uint8_t*,
                          uint32_t)
{}
void gpuTextureReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuSamplerNewImpl(WasmScriptingVM*,
                           const rive_gpu_sampler_desc_v1*,
                           uint32_t)
{
    return 0;
}
void gpuSamplerReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuTextureViewNewImpl(WasmScriptingVM*,
                               uint32_t,
                               const rive_gpu_texture_view_desc_v1*,
                               uint32_t)
{
    return 0;
}
void gpuTextureViewReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuShaderTargetImpl(WasmScriptingVM*) { return 0; }
uint32_t gpuShaderAssetBytesImpl(WasmScriptingVM*,
                                 uint32_t,
                                 const char*,
                                 uint32_t,
                                 uint8_t*,
                                 uint32_t)
{
    return 0;
}
uint32_t gpuShaderAssetIdImpl(WasmScriptingVM*, uint32_t, const char*, uint32_t)
{
    return 0;
}
uint32_t gpuShaderModuleNewImpl(WasmScriptingVM*,
                                const rive_gpu_shader_module_desc_v1*,
                                uint32_t,
                                const uint8_t*,
                                uint32_t)
{
    return 0;
}
void gpuShaderModuleReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuBindGroupLayoutNewImpl(WasmScriptingVM*,
                                   uint32_t,
                                   const rive_gpu_bind_group_layout_entry_v1*,
                                   uint32_t)
{
    return 0;
}
void gpuBindGroupLayoutReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuBindGroupLayoutFromShaderImpl(WasmScriptingVM*,
                                          uint32_t,
                                          uint32_t,
                                          const uint32_t*,
                                          uint32_t)
{
    return 0;
}
uint32_t gpuBindGroupNewImpl(WasmScriptingVM*,
                             uint32_t,
                             const rive_gpu_bind_group_ubo_v1*,
                             uint32_t,
                             const rive_gpu_bind_group_texture_v1*,
                             uint32_t,
                             const rive_gpu_bind_group_sampler_v1*,
                             uint32_t)
{
    return 0;
}
void gpuBindGroupReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t gpuPipelineNewImpl(WasmScriptingVM*,
                            const rive_gpu_pipeline_desc_v1*,
                            uint32_t,
                            const uint8_t*,
                            uint32_t)
{
    return 0;
}
void gpuPipelineReleaseImpl(WasmScriptingVM*, uint32_t) {}
#endif

#ifdef RIVE_CANVAS
// Frames go through the deferred canvas host, the only path that can open
// inside the screen frame already open around the draw.
struct HostCanvas
{
    rcp<gpu::RenderCanvas> canvas;
    // A size requested before the device bound, allocated on first use.
    uint32_t pendingWidth = 0;
    uint32_t pendingHeight = 0;
    cmd::DeferredCanvasHost* frameHost = nullptr;
    uint32_t rendererHandle = 0;
};

HostCanvas* resolveCanvas(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostCanvas*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::canvas));
}

// Allocates a pending size once a device is there to allocate against.
// False only when a device is present and refuses.
bool canvasSatisfyPending(WasmScriptingVM* vm, HostCanvas* host)
{
    if (host->pendingWidth == 0 || host->pendingHeight == 0)
    {
        return true;
    }
    auto* renderContext =
        static_cast<gpu::RenderContext*>(vm->factory()->renderContext());
    if (renderContext == nullptr)
    {
        return true;
    }
    // A refused size leaves the previous backing in place.
    auto* deferredHost = vm->factory()->deferredCanvasHost();
    rcp<gpu::RenderCanvas> canvas =
        deferredHost != nullptr
            ? deferredHost->makeContentCanvas(host->pendingWidth,
                                              host->pendingHeight)
            : renderContext->makeRenderCanvas(host->pendingWidth,
                                              host->pendingHeight);
    host->pendingWidth = 0;
    host->pendingHeight = 0;
    if (canvas == nullptr)
    {
        return false;
    }
    host->canvas = std::move(canvas);
    return true;
}

uint32_t canvasNewImpl(WasmScriptingVM* vm, uint32_t width, uint32_t height)
{
    if (vm == nullptr || vm->factory() == nullptr)
    {
        return 0;
    }
    auto* host = new HostCanvas();
    if (width != 0 && height != 0)
    {
        host->pendingWidth = width;
        host->pendingHeight = height;
        // A size only waits when a recording host will bind a device later.
        if (!canvasSatisfyPending(vm, host) ||
            (host->canvas == nullptr &&
             vm->factory()->deferredCanvasHost() == nullptr))
        {
            delete host;
            return 0;
        }
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::canvas, host);
}

void canvasReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    canvasEndFrameImpl(vm, handle);
    delete host;
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::canvas);
}

uint32_t canvasWidthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    canvasSatisfyPending(vm, host);
    return host->canvas != nullptr ? host->canvas->width() : host->pendingWidth;
}

uint32_t canvasHeightImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    canvasSatisfyPending(vm, host);
    return host->canvas != nullptr ? host->canvas->height()
                                   : host->pendingHeight;
}

uint32_t canvasResizeImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          uint32_t width,
                          uint32_t height)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr || host->frameHost != nullptr)
    {
        return 0;
    }
    if (width == 0 || height == 0)
    {
        host->canvas = nullptr;
        host->pendingWidth = 0;
        host->pendingHeight = 0;
        return 1;
    }
    // An unchanged size would churn a new texture per frame.
    if (host->canvas != nullptr && host->canvas->width() == width &&
        host->canvas->height() == height)
    {
        return 1;
    }
    host->pendingWidth = width;
    host->pendingHeight = height;
    return canvasSatisfyPending(vm, host) ? 1 : 0;
}

uint32_t canvasImageImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    canvasSatisfyPending(vm, host);
    if (host->canvas == nullptr || host->canvas->renderImage() == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::image,
                              new HostImage{ref_rcp(static_cast<RenderImage*>(
                                                host->canvas->renderImage())),
                                            host->canvas});
}

uint32_t canvasBeginFrameImpl(WasmScriptingVM* vm,
                              uint32_t handle,
                              uint32_t clearColor)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr || host->frameHost != nullptr)
    {
        return 0;
    }
    canvasSatisfyPending(vm, host);
    cmd::DeferredCanvasHost* frameHost = vm->factory()->deferredCanvasHost();
    if (host->canvas == nullptr || frameHost == nullptr)
    {
        return 0;
    }
    Renderer* renderer =
        frameHost->beginCanvasContent(host->canvas.get(), clearColor);
    if (renderer == nullptr)
    {
        return 0;
    }
    host->frameHost = frameHost;
    host->rendererHandle =
        vm->handles().mint(WasmScriptingVM::HandleTable::Tag::renderer,
                           renderer);
    vm->registerOpenCanvasFrame(handle);
    return host->rendererHandle;
}

void canvasEndFrameImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto* host = resolveCanvas(vm, handle);
    if (host == nullptr || host->frameHost == nullptr)
    {
        return;
    }
    vm->unregisterOpenCanvasFrame(handle);
    // Releasing bumps the generation so a stashed renderer goes stale.
    vm->handles().release(host->rendererHandle,
                          WasmScriptingVM::HandleTable::Tag::renderer);
    host->rendererHandle = 0;
    host->frameHost->endCanvasContent(host->canvas.get());
    host->frameHost = nullptr;
}
#else
uint32_t canvasNewImpl(WasmScriptingVM*, uint32_t, uint32_t) { return 0; }
void canvasReleaseImpl(WasmScriptingVM*, uint32_t) {}
uint32_t canvasWidthImpl(WasmScriptingVM*, uint32_t) { return 0; }
uint32_t canvasHeightImpl(WasmScriptingVM*, uint32_t) { return 0; }
uint32_t canvasResizeImpl(WasmScriptingVM*, uint32_t, uint32_t, uint32_t)
{
    return 0;
}
uint32_t canvasImageImpl(WasmScriptingVM*, uint32_t) { return 0; }
uint32_t canvasBeginFrameImpl(WasmScriptingVM*, uint32_t, uint32_t)
{
    return 0;
}
void canvasEndFrameImpl(WasmScriptingVM*, uint32_t) {}
#endif

struct HostBuffer
{
    rcp<RenderBuffer> buffer;
};

HostBuffer* resolveBuffer(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostBuffer*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::buffer));
}

uint32_t bufferNewImpl(WasmScriptingVM* vm,
                       uint32_t bufferType,
                       uint32_t flags,
                       uint32_t sizeInBytes)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto buffer = vm->factory()->makeRenderBuffer((RenderBufferType)bufferType,
                                                  (RenderBufferFlags)flags,
                                                  sizeInBytes);
    if (buffer == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::buffer,
                              new HostBuffer{std::move(buffer)});
}

void bufferUpdateImpl(WasmScriptingVM* vm,
                      uint32_t handle,
                      const uint8_t* bytes,
                      uint32_t byteCount)
{
    auto host = resolveBuffer(vm, handle);
    if (host == nullptr || byteCount != host->buffer->sizeInBytes())
    {
        return;
    }
    void* data = host->buffer->map();
    if (data != nullptr)
    {
        memcpy(data, bytes, byteCount);
        host->buffer->unmap();
    }
}

void bufferReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostBuffer*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::buffer));
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::buffer);
}

struct HostMeshInstances
{
    rcp<ImageMeshInstances> instances;
};

HostMeshInstances* resolveMeshInstances(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostMeshInstances*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::meshInstances));
}

uint32_t meshInstancesNewImpl(WasmScriptingVM* vm, uint32_t count)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto instances = vm->factory()->makeImageMeshInstances(count);
    if (instances == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::meshInstances,
                              new HostMeshInstances{std::move(instances)});
}

void meshInstancesResizeImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             uint32_t count)
{
    auto host = resolveMeshInstances(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    host->instances->edit(count);
    host->instances->endEdit();
}

void meshInstancesUpdateImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             uint32_t first,
                             const uint8_t* bytes,
                             uint32_t byteCount)
{
    auto host = resolveMeshInstances(vm, handle);
    if (host == nullptr || byteCount % sizeof(ImageMeshInstanceData) != 0)
    {
        return;
    }
    size_t count = byteCount / sizeof(ImageMeshInstanceData);
    Span<ImageMeshInstanceData> data = host->instances->edit();
    if (first <= data.size() && count <= data.size() - first)
    {
        memcpy(data.data() + first, bytes, byteCount);
    }
    host->instances->endEdit();
}

void meshInstancesReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostMeshInstances*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::meshInstances));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::meshInstances);
}

Renderer* resolveRenderer(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<Renderer*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::renderer));
}

void rendererSaveImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (auto renderer = resolveRenderer(vm, handle))
    {
        renderer->save();
        auto& saves = vm->visitSaves();
        saves.open += renderer == saves.renderer ? 1 : 0;
    }
}
void rendererRestoreImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (auto renderer = resolveRenderer(vm, handle))
    {
        renderer->restore();
        auto& saves = vm->visitSaves();
        saves.open -= renderer == saves.renderer ? 1 : 0;
    }
}
void rendererTransformImpl(WasmScriptingVM* vm,
                           uint32_t handle,
                           float xx,
                           float xy,
                           float yx,
                           float yy,
                           float tx,
                           float ty)
{
    if (auto renderer = resolveRenderer(vm, handle))
    {
        renderer->transform(Mat2D(xx, xy, yx, yy, tx, ty));
    }
}
void rendererDrawPathImpl(WasmScriptingVM* vm,
                          uint32_t rendererHandle,
                          uint32_t pathHandle,
                          uint32_t paintHandle)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    auto paint = resolvePaint(vm, paintHandle);
    if (vm == nullptr || renderer == nullptr || paint == nullptr)
    {
        return;
    }
    RenderPath* path = hostRenderPath(vm, resolvePath(vm, pathHandle));
    if (path == nullptr)
    {
        return;
    }
    renderer->drawPath(path, paint);
}
void rendererDrawImageImpl(WasmScriptingVM* vm,
                           uint32_t rendererHandle,
                           uint32_t imageHandle,
                           uint32_t samplerKey,
                           uint32_t blend,
                           float opacity)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    auto host = resolveImage(vm, imageHandle);
    if (renderer == nullptr || host == nullptr)
    {
        return;
    }
    renderer->drawImage(host->image.get(),
                        ImageSampler::SamplerFromKey((uint8_t)samplerKey),
                        (BlendMode)blend,
                        opacity);
}

void rendererDrawImageMeshImpl(WasmScriptingVM* vm,
                               uint32_t rendererHandle,
                               uint32_t imageHandle,
                               uint32_t samplerKey,
                               uint32_t vertexHandle,
                               uint32_t uvHandle,
                               uint32_t indexHandle,
                               uint32_t blend,
                               float opacity)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    auto image = resolveImage(vm, imageHandle);
    auto vertex = resolveBuffer(vm, vertexHandle);
    auto uv = resolveBuffer(vm, uvHandle);
    auto index = resolveBuffer(vm, indexHandle);
    if (renderer == nullptr || image == nullptr || vertex == nullptr ||
        uv == nullptr || index == nullptr)
    {
        return;
    }
    renderer->drawImageMesh(
        image->image.get(),
        ImageSampler::SamplerFromKey((uint8_t)samplerKey),
        vertex->buffer,
        uv->buffer,
        index->buffer,
        (uint32_t)(vertex->buffer->sizeInBytes() / sizeof(Vec2D)),
        (uint32_t)(index->buffer->sizeInBytes() / sizeof(uint16_t)),
        (BlendMode)blend,
        opacity);
}

void rendererDrawImageMeshInstancedImpl(WasmScriptingVM* vm,
                                        uint32_t rendererHandle,
                                        uint32_t imageHandle,
                                        uint32_t samplerKey,
                                        uint32_t vertexHandle,
                                        uint32_t uvHandle,
                                        uint32_t indexHandle,
                                        uint32_t instancesHandle)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    auto image = resolveImage(vm, imageHandle);
    auto vertex = resolveBuffer(vm, vertexHandle);
    auto uv = resolveBuffer(vm, uvHandle);
    auto index = resolveBuffer(vm, indexHandle);
    auto instances = resolveMeshInstances(vm, instancesHandle);
    if (renderer == nullptr || image == nullptr || vertex == nullptr ||
        uv == nullptr || index == nullptr || instances == nullptr)
    {
        return;
    }
    renderer->drawImageMeshInstanced(
        image->image.get(),
        ImageSampler::SamplerFromKey((uint8_t)samplerKey),
        vertex->buffer,
        uv->buffer,
        index->buffer,
        (uint32_t)(vertex->buffer->sizeInBytes() / sizeof(Vec2D)),
        (uint32_t)(index->buffer->sizeInBytes() / sizeof(uint16_t)),
        instances->instances);
}

void rendererClipPathImpl(WasmScriptingVM* vm,
                          uint32_t rendererHandle,
                          uint32_t pathHandle)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (vm == nullptr || renderer == nullptr)
    {
        return;
    }
    RenderPath* path = hostRenderPath(vm, resolvePath(vm, pathHandle));
    if (path == nullptr)
    {
        return;
    }
    renderer->clipPath(path);
}

void rendererModulateOpacityImpl(WasmScriptingVM* vm,
                                 uint32_t rendererHandle,
                                 float opacity)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (renderer != nullptr)
    {
        renderer->modulateOpacity(opacity);
    }
}

void rendererModulateColorImpl(WasmScriptingVM* vm,
                               uint32_t rendererHandle,
                               uint32_t color,
                               uint32_t replace)
{
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (renderer != nullptr)
    {
        renderer->modulateColor(color, replace != 0);
    }
}

void rtLogImpl(WasmScriptingVM* vm,
               int32_t level,
               const char* message,
               uint32_t length)
{
    WasmScriptingVMNatives::print(vm, message, length);
    WasmScriptingVMNatives::print(vm, "\n", 1);
}

void rtBudgetExceededImpl(WasmScriptingVM* vm, uint32_t ms)
{
    fprintf(stderr,
            "script error: execution exceeded %u millisecond timeout\n",
            ms);
    // Terminates like a trap when the native returns, so the caller's
    // failed-op handling engages.
    vm->raiseModuleError("execution exceeded timeout");
}

// Unfused multiply-add keeps these bit identical to the module's own f32
// math, on every tier and platform.
#pragma clang fp contract(off)
void mat4MultiplyImpl(WasmScriptingVM*,
                      uint8_t* outBytes,
                      uint32_t outByteCount,
                      const uint8_t* aBytes,
                      uint32_t aByteCount,
                      const uint8_t* bBytes,
                      uint32_t bByteCount)
{
    if (outByteCount < 64 || aByteCount < 64 || bByteCount < 64)
    {
        return;
    }
    float a[16];
    float b[16];
    memcpy(a, aBytes, sizeof(a));
    memcpy(b, bBytes, sizeof(b));
    float result[16];
    for (int col = 0; col < 4; col++)
    {
        for (int row = 0; row < 4; row++)
        {
            result[col * 4 + row] =
                a[row] * b[col * 4] + a[4 + row] * b[col * 4 + 1] +
                a[8 + row] * b[col * 4 + 2] + a[12 + row] * b[col * 4 + 3];
        }
    }
    memcpy(outBytes, result, sizeof(result));
}

uint32_t mat4InvertImpl(WasmScriptingVM*,
                        uint8_t* outBytes,
                        uint32_t outByteCount,
                        const uint8_t* srcBytes,
                        uint32_t srcByteCount)
{
    if (outByteCount < 64 || srcByteCount < 64)
    {
        return 0;
    }
    float m[16];
    memcpy(m, srcBytes, sizeof(m));
    float inv[16];
    inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
             m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
    inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] +
             m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] +
             m[12] * m[7] * m[10];
    inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] +
             m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
    inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] +
              m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] +
              m[12] * m[6] * m[9];
    inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] +
             m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] +
             m[13] * m[3] * m[10];
    inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] +
             m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
    inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] -
             m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
    inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] +
              m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
    inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] +
             m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
    inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] -
             m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
    inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] +
              m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
    inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] -
              m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
    inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] -
             m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
    inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] +
             m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
    inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] -
              m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
    inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] +
              m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
    float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
    if (det == 0)
    {
        return 0;
    }
    float detInv = 1.0f / det;
    for (int i = 0; i < 16; i++)
    {
        inv[i] *= detInv;
    }
    memcpy(outBytes, inv, sizeof(inv));
    return 1;
}
#pragma clang fp contract(on)

uint32_t rtUtcOffsetImpl(WasmScriptingVM* vm, double epochSeconds)
{
    time_t at;
    struct tm local;
    return localTime(epochSeconds, at, local) ? (uint32_t)utcOffsetOf(local, at)
                                              : 0;
}

uint32_t rtIsDstImpl(WasmScriptingVM* vm, double epochSeconds)
{
    time_t at;
    struct tm local;
    return localTime(epochSeconds, at, local) && local.tm_isdst > 0 ? 1 : 0;
}

uint32_t rtZoneNameImpl(WasmScriptingVM* vm,
                        double epochSeconds,
                        char* buffer,
                        uint32_t capacity)
{
    time_t at;
    struct tm local;
    if (!localTime(epochSeconds, at, local))
    {
        return 0;
    }
    char name[64];
    size_t length = strftime(name, sizeof(name), "%Z", &local);
    return fillModuleString(vm, std::string(name, length), buffer, capacity);
}

// Module start has no exec env to carry the vm; the probes its top level
// hits belong to the VM being booted.
static WasmDebugHooks* debugHooksFor(WasmScriptingVM*& vm)
{
    if (vm == nullptr)
    {
        vm = s_booting;
    }
    return vm != nullptr ? vm->debugHooks() : nullptr;
}

void rtDebugEnterImpl(WasmScriptingVM* vm, uint32_t function, uint32_t line)
{
    if (WasmDebugHooks* hooks = debugHooksFor(vm))
    {
        hooks->onEnter(*vm, function, line);
    }
}

uint32_t rtDebugLineImpl(WasmScriptingVM* vm, uint32_t line)
{
    WasmDebugHooks* hooks = debugHooksFor(vm);
    return hooks != nullptr && hooks->onLine(*vm, line) ? 1 : 0;
}

void rtDebugLeaveImpl(WasmScriptingVM* vm)
{
    if (WasmDebugHooks* hooks = debugHooksFor(vm))
    {
        hooks->onLeave(*vm);
    }
}

void rtMarkNeedsUpdateImpl(WasmScriptingVM* vm, uint32_t objectHandle)
{
    if (vm == nullptr)
    {
        return;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    if (object != nullptr)
    {
        object->markNeedsUpdate();
    }
}

// --- rive_data_v1: view model instances and their values, pinned per handle

struct HostViewModelInstance
{
    rcp<ViewModelInstance> instance;
};

// Forwards core value change notifications into the module's listener
// registry by token.
struct HostValueDelegate : public ViewModelInstanceValueDelegate
{
    WasmScriptingVM* vm = nullptr;
    uint32_t token = 0;
    void valueChanged() override { vm->notifyDataValueChanged(token); }
};

struct HostInstanceValue
{
    rcp<ViewModelInstanceValue> value;
    HostValueDelegate* delegate = nullptr;
    // What string_get last handed the module, for string_changed.
    std::string sent;
    bool hasSent = false;

    ~HostInstanceValue()
    {
        if (delegate != nullptr)
        {
            value->removeDelegate(delegate);
            delete delegate;
        }
    }
};

void dataConvertResultImpl(WasmScriptingVM* vm,
                           uint32_t kind,
                           float number,
                           uint32_t booleanValue,
                           uint32_t color,
                           const char* value,
                           uint32_t length)
{
    ScriptBackend::ScriptDataResult* out =
        vm != nullptr ? vm->convertResultOut() : nullptr;
    if (out == nullptr)
    {
        return;
    }
    switch (kind)
    {
        case DataConvertWire::kindNumber:
            out->kind = ScriptBackend::ScriptDataResult::Kind::number;
            out->number = number;
            break;
        case DataConvertWire::kindString:
            out->kind = ScriptBackend::ScriptDataResult::Kind::string;
            out->string.assign(value, length);
            break;
        case DataConvertWire::kindBoolean:
            out->kind = ScriptBackend::ScriptDataResult::Kind::boolean;
            out->boolean = booleanValue != 0;
            break;
        case DataConvertWire::kindColor:
            out->kind = ScriptBackend::ScriptDataResult::Kind::color;
            out->color = (int)color;
            break;
        default:
            break;
    }
}

uint32_t dataViewModelImpl(WasmScriptingVM* vm, uint32_t objectHandle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    auto instance = object != nullptr && object->dataContext() != nullptr
                        ? object->dataContext()->mainViewModelInstance()
                        : nullptr;
    if (instance == nullptr)
    {
        vm->noteMissingRequestedData();
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

void dataVmiReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostViewModelInstance*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::viewModelInstance);
}

template <typename T>
uint32_t mintInstanceValue(WasmScriptingVM* vm,
                           uint32_t vmiHandle,
                           const char* name,
                           uint32_t length)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    if (host == nullptr)
    {
        return 0;
    }
    auto value = host->instance->propertyValue(std::string(name, length));
    if (value == nullptr || !value->template is<T>())
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::instanceValue,
                              new HostInstanceValue{ref_rcp(value)});
}

ViewModel* findViewModel(WasmScriptingVM* vm, const char* name, uint32_t length)
{
    if (vm == nullptr || vm->viewModels() == nullptr)
    {
        return nullptr;
    }
    std::string key(name, length);
    for (ViewModel* viewModel : *vm->viewModels())
    {
        if (viewModel != nullptr && viewModel->name() == key)
        {
            return viewModel;
        }
    }
    return nullptr;
}

uint32_t dataHasViewModelImpl(WasmScriptingVM* vm,
                              const char* name,
                              uint32_t nameLength)
{
    return findViewModel(vm, name, nameLength) != nullptr ? 1 : 0;
}

uint32_t dataNewViewModelImpl(WasmScriptingVM* vm,
                              const char* name,
                              uint32_t nameLength,
                              const char* templateName,
                              uint32_t templateLength)
{
    ViewModel* viewModel = findViewModel(vm, name, nameLength);
    if (vm == nullptr || viewModel == nullptr)
    {
        return 0;
    }
    auto instance = templateLength != 0
                        ? viewModel->createFromInstance(
                              std::string(templateName, templateLength))
                        : viewModel->createInstance();
    if (instance == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

uint32_t dataVmiNumberImpl(WasmScriptingVM* vm,
                           uint32_t vmiHandle,
                           const char* name,
                           uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceNumber>(vm,
                                                      vmiHandle,
                                                      name,
                                                      length);
}

uint32_t dataVmiBooleanImpl(WasmScriptingVM* vm,
                            uint32_t vmiHandle,
                            const char* name,
                            uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceBoolean>(vm,
                                                       vmiHandle,
                                                       name,
                                                       length);
}

uint32_t dataVmiStringImpl(WasmScriptingVM* vm,
                           uint32_t vmiHandle,
                           const char* name,
                           uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceString>(vm,
                                                      vmiHandle,
                                                      name,
                                                      length);
}

uint32_t dataVmiTriggerImpl(WasmScriptingVM* vm,
                            uint32_t vmiHandle,
                            const char* name,
                            uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceTrigger>(vm,
                                                       vmiHandle,
                                                       name,
                                                       length);
}

uint32_t dataVmiColorImpl(WasmScriptingVM* vm,
                          uint32_t vmiHandle,
                          const char* name,
                          uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceColor>(vm,
                                                     vmiHandle,
                                                     name,
                                                     length);
}

uint32_t dataVmiViewModelImpl(WasmScriptingVM* vm,
                              uint32_t vmiHandle,
                              const char* name,
                              uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceViewModel>(vm,
                                                         vmiHandle,
                                                         name,
                                                         length);
}

void dataPropReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostInstanceValue*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::instanceValue));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::instanceValue);
}

template <typename T>
T* resolveInstanceValue(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    auto host = static_cast<HostInstanceValue*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::instanceValue));
    if (host == nullptr || !host->value->template is<T>())
    {
        return nullptr;
    }
    return host->value->template as<T>();
}

float dataNumberGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto number = resolveInstanceValue<ViewModelInstanceNumber>(vm, handle);
    return number != nullptr ? number->propertyValue() : 0.0f;
}

void dataNumberSetImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
    auto number = resolveInstanceValue<ViewModelInstanceNumber>(vm, handle);
    if (number != nullptr)
    {
        number->propertyValue(value);
    }
}

uint32_t dataBooleanGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto boolean = resolveInstanceValue<ViewModelInstanceBoolean>(vm, handle);
    return boolean != nullptr && boolean->propertyValue() ? 1 : 0;
}

void dataBooleanSetImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    auto boolean = resolveInstanceValue<ViewModelInstanceBoolean>(vm, handle);
    if (boolean != nullptr)
    {
        boolean->propertyValue(value != 0);
    }
}

uint32_t dataStringGetImpl(WasmScriptingVM* vm,
                           uint32_t handle,
                           char* buffer,
                           uint32_t capacity)
{
    auto string = resolveInstanceValue<ViewModelInstanceString>(vm, handle);
    if (string == nullptr)
    {
        return 0;
    }
    uint32_t length =
        fillModuleString(vm, string->propertyValue(), buffer, capacity);
    if (length <= capacity)
    {
        auto host = static_cast<HostInstanceValue*>(vm->handles().resolve(
            handle,
            WasmScriptingVM::HandleTable::Tag::instanceValue));
        host->sent = string->propertyValue();
        host->hasSent = true;
    }
    return length;
}

uint32_t dataStringChangedImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto string = resolveInstanceValue<ViewModelInstanceString>(vm, handle);
    if (string == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostInstanceValue*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::instanceValue));
    if (host->hasSent && host->sent == string->propertyValue())
    {
        return ~0u;
    }
    return (uint32_t)fillModuleString(vm, string->propertyValue(), nullptr, 0);
}

void dataStringSetImpl(WasmScriptingVM* vm,
                       uint32_t handle,
                       const char* value,
                       uint32_t length)
{
    auto string = resolveInstanceValue<ViewModelInstanceString>(vm, handle);
    if (string != nullptr)
    {
        string->propertyValue(std::string(value, length));
    }
}

void dataTriggerFireImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto trigger = resolveInstanceValue<ViewModelInstanceTrigger>(vm, handle);
    if (trigger != nullptr)
    {
        trigger->trigger();
    }
}

uint32_t dataColorGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto color = resolveInstanceValue<ViewModelInstanceColor>(vm, handle);
    return color != nullptr ? (uint32_t)color->propertyValue() : 0;
}

void dataColorSetImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t value)
{
    auto color = resolveInstanceValue<ViewModelInstanceColor>(vm, handle);
    if (color != nullptr)
    {
        color->propertyValue((int)value);
    }
}

uint32_t dataVmiEnumImpl(WasmScriptingVM* vm,
                         uint32_t vmiHandle,
                         const char* name,
                         uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceEnum>(vm,
                                                    vmiHandle,
                                                    name,
                                                    length);
}

uint32_t dataEnumGetImpl(WasmScriptingVM* vm,
                         uint32_t handle,
                         char* buffer,
                         uint32_t capacity)
{
    auto value = resolveInstanceValue<ViewModelInstanceEnum>(vm, handle);
    if (value == nullptr || value->viewModelProperty() == nullptr ||
        !value->viewModelProperty()->is<ViewModelPropertyEnum>())
    {
        return 0;
    }
    auto dataEnum =
        value->viewModelProperty()->as<ViewModelPropertyEnum>()->dataEnum();
    if (dataEnum == nullptr)
    {
        return 0;
    }
    auto values = dataEnum->values();
    uint32_t index = value->propertyValue();
    if (index >= values.size())
    {
        return 0;
    }
    return fillModuleString(vm, values[index]->key(), buffer, capacity);
}

void dataEnumSetImpl(WasmScriptingVM* vm,
                     uint32_t handle,
                     const char* value,
                     uint32_t length)
{
    auto instanceValue =
        resolveInstanceValue<ViewModelInstanceEnum>(vm, handle);
    if (instanceValue != nullptr)
    {
        instanceValue->value(std::string(value, length));
    }
}

uint32_t dataVmiListImpl(WasmScriptingVM* vm,
                         uint32_t vmiHandle,
                         const char* name,
                         uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceList>(vm,
                                                    vmiHandle,
                                                    name,
                                                    length);
}

uint32_t dataListLengthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    return list != nullptr ? (uint32_t)list->listItems().size() : 0;
}

void dataListPushImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t vmiHandle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    if (vm == nullptr || list == nullptr)
    {
        return;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    if (host == nullptr)
    {
        return;
    }
    auto item = make_rcp<ViewModelInstanceListItem>();
    item->viewModelInstance(host->instance);
    list->addItem(std::move(item));
}

uint32_t mintRemovedItem(WasmScriptingVM* vm,
                         rcp<ViewModelInstanceListItem> item)
{
    if (vm == nullptr || item == nullptr ||
        item->viewModelInstance() == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{item->viewModelInstance()});
}

uint32_t dataListPopImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    return list != nullptr ? mintRemovedItem(vm, list->pop()) : 0;
}

uint32_t dataListShiftImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    return list != nullptr ? mintRemovedItem(vm, list->shift()) : 0;
}

void dataListClearImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    if (list != nullptr)
    {
        list->removeAllItems();
    }
}

void dataListSwapImpl(WasmScriptingVM* vm,
                      uint32_t handle,
                      uint32_t index1,
                      uint32_t index2)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    if (list != nullptr)
    {
        list->swap(index1, index2);
    }
}

rcp<ViewModelInstance> resolveVmiArg(WasmScriptingVM* vm, uint32_t vmiHandle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    return host != nullptr ? host->instance : nullptr;
}

void dataListInsertImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        uint32_t vmiHandle,
                        uint32_t index)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    auto instance = resolveVmiArg(vm, vmiHandle);
    if (list == nullptr || instance == nullptr)
    {
        return;
    }
    auto item = make_rcp<ViewModelInstanceListItem>();
    item->viewModelInstance(std::move(instance));
    list->addItemAt(std::move(item), (int)index);
}

void dataListRemoveImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        uint32_t vmiHandle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    auto instance = resolveVmiArg(vm, vmiHandle);
    if (list == nullptr || instance == nullptr)
    {
        return;
    }
    for (const auto& item : list->listItems())
    {
        if (item->viewModelInstance() == instance)
        {
            list->removeItem(item);
            break;
        }
    }
}

void dataListRemoveAtImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t index)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    if (list != nullptr)
    {
        list->removeItem((int)index);
    }
}

void dataViewModelSetImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          uint32_t vmiHandle)
{
    auto value = resolveInstanceValue<ViewModelInstanceViewModel>(vm, handle);
    auto instance = resolveVmiArg(vm, vmiHandle);
    if (value == nullptr || instance == nullptr ||
        value->parentViewModelInstance() == nullptr)
    {
        return;
    }
    value->parentViewModelInstance()->replaceViewModelByProperty(
        value,
        std::move(instance));
}

uint32_t dataViewModelGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto value = resolveInstanceValue<ViewModelInstanceViewModel>(vm, handle);
    if (vm == nullptr || value == nullptr)
    {
        return 0;
    }
    auto reference = value->referenceViewModelInstance();
    if (reference == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(reference)});
}

uint32_t dataVmiPropertyImpl(WasmScriptingVM* vm,
                             uint32_t vmiHandle,
                             const char* name,
                             uint32_t length,
                             uint32_t* kindOut,
                             uint32_t kindCount)
{
    if (kindCount > 0)
    {
        kindOut[0] = DataPropertyWire::kindNone;
    }
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    if (host == nullptr)
    {
        return 0;
    }
    auto value = host->instance->propertyValue(std::string(name, length));
    if (value == nullptr)
    {
        return 0;
    }
    uint32_t kind = DataPropertyWire::kindNone;
    switch (value->coreType())
    {
        case ViewModelInstanceNumberBase::typeKey:
            kind = DataPropertyWire::kindNumber;
            break;
        case ViewModelInstanceBooleanBase::typeKey:
            kind = DataPropertyWire::kindBoolean;
            break;
        case ViewModelInstanceStringBase::typeKey:
            kind = DataPropertyWire::kindString;
            break;
        case ViewModelInstanceTriggerBase::typeKey:
            kind = DataPropertyWire::kindTrigger;
            break;
        case ViewModelInstanceColorBase::typeKey:
            kind = DataPropertyWire::kindColor;
            break;
        case ViewModelInstanceViewModelBase::typeKey:
            kind = DataPropertyWire::kindViewModel;
            break;
        case ViewModelInstanceListBase::typeKey:
            kind = DataPropertyWire::kindList;
            break;
        case ViewModelInstanceEnumBase::typeKey:
            kind = DataPropertyWire::kindEnum;
            break;
        case ViewModelInstanceAssetImageBase::typeKey:
            kind = DataPropertyWire::kindImage;
            break;
        case ViewModelInstanceAssetFontBase::typeKey:
            kind = DataPropertyWire::kindFont;
            break;
        case ViewModelInstanceAssetBlobBase::typeKey:
            kind = DataPropertyWire::kindBlob;
            break;
        case ViewModelInstanceSymbolListIndexBase::typeKey:
            if (kindCount > 0)
            {
                kindOut[0] = DataPropertyWire::kindSymbolListIndex;
            }
            if (kindCount > 1)
            {
                kindOut[1] =
                    (uint32_t)value->as<ViewModelInstanceSymbolListIndex>()
                        ->propertyValue();
            }
            return 0;
        default:
            return 0;
    }
    if (kindCount > 0)
    {
        kindOut[0] = kind;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::instanceValue,
                              new HostInstanceValue{ref_rcp(value)});
}

uint32_t dataVmiInstanceImpl(WasmScriptingVM* vm,
                             uint32_t vmiHandle,
                             const char* name,
                             uint32_t nameLength)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    if (host == nullptr || host->instance->viewModel() == nullptr)
    {
        return 0;
    }
    ViewModel* viewModel = host->instance->viewModel();
    auto instance =
        nameLength != 0
            ? viewModel->createFromInstance(std::string(name, nameLength))
            : nullptr;
    if (instance == nullptr)
    {
        instance = viewModel->createInstance();
    }
    if (instance == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

uint32_t dataVmiSymbolIndexImpl(WasmScriptingVM* vm, uint32_t vmiHandle)
{
    if (vm == nullptr)
    {
        return ~0u;
    }
    auto host = static_cast<HostViewModelInstance*>(vm->handles().resolve(
        vmiHandle,
        WasmScriptingVM::HandleTable::Tag::viewModelInstance));
    if (host == nullptr)
    {
        return ~0u;
    }
    auto prop = host->instance->propertyValue(SymbolType::itemIndex);
    if (prop != nullptr && prop->is<ViewModelInstanceSymbolListIndex>())
    {
        return (uint32_t)prop->as<ViewModelInstanceSymbolListIndex>()
            ->propertyValue();
    }
    return ~0u;
}

uint32_t dataVmiEqualImpl(WasmScriptingVM* vm, uint32_t a, uint32_t b)
{
    auto lhs = resolveVmiArg(vm, a);
    auto rhs = resolveVmiArg(vm, b);
    return lhs != nullptr && lhs == rhs ? 1 : 0;
}

void dataListRemoveAllOfImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             uint32_t vmiHandle)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    auto instance = resolveVmiArg(vm, vmiHandle);
    if (list != nullptr && instance != nullptr)
    {
        list->removeAllItemsWithViewModelInstance(instance.get());
    }
}

uint32_t dataListGetImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t index)
{
    auto list = resolveInstanceValue<ViewModelInstanceList>(vm, handle);
    if (list == nullptr || index >= list->listItems().size())
    {
        return 0;
    }
    return mintRemovedItem(vm, list->listItems()[index]);
}

uint32_t dataEnumValuesImpl(WasmScriptingVM* vm,
                            uint32_t handle,
                            char* buffer,
                            uint32_t capacity)
{
    auto value = resolveInstanceValue<ViewModelInstanceEnum>(vm, handle);
    if (value == nullptr || value->viewModelProperty() == nullptr ||
        !value->viewModelProperty()->is<ViewModelPropertyEnum>())
    {
        return 0;
    }
    auto dataEnum =
        value->viewModelProperty()->as<ViewModelPropertyEnum>()->dataEnum();
    if (dataEnum == nullptr)
    {
        return 0;
    }
    std::string joined;
    for (auto& entry : dataEnum->values())
    {
        if (!joined.empty())
        {
            joined += '\n';
        }
        joined += entry->key();
    }
    return fillModuleString(vm, joined, buffer, capacity);
}

uint32_t dataRootViewModelImpl(WasmScriptingVM* vm, uint32_t objectHandle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    auto instance = object != nullptr && object->dataContext() != nullptr
                        ? object->dataContext()->rootViewModelInstance()
                        : nullptr;
    if (instance == nullptr)
    {
        vm->noteMissingRequestedData();
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

uint32_t dataGlobalViewModelImpl(WasmScriptingVM* vm,
                                 uint32_t objectHandle,
                                 const char* name,
                                 uint32_t nameLength)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    if (object == nullptr || object->scriptAsset() == nullptr ||
        object->scriptAsset()->file() == nullptr ||
        object->dataContext() == nullptr)
    {
        return 0;
    }
    std::string key(name, nameLength);
    auto instance = object->dataContext()->resolveGlobalViewModel(
        object->scriptAsset()->file(),
        key.c_str());
    if (instance == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

uint32_t dataGlobalViewModelNamesImpl(WasmScriptingVM* vm,
                                      uint32_t objectHandle,
                                      char* buffer,
                                      uint32_t capacity)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    if (object == nullptr || object->scriptAsset() == nullptr ||
        object->scriptAsset()->file() == nullptr)
    {
        return 0;
    }
    std::string joined;
    for (auto& name : object->scriptAsset()->file()->globalViewModelNames())
    {
        if (!joined.empty())
        {
            joined += '\n';
        }
        joined += name;
    }
    return fillModuleString(vm, joined, buffer, capacity);
}

struct HostDataContext
{
    rcp<DataContext> context;
};

uint32_t dataContextImpl(WasmScriptingVM* vm, uint32_t objectHandle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto object = static_cast<ScriptedObject*>(
        vm->handles().resolve(objectHandle,
                              WasmScriptingVM::HandleTable::Tag::object));
    if (object == nullptr || object->dataContext() == nullptr)
    {
        vm->noteMissingRequestedData();
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::dataContext,
                              new HostDataContext{object->dataContext()});
}

uint32_t dataContextParentImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostDataContext*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::dataContext));
    if (host == nullptr || host->context->parent() == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::dataContext,
                              new HostDataContext{host->context->parent()});
}

uint32_t dataContextViewModelImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return 0;
    }
    auto host = static_cast<HostDataContext*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::dataContext));
    if (host == nullptr)
    {
        return 0;
    }
    auto instance = host->context->mainViewModelInstance();
    if (instance == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{std::move(instance)});
}

void dataContextReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return;
    }
    delete static_cast<HostDataContext*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::dataContext));
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::dataContext);
}

// --- rive_artboard_v1: host-owned artboard inputs ---------------------------

// Mirrors ScriptReffedArtboard: the host owns the instance, its default state
// machine, and the bound view model instance; module userdata share it by ref.
struct HostArtboard : public RefCnt<HostArtboard>
{
    File* file = nullptr;
    std::unique_ptr<ArtboardInstance> artboard;
    std::unique_ptr<StateMachineInstance> stateMachine;
    rcp<ViewModelInstance> viewModelInstance;
    rcp<DataContext> parentDataContext;

    HostArtboard(File* fileValue,
                 std::unique_ptr<ArtboardInstance>&& artboardInstance,
                 rcp<ViewModelInstance> boundInstance,
                 rcp<DataContext> parent) :
        file(fileValue),
        artboard(std::move(artboardInstance)),
        stateMachine(artboard->defaultStateMachine()),
        parentDataContext(std::move(parent))
    {
        // A scripted artboard is a root: nothing hosts it in another
        // artboard's focus tree, so it owns its FocusManager and builds its
        // own focus tree.
        artboard->buildFocusTree(artboard->ensureFocusManager(), nullptr);
        viewModelInstance = boundInstance != nullptr
                                ? std::move(boundInstance)
                                : file->createViewModelInstance(artboard.get());
        if (stateMachine != nullptr && viewModelInstance != nullptr)
        {
            if (parentDataContext != nullptr)
            {
                auto dataContext = make_rcp<DataContext>(viewModelInstance);
                dataContext->parent(parentDataContext);
                stateMachine->bindDataContext(dataContext);
            }
            else
            {
                stateMachine->bindViewModelInstance(viewModelInstance);
            }
        }
    }

    ~HostArtboard()
    {
        // State machine before artboard; its destructor touches the artboard.
        stateMachine = nullptr;
        artboard = nullptr;
    }

    bool advance(float seconds)
    {
        if (stateMachine != nullptr)
        {
            // Bound view models advance with the host frame, not here.
            return stateMachine->advanceAndApply(seconds, false);
        }
        return artboard->advance(seconds);
    }
};

HostArtboard* resolveArtboard(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostArtboard*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::artboard));
}

void artboardReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return;
    }
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::artboard);
    host->unref();
}

uint32_t artboardAdvanceImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             float seconds)
{
    auto host = resolveArtboard(vm, handle);
    return host != nullptr && host->advance(seconds) ? 1 : 0;
}

void artboardDrawImpl(WasmScriptingVM* vm,
                      uint32_t handle,
                      uint32_t rendererHandle)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return;
    }
    auto renderer = static_cast<Renderer*>(
        vm->handles().resolve(rendererHandle,
                              WasmScriptingVM::HandleTable::Tag::renderer));
    if (renderer != nullptr)
    {
        host->artboard->drawInternal(renderer);
    }
}

namespace
{
struct WasmDrawVisit
{
    WasmScriptingVM* vm;
    bool failed = false;
};

void wasmDrawVisitor(void* context, Drawable* drawable, Renderer* renderer)
{
    auto visit = static_cast<WasmDrawVisit*>(context);
    if (visit->failed)
    {
        drawable->draw(renderer);
        return;
    }
    auto& handles = visit->vm->handles();
    uint32_t handle =
        handles.mint(WasmScriptingVM::HandleTable::Tag::drawable, drawable);
    auto& saves = visit->vm->visitSaves();
    WasmScriptingVM::VisitSaves outer = saves;
    saves = {renderer, 0};
    visit->failed = !visit->vm->notifyDrawVisit(handle);
    if (visit->failed)
    {
        for (; saves.open > 0; saves.open--)
        {
            renderer->restore();
        }
    }
    saves = outer;
    handles.release(handle, WasmScriptingVM::HandleTable::Tag::drawable);
}

Drawable* resolveDrawable(WasmScriptingVM* vm, uint32_t handle)
{
    return vm == nullptr ? nullptr
                         : static_cast<Drawable*>(vm->handles().resolve(
                               handle,
                               WasmScriptingVM::HandleTable::Tag::drawable));
}

CustomProperty* resolveDrawableProperty(WasmScriptingVM* vm,
                                        uint32_t handle,
                                        uint32_t key)
{
    auto drawable = resolveDrawable(vm, handle);
    return drawable != nullptr ? drawable->customProperty(key) : nullptr;
}
} // namespace

void artboardDrawVisitImpl(WasmScriptingVM* vm,
                           uint32_t handle,
                           uint32_t rendererHandle)
{
    auto host = resolveArtboard(vm, handle);
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (host == nullptr || renderer == nullptr)
    {
        return;
    }
    WasmDrawVisit visit = {vm};
    host->artboard->drawInternal(renderer, wasmDrawVisitor, &visit, host->file);
}

void artboardDrawModulatedImpl(WasmScriptingVM* vm,
                               uint32_t handle,
                               uint32_t rendererHandle,
                               uint32_t key)
{
    auto host = resolveArtboard(vm, handle);
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (host != nullptr && renderer != nullptr)
    {
        host->artboard->drawModulated(renderer, key, host->file);
    }
}

void artboardDrawableDrawImpl(WasmScriptingVM* vm,
                              uint32_t handle,
                              uint32_t rendererHandle)
{
    auto drawable = resolveDrawable(vm, handle);
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (drawable != nullptr && renderer != nullptr)
    {
        drawable->draw(renderer);
    }
}

uint32_t artboardPropertyKeyImpl(WasmScriptingVM* vm,
                                 uint32_t handle,
                                 const char* name,
                                 uint32_t length)
{
    auto host = resolveArtboard(vm, handle);
    return File::customPropertyKey(host != nullptr ? host->file : nullptr,
                                   name,
                                   length);
}

uint32_t artboardDrawableValueImpl(WasmScriptingVM* vm,
                                   uint32_t handle,
                                   uint32_t key,
                                   uint32_t* out,
                                   uint32_t outCount)
{
    auto property = resolveDrawableProperty(vm, handle, key);
    if (property == nullptr)
    {
        return 0;
    }
    CustomPropertyKind kind = property->kind();
    uint32_t bits = 0;
    switch (kind)
    {
        case CustomPropertyKind::number:
        {
            float value = property->as<CustomPropertyNumber>()->propertyValue();
            memcpy(&bits, &value, sizeof(bits));
            break;
        }
        case CustomPropertyKind::boolean:
            bits = property->as<CustomPropertyBoolean>()->propertyValue();
            break;
        case CustomPropertyKind::color:
            bits = property->as<CustomPropertyColor>()->propertyValue();
            break;
        default:
            // No reader takes the others' bits, the kind answers has().
            break;
    }
    if (outCount > 0)
    {
        out[0] = bits;
    }
    return (uint32_t)kind + 1;
}

uint32_t artboardDrawableStringImpl(WasmScriptingVM* vm,
                                    uint32_t handle,
                                    uint32_t key,
                                    char* out,
                                    uint32_t outCount)
{
    auto property = resolveDrawableProperty(vm, handle, key);
    if (property == nullptr || !property->is<CustomPropertyString>())
    {
        return ~0u;
    }
    return fillModuleString(
        vm,
        property->as<CustomPropertyString>()->propertyValue(),
        out,
        outCount);
}

#ifdef WITH_RIVE_TOOLS
uint32_t artboardDrawablePropertiesImpl(WasmScriptingVM* vm,
                                        uint32_t handle,
                                        char* out,
                                        uint32_t outCount)
{
    auto drawable = resolveDrawable(vm, handle);
    auto file =
        drawable != nullptr ? drawable->artboard()->drawVisitorFile() : nullptr;
    auto manifest = file != nullptr ? file->manifest() : nullptr;
    if (manifest == nullptr)
    {
        return 0;
    }
    std::string packed;
    for (auto child : drawable->children())
    {
        auto property = CustomProperty::tagging(child);
        if (property == nullptr)
        {
            continue;
        }
        packed.push_back((char)property->kind());
        packed.append(manifest->resolveName(property->nameId()));
        packed.push_back('\0');
    }
    memcpy(out, packed.data(), std::min<size_t>(packed.size(), outCount));
    return (uint32_t)packed.size();
}
#endif

uint32_t artboardInstanceImpl(WasmScriptingVM* vm,
                              uint32_t handle,
                              uint32_t vmiHandle)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return 0;
    }
    auto clone = host->artboard->instance();
    clone->frameOrigin(false);
    auto vmi = vmiHandle != 0 ? resolveVmiArg(vm, vmiHandle) : nullptr;
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::artboard,
                              new HostArtboard(host->file,
                                               std::move(clone),
                                               std::move(vmi),
                                               host->parentDataContext));
}

uint32_t artboardDataImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr || host->viewModelInstance == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::viewModelInstance,
        new HostViewModelInstance{host->viewModelInstance});
}

float artboardWidthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveArtboard(vm, handle);
    return host != nullptr ? host->artboard->width() : 0.0f;
}

float artboardHeightImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveArtboard(vm, handle);
    return host != nullptr ? host->artboard->height() : 0.0f;
}

void artboardSetWidthImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
    auto host = resolveArtboard(vm, handle);
    if (host != nullptr)
    {
        host->artboard->width(value);
    }
}

void artboardSetHeightImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
    auto host = resolveArtboard(vm, handle);
    if (host != nullptr)
    {
        host->artboard->height(value);
    }
}

uint32_t artboardFrameOriginImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveArtboard(vm, handle);
    return host != nullptr && host->artboard->frameOrigin() ? 1 : 0;
}

void artboardSetFrameOriginImpl(WasmScriptingVM* vm,
                                uint32_t handle,
                                uint32_t value)
{
    auto host = resolveArtboard(vm, handle);
    if (host != nullptr)
    {
        host->artboard->frameOrigin(value != 0);
    }
}

void artboardBoundsImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        float* out,
                        uint32_t outCount)
{
    auto host = resolveArtboard(vm, handle);
    if (host == nullptr || outCount < 4)
    {
        return;
    }
    const AABB& bounds = host->artboard->bounds();
    out[0] = bounds.min().x;
    out[1] = bounds.min().y;
    out[2] = bounds.max().x;
    out[3] = bounds.max().y;
}

uint32_t artboardPointerEventImpl(WasmScriptingVM* vm,
                                  uint32_t handle,
                                  uint32_t kind,
                                  uint32_t pointerId,
                                  float x,
                                  float y)
{
    auto host = resolveArtboard(vm, handle);
    if (host == nullptr || host->stateMachine == nullptr)
    {
        return 0;
    }
    Vec2D position(x, y);
    switch (kind)
    {
        case ArtboardWire::pointerDown:
            return (uint32_t)(int)host->stateMachine->pointerDown(
                position,
                (uint8_t)pointerId);
        case ArtboardWire::pointerMove:
            return (uint32_t)(int)host->stateMachine->pointerMove(
                position,
                0,
                (uint8_t)pointerId);
        case ArtboardWire::pointerUp:
            return (uint32_t)(int)host->stateMachine->pointerUp(
                position,
                (uint8_t)pointerId);
        case ArtboardWire::pointerExit:
            return (uint32_t)(int)host->stateMachine->pointerExit(
                position,
                (uint8_t)pointerId);
    }
    return 0;
}

// Animations pin their artboard so the instance they play into outlives them.
struct HostAnimation
{
    rcp<HostArtboard> owner;
    std::unique_ptr<LinearAnimationInstance> animation;

    float duration() const
    {
        return (float)animation->duration() / (float)animation->fps();
    }
};

uint32_t artboardAnimationImpl(WasmScriptingVM* vm,
                               uint32_t handle,
                               const char* name,
                               uint32_t length)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return 0;
    }
    auto animation = host->artboard->animationNamed(std::string(name, length));
    if (animation == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::animation,
        new HostAnimation{ref_rcp(host), std::move(animation)});
}

HostAnimation* resolveAnimation(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostAnimation*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::animation));
}

void artboardAnimationReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveAnimation(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return;
    }
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::animation);
    delete host;
}

float artboardAnimationDurationImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveAnimation(vm, handle);
    return host != nullptr ? host->duration() : 0.0f;
}

uint32_t artboardAnimationAdvanceImpl(WasmScriptingVM* vm,
                                      uint32_t handle,
                                      float seconds)
{
    auto host = resolveAnimation(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    bool advanced = host->animation->advance(seconds);
    host->animation->apply();
    return advanced ? 1 : 0;
}

void artboardAnimationSetTimeImpl(WasmScriptingVM* vm,
                                  uint32_t handle,
                                  float value,
                                  uint32_t mode)
{
    auto host = resolveAnimation(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    float seconds = value;
    if (mode == ArtboardWire::timeFrames)
    {
        seconds = value / (float)host->animation->fps();
    }
    else if (mode == ArtboardWire::timePercentage)
    {
        seconds = value * host->duration();
    }
    host->animation->time(
        host->animation->animation()->globalToLocalSeconds(seconds));
    host->animation->apply();
}

// Nodes pin their artboard; the component pointer lives inside its instance.
struct HostNode
{
    rcp<HostArtboard> owner;
    TransformComponent* component;
};

uint32_t artboardNodeImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          const char* name,
                          uint32_t length)
{
    auto host = resolveArtboard(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return 0;
    }
    auto component =
        host->artboard->find<TransformComponent>(std::string(name, length));
    if (component == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::node,
                              new HostNode{ref_rcp(host), component});
}

HostNode* resolveNode(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostNode*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::node));
}

void artboardNodeReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveNode(vm, handle);
    if (vm == nullptr || host == nullptr)
    {
        return;
    }
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::node);
    delete host;
}

void artboardNodeTransformImpl(WasmScriptingVM* vm,
                               uint32_t handle,
                               float* out,
                               uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || outCount < 5)
    {
        return;
    }
    out[0] = host->component->x();
    out[1] = host->component->y();
    out[2] = host->component->rotation();
    out[3] = host->component->scaleX();
    out[4] = host->component->scaleY();
}

// x/y writes only land on Node and RootBone, like the Luau lane.
void nodeSetX(TransformComponent* component, float value)
{
    if (component->is<Node>())
    {
        component->as<Node>()->x(value);
    }
    else if (component->is<RootBone>())
    {
        component->as<RootBone>()->x(value);
    }
}

void nodeSetY(TransformComponent* component, float value)
{
    if (component->is<Node>())
    {
        component->as<Node>()->y(value);
    }
    else if (component->is<RootBone>())
    {
        component->as<RootBone>()->y(value);
    }
}

void artboardNodeSetImpl(WasmScriptingVM* vm,
                         uint32_t handle,
                         uint32_t field,
                         float v0,
                         float v1)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    TransformComponent* component = host->component;
    switch (field)
    {
        case ArtboardWire::nodeX:
            nodeSetX(component, v0);
            break;
        case ArtboardWire::nodeY:
            nodeSetY(component, v0);
            break;
        case ArtboardWire::nodeRotation:
            component->rotation(v0);
            break;
        case ArtboardWire::nodeScaleX:
            component->scaleX(v0);
            break;
        case ArtboardWire::nodeScaleY:
            component->scaleY(v0);
            break;
        case ArtboardWire::nodePosition:
            nodeSetX(component, v0);
            nodeSetY(component, v1);
            break;
        case ArtboardWire::nodeScale:
            component->scaleX(v0);
            component->scaleY(v1);
            break;
    }
}

void artboardNodeWorldTransformImpl(WasmScriptingVM* vm,
                                    uint32_t handle,
                                    float* out,
                                    uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || outCount < 6)
    {
        return;
    }
    const Mat2D& world = host->component->worldTransform();
    for (int i = 0; i < 6; i++)
    {
        out[i] = world[i];
    }
}

void artboardNodeSetWorldTransformImpl(WasmScriptingVM* vm,
                                       uint32_t handle,
                                       const float* values,
                                       uint32_t floatCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || floatCount < 6)
    {
        return;
    }
    host->component->mutableWorldTransform() =
        Mat2D(values[0], values[1], values[2], values[3], values[4], values[5]);
}

void artboardNodeDecomposeImpl(WasmScriptingVM* vm,
                               uint32_t handle,
                               const float* values,
                               uint32_t floatCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || floatCount < 6)
    {
        return;
    }
    TransformComponent* component = host->component;
    Mat2D world =
        getParentWorld(*component).invertOrIdentity() *
        Mat2D(values[0], values[1], values[2], values[3], values[4], values[5]);
    TransformComponents components = world.decompose();
    nodeSetX(component, components.x());
    nodeSetY(component, components.y());
    component->scaleX(components.scaleX());
    component->scaleY(components.scaleY());
    component->rotation(components.rotation());
}

uint32_t artboardNodePathVerbsImpl(WasmScriptingVM* vm,
                                   uint32_t handle,
                                   uint8_t* out,
                                   uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || !host->component->is<Path>())
    {
        return ~0u;
    }
    return fillOut(pathVerbBytes(host->component->as<Path>()->rawPath()),
                   out,
                   outCount);
}

uint32_t artboardNodePathPointsImpl(WasmScriptingVM* vm,
                                    uint32_t handle,
                                    float* out,
                                    uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || !host->component->is<Path>())
    {
        return ~0u;
    }
    return fillOut(pathFloats(host->component->as<Path>()->rawPath()),
                   out,
                   outCount);
}

uint32_t artboardNodePaintImpl(WasmScriptingVM* vm,
                               uint32_t handle,
                               uint32_t* out,
                               uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || !host->component->is<ShapePaint>() || outCount < 7)
    {
        return 0;
    }
    // The same snapshot ScriptedPaintData(const ShapePaint*) takes.
    auto shapePaint = host->component->as<ShapePaint>();
    uint32_t style = (uint32_t)RenderPaintStyle::fill;
    uint32_t join = (uint32_t)StrokeJoin::miter;
    uint32_t cap = (uint32_t)StrokeCap::butt;
    float thickness = 1.0f;
    float featherStrength = 0.0f;
    uint32_t color = 0xFF000000;
    if (shapePaint->is<Stroke>())
    {
        auto stroke = shapePaint->as<Stroke>();
        style = (uint32_t)RenderPaintStyle::stroke;
        thickness = stroke->thickness();
        cap = stroke->cap();
        join = stroke->join();
    }
    for (auto& child : shapePaint->children())
    {
        if (child->is<SolidColor>())
        {
            color = child->as<SolidColor>()->colorValue();
            break;
        }
    }
    if (shapePaint->feather() != nullptr)
    {
        featherStrength = shapePaint->feather()->strength();
    }
    out[0] = style;
    out[1] = join;
    out[2] = cap;
    out[3] = (uint32_t)shapePaint->blendModeValue();
    out[4] = color;
    memcpy(&out[5], &thickness, sizeof(float));
    memcpy(&out[6], &featherStrength, sizeof(float));
    return 1;
}

uint32_t artboardNodeChildrenImpl(WasmScriptingVM* vm,
                                  uint32_t handle,
                                  uint32_t* out,
                                  uint32_t outCount)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr || !host->component->is<ContainerComponent>())
    {
        return 0;
    }
    auto& children = host->component->as<ContainerComponent>()->children();
    uint32_t count = 0;
    for (auto child : children)
    {
        if (child->is<TransformComponent>())
        {
            count++;
        }
    }
    if (count > outCount)
    {
        return count;
    }
    uint32_t index = 0;
    for (auto child : children)
    {
        if (child->is<TransformComponent>())
        {
            out[index++] = vm->handles().mint(
                WasmScriptingVM::HandleTable::Tag::node,
                new HostNode{host->owner, child->as<TransformComponent>()});
        }
    }
    return count;
}

uint32_t artboardNodeParentImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveNode(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    auto parent = host->component->parent();
    if (parent == nullptr || !parent->is<TransformComponent>())
    {
        return 0;
    }
    return vm->handles().mint(
        WasmScriptingVM::HandleTable::Tag::node,
        new HostNode{host->owner, parent->as<TransformComponent>()});
}

// --- rive_data_v1 asset properties (image/font/blob) ------------------------

struct HostFont
{
    rcp<Font> font;
#ifdef WITH_RIVE_TEXT
    RawPath glyphPath;
    uint32_t glyphPathId = 0;
    bool hasGlyphPath = false;
#endif
};

uint32_t dataVmiImageImpl(WasmScriptingVM* vm,
                          uint32_t vmiHandle,
                          const char* name,
                          uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceAssetImage>(vm,
                                                          vmiHandle,
                                                          name,
                                                          length);
}

uint32_t dataVmiFontImpl(WasmScriptingVM* vm,
                         uint32_t vmiHandle,
                         const char* name,
                         uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceAssetFont>(vm,
                                                         vmiHandle,
                                                         name,
                                                         length);
}

uint32_t dataVmiBlobImpl(WasmScriptingVM* vm,
                         uint32_t vmiHandle,
                         const char* name,
                         uint32_t length)
{
    return mintInstanceValue<ViewModelInstanceAssetBlob>(vm,
                                                         vmiHandle,
                                                         name,
                                                         length);
}

// Mirrors ScriptedPropertyImage::pushValue: the instance's embedded asset
// first, else the id-bound asset through the file registry.
uint32_t dataImageGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetImage>(vm, handle);
    if (vm == nullptr || value == nullptr)
    {
        return 0;
    }
    RenderImage* renderImage = nullptr;
    if (auto asset = value->asset())
    {
        renderImage = asset->renderImage();
    }
    if (renderImage == nullptr && vm->file() != nullptr)
    {
        auto fileAsset = vm->file()->asset(value->propertyValue());
        if (fileAsset != nullptr && fileAsset->is<ImageAsset>())
        {
            renderImage = fileAsset->as<ImageAsset>()->renderImage();
        }
    }
    if (renderImage == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::image,
                              new HostImage{ref_rcp(renderImage)});
}

void dataImageSetImpl(WasmScriptingVM* vm,
                      uint32_t handle,
                      uint32_t imageHandle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetImage>(vm, handle);
    if (value == nullptr)
    {
        return;
    }
    auto host = resolveImage(vm, imageHandle);
    value->value(host != nullptr ? host->image.get() : nullptr);
}

uint32_t dataFontGetImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetFont>(vm, handle);
    if (vm == nullptr || value == nullptr)
    {
        return 0;
    }
    rcp<Font> font;
    if (auto asset = value->asset())
    {
        font = asset->font();
    }
    if (font == nullptr && vm->file() != nullptr)
    {
        auto fileAsset = vm->file()->asset(value->propertyValue());
        if (fileAsset != nullptr && fileAsset->is<FontAsset>())
        {
            font = fileAsset->as<FontAsset>()->font();
        }
    }
    if (font == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::font,
                              new HostFont{std::move(font)});
}

void dataFontSetImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t fontHandle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetFont>(vm, handle);
    if (vm == nullptr || value == nullptr)
    {
        return;
    }
    auto host = static_cast<HostFont*>(
        vm->handles().resolve(fontHandle,
                              WasmScriptingVM::HandleTable::Tag::font));
    value->value(host != nullptr ? host->font.get() : nullptr);
}

HostFont* resolveFont(WasmScriptingVM* vm, uint32_t handle);

void dataFontReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    // A font the teardown sweep already freed resolves to nothing here.
    auto host = resolveFont(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    delete host;
    vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::font);
}

// --- rive_font_v1 / rive_text_v1
// ----------------------------------------------

HostFont* resolveFont(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostFont*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::font));
}

uint32_t mintFont(WasmScriptingVM* vm, rcp<Font> font)
{
    if (font == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::font,
                              new HostFont{std::move(font)});
}

uint32_t floatBits(float value)
{
    uint32_t bits;
    memcpy(&bits, &value, sizeof(bits));
    return bits;
}

float bitsFloat(uint32_t bits)
{
    float value;
    memcpy(&value, &bits, sizeof(value));
    return value;
}

uint32_t fontFromAssetImpl(WasmScriptingVM* vm,
                           uint32_t objectHandle,
                           const char* name,
                           uint32_t length)
{
    auto asset = findFileAsset<FontAsset>(vm, objectHandle, name, length);
    return asset == nullptr ? 0 : mintFont(vm, asset->font());
}

void fontReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    dataFontReleaseImpl(vm, handle);
}

void fontMetricsImpl(WasmScriptingVM* vm,
                     uint32_t handle,
                     float* out,
                     uint32_t outCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr || out == nullptr || outCount < 4)
    {
        return;
    }
    const Font::LineMetrics& metrics = host->font->lineMetrics();
    out[0] = metrics.ascent;
    out[1] = metrics.descent;
    out[2] = metrics.capHeight;
    out[3] = metrics.xHeight;
}

uint32_t fontWeightImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveFont(vm, handle);
    return host == nullptr ? 0 : host->font->getWeight();
}

uint32_t fontIsItalicImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveFont(vm, handle);
    return host != nullptr && host->font->isItalic() ? 1 : 0;
}

uint32_t fontAxisCountImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveFont(vm, handle);
    return host == nullptr ? 0 : host->font->getAxisCount();
}

void fontAxisImpl(WasmScriptingVM* vm,
                  uint32_t handle,
                  uint32_t index,
                  float* out,
                  uint32_t outCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr || out == nullptr || outCount < 4 ||
        index >= host->font->getAxisCount())
    {
        return;
    }
    Font::Axis axis = host->font->getAxis((uint16_t)index);
    out[0] = bitsFloat(axis.tag);
    out[1] = axis.min;
    out[2] = axis.def;
    out[3] = axis.max;
}

float fontAxisValueImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t tag)
{
    auto host = resolveFont(vm, handle);
    return host == nullptr ? 0.0f : host->font->getAxisValue(tag);
}

uint32_t fontFeaturesImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          uint32_t* out,
                          uint32_t outCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    SimpleArray<uint32_t> features = host->font->features();
    return fillOut(Span<const uint32_t>(features.data(), features.size()),
                   out,
                   outCount);
}

uint32_t fontHasGlyphImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          uint32_t codepoint)
{
    auto host = resolveFont(vm, handle);
    return host != nullptr && host->font->hasGlyph(codepoint) ? 1 : 0;
}

uint32_t fontWithOptionsImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             const uint32_t* coords,
                             uint32_t coordCount,
                             const uint32_t* features,
                             uint32_t featureCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    std::vector<Font::Coord> axes;
    for (uint32_t i = 0; i + 1 < coordCount; i += 2)
    {
        axes.push_back({coords[i], bitsFloat(coords[i + 1])});
    }
    std::vector<Font::Feature> settings;
    for (uint32_t i = 0; i + 1 < featureCount; i += 2)
    {
        settings.push_back({features[i], features[i + 1]});
    }
    return mintFont(vm, host->font->withOptions(axes, settings));
}

#ifdef WITH_RIVE_TEXT
uint32_t fontDecodeImpl(WasmScriptingVM* vm,
                        const uint8_t* bytes,
                        uint32_t byteCount)
{
    if (vm == nullptr || bytes == nullptr)
    {
        return 0;
    }
    return mintFont(vm, HBFont::Decode(Span<const uint8_t>(bytes, byteCount)));
}

// The outline crosses in two calls, so the last one is kept for the second.
const RawPath& fontGlyph(HostFont* host, uint32_t glyph)
{
    if (!host->hasGlyphPath || host->glyphPathId != glyph)
    {
        host->glyphPath = RawText::glyphPath(*host->font, (GlyphID)glyph);
        host->glyphPathId = glyph;
        host->hasGlyphPath = true;
    }
    return host->glyphPath;
}

uint32_t fontGlyphVerbsImpl(WasmScriptingVM* vm,
                            uint32_t handle,
                            uint32_t glyph,
                            uint8_t* out,
                            uint32_t outCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    return fillOut(pathVerbBytes(fontGlyph(host, glyph)), out, outCount);
}

uint32_t fontGlyphPointsImpl(WasmScriptingVM* vm,
                             uint32_t handle,
                             uint32_t glyph,
                             float* out,
                             uint32_t outCount)
{
    auto host = resolveFont(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    return fillOut(pathFloats(fontGlyph(host, glyph)), out, outCount);
}

// A Text builtin: the layout plus the flat records the module reads it
// through, rebuilt after any change.
struct HostText
{
    HostText(Factory* factory) : text(factory) {}
    RawText text;
    std::vector<const GlyphRun*> runs;
    std::vector<uint32_t> lineWords;
    std::vector<uint32_t> runWords;
    std::vector<uint32_t> glyphWords;
    // Fonts the layout produced, fallbacks included, handed to the module as
    // handles this text owns.
    std::unordered_map<const Font*, uint32_t> fontHandles;
    // RawText revision the records were built from; ~0u before the first.
    uint32_t snapshotRevision = ~0u;
};

HostText* resolveText(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostText*>(
        vm->handles().resolve(handle, WasmScriptingVM::HandleTable::Tag::text));
}

void deleteHostText(WasmScriptingVM* vm, HostText* host)
{
    if (host == nullptr)
    {
        return;
    }
    for (auto& pair : host->fontHandles)
    {
        dataFontReleaseImpl(vm, pair.second);
    }
    delete host;
}

void buildTextSnapshot(WasmScriptingVM* vm, HostText* host)
{
    if (host->snapshotRevision == host->text.revision())
    {
        return;
    }
    host->snapshotRevision = host->text.revision();
    host->runs.clear();
    host->lineWords.clear();
    host->runWords.clear();
    host->glyphWords.clear();

    RawText& text = host->text;
    const GlyphLookup& lookup = text.layoutView().glyphLookup();
    std::unordered_map<const GlyphRun*, uint32_t> runIndices;
    uint32_t glyphCount = 0;
    for (uint32_t line = 0; line < text.lineCount(); line++)
    {
        const OrderedLine& orderedLine = text.orderedLines()[line];
        uint32_t glyphStart = glyphCount;
        text.forEachGlyph(
            line,
            [&](const GlyphRun& run, uint32_t glyphIndex, Vec2D position) {
                auto indexed =
                    runIndices.emplace(&run, (uint32_t)host->runs.size());
                if (indexed.second)
                {
                    host->runs.push_back(&run);
                }
                glyphCount++;
                GlyphID glyphId = run.glyphs[glyphIndex];
                uint32_t flags =
                    (run.level & 1) | (run.font->isColorGlyph(glyphId) ? 2 : 0);
                host->glyphWords.insert(host->glyphWords.end(),
                                        {glyphId,
                                         run.textIndices[glyphIndex],
                                         indexed.first->second,
                                         flags,
                                         floatBits(position.x),
                                         floatBits(position.y),
                                         floatBits(run.advances[glyphIndex])});
                return true;
            });
        host->lineWords.insert(host->lineWords.end(),
                               {glyphStart,
                                glyphCount - glyphStart,
                                (uint32_t)text.lineDirection(line),
                                orderedLine.firstCodePointIndex(lookup),
                                orderedLine.lastCodePointIndex(lookup),
                                floatBits(orderedLine.glyphLine().startX),
                                floatBits(text.lineTop(line)),
                                floatBits(orderedLine.y()),
                                floatBits(orderedLine.bottom())});
    }
    for (const GlyphRun* run : host->runs)
    {
        auto found = host->fontHandles.find(run->font.get());
        if (found == host->fontHandles.end())
        {
            found = host->fontHandles
                        .emplace(run->font.get(), mintFont(vm, run->font))
                        .first;
        }
        host->runWords.insert(host->runWords.end(),
                              {found->second,
                               (uint32_t)(run->level & 1),
                               floatBits(run->size),
                               floatBits(run->lineHeight),
                               floatBits(run->letterSpacing)});
    }
}

uint32_t textNewImpl(WasmScriptingVM* vm)
{
    if (vm == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::text,
                              new HostText(vm->factory()));
}

void textReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
    deleteHostText(vm, resolveText(vm, handle));
    if (vm != nullptr)
    {
        vm->handles().release(handle, WasmScriptingVM::HandleTable::Tag::text);
    }
}

void textAppendImpl(WasmScriptingVM* vm,
                    uint32_t handle,
                    const char* chars,
                    uint32_t length,
                    uint32_t fontHandle,
                    uint32_t paintHandle,
                    float size,
                    float lineHeight,
                    float letterSpacing,
                    uint32_t foreground)
{
    auto host = resolveText(vm, handle);
    auto font = resolveFont(vm, fontHandle);
    if (host == nullptr || font == nullptr)
    {
        return;
    }
    RenderPaint* paint = resolvePaint(vm, paintHandle);
    host->text.append(std::string(chars, length),
                      paint != nullptr ? ref_rcp(paint) : nullptr,
                      font->font,
                      size,
                      lineHeight,
                      letterSpacing,
                      foreground);
}

void textClearImpl(WasmScriptingVM* vm, uint32_t handle)
{
    if (auto host = resolveText(vm, handle))
    {
        host->text.clear();
    }
}

void textLayoutImpl(WasmScriptingVM* vm,
                    uint32_t handle,
                    const rive_text_layout_desc_v1* desc,
                    uint32_t descByteCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr || desc == nullptr ||
        descByteCount < sizeof(rive_text_layout_desc_v1))
    {
        return;
    }
    RawText& text = host->text;
    text.sizingIndex((int)desc->sizing);
    text.overflowIndex((int)desc->overflow);
    text.alignIndex((int)desc->align);
    text.wrapIndex((int)desc->wrap);
    text.wordBreakIndex((int)desc->wordBreak);
    text.originIndex((int)desc->origin);
    text.directionIndex((int)desc->direction);
    text.maxWidth(desc->maxWidth);
    text.maxHeight(desc->maxHeight);
    text.paragraphSpacing(desc->paragraphSpacing);
}

void textDrawImpl(WasmScriptingVM* vm,
                  uint32_t handle,
                  uint32_t rendererHandle,
                  uint32_t paintHandle)
{
    auto host = resolveText(vm, handle);
    auto renderer = resolveRenderer(vm, rendererHandle);
    if (host == nullptr || renderer == nullptr)
    {
        return;
    }
    RenderPaint* paint = resolvePaint(vm, paintHandle);
    host->text.render(renderer, paint != nullptr ? ref_rcp(paint) : nullptr);
}

void textBoundsImpl(WasmScriptingVM* vm,
                    uint32_t handle,
                    float* out,
                    uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr || out == nullptr || outCount < 4)
    {
        return;
    }
    AABB bounds = host->text.bounds();
    out[0] = bounds.minX;
    out[1] = bounds.minY;
    out[2] = bounds.maxX;
    out[3] = bounds.maxY;
}

uint32_t textLengthImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveText(vm, handle);
    return host == nullptr ? 0 : (uint32_t)host->text.length();
}

uint32_t textLinesImpl(WasmScriptingVM* vm,
                       uint32_t handle,
                       uint32_t* out,
                       uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    buildTextSnapshot(vm, host);
    return fillOut(host->lineWords, out, outCount);
}

uint32_t textRunsImpl(WasmScriptingVM* vm,
                      uint32_t handle,
                      uint32_t* out,
                      uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    buildTextSnapshot(vm, host);
    return fillOut(host->runWords, out, outCount);
}

uint32_t textGlyphsImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        uint32_t* out,
                        uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    buildTextSnapshot(vm, host);
    return fillOut(host->glyphWords, out, outCount);
}

uint32_t textHitTestImpl(WasmScriptingVM* vm, uint32_t handle, float x, float y)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    TextLayoutView view = host->text.layoutView();
    return CursorPosition::fromTranslation(Vec2D(x, y), view).codePointIndex();
}

uint32_t textCaretImpl(WasmScriptingVM* vm,
                       uint32_t handle,
                       uint32_t index,
                       float* out,
                       uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr || out == nullptr || outCount < 3)
    {
        return 0;
    }
    TextLayoutView view = host->text.layoutView();
    auto visual = CursorPosition::atIndex(index, view).visualPosition(view);
    if (!visual.found())
    {
        return 0;
    }
    out[0] = visual.x();
    out[1] = visual.top();
    out[2] = visual.bottom();
    return 1;
}

uint32_t textSelectionRectsImpl(WasmScriptingVM* vm,
                                uint32_t handle,
                                uint32_t from,
                                uint32_t to,
                                float* out,
                                uint32_t outCount)
{
    auto host = resolveText(vm, handle);
    if (host == nullptr)
    {
        return 0;
    }
    TextLayoutView view = host->text.layoutView();
    Cursor cursor(CursorPosition::atIndex(from, view),
                  CursorPosition::atIndex(to, view));
    std::vector<AABB> rects;
    cursor.selectionRects(rects, view);
    std::vector<float> words;
    for (const AABB& rect : rects)
    {
        words.insert(words.end(), {rect.minX, rect.minY, rect.maxX, rect.maxY});
    }
    return fillOut(words, out, outCount);
}
#else
struct HostText
{};
void deleteHostText(WasmScriptingVM*, HostText*) {}
#endif

// Mirrors ScriptedPropertyBlob::pushValue: a non-null instance asset (even
// empty) wins, else the id-bound asset through the file registry.
rcp<FileAsset> resolveBlobAsset(WasmScriptingVM* vm, uint32_t handle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetBlob>(vm, handle);
    if (vm == nullptr || value == nullptr)
    {
        return nullptr;
    }
    if (auto asset = value->asset())
    {
        return asset;
    }
    if (vm->file() != nullptr)
    {
        auto fileAsset = vm->file()->asset(value->propertyValue());
        if (fileAsset != nullptr && fileAsset->is<BlobAsset>())
        {
            return fileAsset;
        }
    }
    return nullptr;
}

uint32_t blobAssetBytesImpl(WasmScriptingVM* vm,
                            uint32_t objectHandle,
                            const char* name,
                            uint32_t nameLength,
                            uint8_t* out,
                            uint32_t outCount)
{
    auto asset = findFileAsset<BlobAsset>(
        vm,
        objectHandle,
        name,
        nameLength,
        [](BlobAsset* blob) { return !blob->bytes().empty(); });
    if (asset == nullptr)
    {
        return 0;
    }
    auto bytes = asset->bytes();
    if (bytes.size() <= outCount)
    {
        memcpy(out, bytes.data(), bytes.size());
    }
    return (uint32_t)bytes.size();
}

// --- rive_audio_v1 ---------------------------------------------------------

#ifdef WITH_RIVE_AUDIO
struct HostAudioSource
{
    rcp<AudioSource> source;
};

struct HostAudioSound
{
    rcp<AudioSound> sound;
};

HostAudioSource* resolveAudioSource(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostAudioSource*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::audioSource));
}

HostAudioSound* resolveAudioSound(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostAudioSound*>(
        vm->handles().resolve(handle,
                              WasmScriptingVM::HandleTable::Tag::audioSound));
}

// The Luau play and playFrame shapes: relative times offset from the
// engine clock, the sound minted at the artboard-free volume of 1. Tools
// builds refuse to play while playback is paused.
uint32_t audioPlaySound(WasmScriptingVM* vm, rcp<AudioSound> sound)
{
    if (sound == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::audioSound,
                              new HostAudioSound{std::move(sound)});
}

rcp<AudioEngine> audioPlayEngine(WasmScriptingVM* vm, HostAudioSource* host)
{
    if (host == nullptr)
    {
        return nullptr;
    }
#ifdef WITH_RIVE_TOOLS
    if (!vm->isPlaying())
    {
        return nullptr;
    }
#endif
    return AudioEngine::RuntimeEngine(true);
}

uint32_t audioPlaySeconds(WasmScriptingVM* vm,
                          uint32_t sourceHandle,
                          float seconds,
                          bool relative)
{
    auto host = resolveAudioSource(vm, sourceHandle);
    auto engine = audioPlayEngine(vm, host);
    if (engine == nullptr)
    {
        return 0;
    }
    if (relative)
    {
        seconds += engine->timeInSeconds();
    }
    return audioPlaySound(vm, engine->playSeconds(host->source, seconds, 0, 0));
}

uint32_t audioPlayFrames(WasmScriptingVM* vm,
                         uint32_t sourceHandle,
                         double frames,
                         bool relative)
{
    auto host = resolveAudioSource(vm, sourceHandle);
    auto engine = audioPlayEngine(vm, host);
    if (engine == nullptr)
    {
        return 0;
    }
    uint64_t startTime = (uint64_t)frames;
    if (relative)
    {
        startTime += engine->timeInFrames();
    }
    return audioPlaySound(vm, engine->play(host->source, startTime, 0, 0));
}
#endif

uint32_t audioSourceImpl(WasmScriptingVM* vm,
                         uint32_t objectHandle,
                         const char* name,
                         uint32_t nameLength)
{
#ifdef WITH_RIVE_AUDIO
    auto asset = findFileAsset<AudioAsset>(
        vm,
        objectHandle,
        name,
        nameLength,
        [](AudioAsset* audio) { return audio->audioSource() != nullptr; });
    if (asset == nullptr)
    {
        return 0;
    }
    return vm->handles().mint(WasmScriptingVM::HandleTable::Tag::audioSource,
                              new HostAudioSource{asset->audioSource()});
#endif
    return 0;
}

void audioSourceReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSource(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::audioSource);
    delete host;
#endif
}

float audioSourceDurationImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSource(vm, handle);
    return host != nullptr ? host->source->duration() : 0.0f;
#else
    return 0.0f;
#endif
}

uint32_t audioSourceSampleRateImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSource(vm, handle);
    return host != nullptr ? host->source->sampleRate() : 0;
#else
    return 0;
#endif
}

uint32_t audioSourceChannelsImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSource(vm, handle);
    return host != nullptr ? host->source->channels() : 0;
#else
    return 0;
#endif
}

uint32_t audioPlayImpl(WasmScriptingVM* vm, uint32_t source)
{
#ifdef WITH_RIVE_AUDIO
    return audioPlaySeconds(vm, source, 0.0f, true);
#else
    return 0;
#endif
}

uint32_t audioPlayAtTimeImpl(WasmScriptingVM* vm,
                             uint32_t source,
                             float seconds)
{
#ifdef WITH_RIVE_AUDIO
    return audioPlaySeconds(vm, source, seconds, false);
#else
    return 0;
#endif
}

uint32_t audioPlayInTimeImpl(WasmScriptingVM* vm,
                             uint32_t source,
                             float seconds)
{
#ifdef WITH_RIVE_AUDIO
    return audioPlaySeconds(vm, source, seconds, true);
#else
    return 0;
#endif
}

uint32_t audioPlayAtFrameImpl(WasmScriptingVM* vm,
                              uint32_t source,
                              double frame)
{
#ifdef WITH_RIVE_AUDIO
    return audioPlayFrames(vm, source, frame, false);
#else
    return 0;
#endif
}

uint32_t audioPlayInFrameImpl(WasmScriptingVM* vm,
                              uint32_t source,
                              double frame)
{
#ifdef WITH_RIVE_AUDIO
    return audioPlayFrames(vm, source, frame, true);
#else
    return 0;
#endif
}

float audioTimeImpl(WasmScriptingVM* vm)
{
#ifdef WITH_RIVE_AUDIO
    auto engine = AudioEngine::RuntimeEngine(true);
    return engine != nullptr ? engine->timeInSeconds() : 0.0f;
#else
    return 0.0f;
#endif
}

double audioTimeFrameImpl(WasmScriptingVM* vm)
{
#ifdef WITH_RIVE_AUDIO
    auto engine = AudioEngine::RuntimeEngine(true);
    return engine != nullptr ? (double)engine->timeInFrames() : 0.0;
#else
    return 0.0;
#endif
}

uint32_t audioSampleRateImpl(WasmScriptingVM* vm)
{
#ifdef WITH_RIVE_AUDIO
    auto engine = AudioEngine::RuntimeEngine(true);
    return engine != nullptr ? engine->sampleRate() : 0;
#else
    return 0;
#endif
}

void audioSoundReleaseImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host == nullptr)
    {
        return;
    }
    vm->handles().release(handle,
                          WasmScriptingVM::HandleTable::Tag::audioSound);
    delete host;
#endif
}

void audioSoundPlayImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host != nullptr)
    {
        host->sound->play();
    }
#endif
}

void audioSoundPauseImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host != nullptr)
    {
        host->sound->pause();
    }
#endif
}

void audioSoundResumeImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host != nullptr)
    {
        host->sound->resume();
    }
#endif
}

void audioSoundStopImpl(WasmScriptingVM* vm,
                        uint32_t handle,
                        uint32_t fadeFrames)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host != nullptr)
    {
        host->sound->stop(fadeFrames);
    }
#endif
}

uint32_t audioSoundSeekImpl(WasmScriptingVM* vm, uint32_t handle, float seconds)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr && host->sound->seekSeconds(seconds) ? 1 : 0;
#else
    return 0;
#endif
}

uint32_t audioSoundSeekFrameImpl(WasmScriptingVM* vm,
                                 uint32_t handle,
                                 double frame)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr && host->sound->seek((uint64_t)frame) ? 1 : 0;
#else
    return 0;
#endif
}

uint32_t audioSoundCompletedImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr && host->sound->completed() ? 1 : 0;
#else
    return 0;
#endif
}

float audioSoundTimeImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr ? host->sound->timeInSeconds() : 0.0f;
#else
    return 0.0f;
#endif
}

double audioSoundTimeFrameImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr ? (double)host->sound->timeInFrames() : 0.0;
#else
    return 0.0;
#endif
}

float audioSoundVolumeImpl(WasmScriptingVM* vm, uint32_t handle)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    return host != nullptr ? host->sound->volume() : 0.0f;
#else
    return 0.0f;
#endif
}

void audioSoundSetVolumeImpl(WasmScriptingVM* vm, uint32_t handle, float value)
{
#ifdef WITH_RIVE_AUDIO
    auto host = resolveAudioSound(vm, handle);
    if (host != nullptr)
    {
        host->sound->volume(value);
    }
#endif
}

uint32_t dataBlobPresentImpl(WasmScriptingVM* vm, uint32_t handle)
{
    return resolveBlobAsset(vm, handle) != nullptr ? 1 : 0;
}

uint32_t dataBlobGetImpl(WasmScriptingVM* vm,
                         uint32_t handle,
                         uint8_t* buffer,
                         uint32_t capacity)
{
    auto asset = resolveBlobAsset(vm, handle);
    if (asset == nullptr)
    {
        return 0;
    }
    auto bytes = asset->as<BlobAsset>()->bytes();
    size_t copied = bytes.size() < capacity ? bytes.size() : capacity;
    memcpy(buffer, bytes.data(), copied);
    return (uint32_t)bytes.size();
}

uint32_t dataBlobNameImpl(WasmScriptingVM* vm,
                          uint32_t handle,
                          char* buffer,
                          uint32_t capacity)
{
    auto asset = resolveBlobAsset(vm, handle);
    if (asset == nullptr)
    {
        return 0;
    }
    return fillModuleString(vm, asset->name(), buffer, capacity);
}

void dataBlobSetImpl(WasmScriptingVM* vm,
                     uint32_t handle,
                     const uint8_t* bytes,
                     uint32_t byteCount)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetBlob>(vm, handle);
    if (value == nullptr)
    {
        return;
    }
    auto asset = make_rcp<BlobAsset>();
    SimpleArray<uint8_t> data(bytes, byteCount);
    asset->decode(data, nullptr);
    value->value(asset.get());
}

void dataBlobClearImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto value = resolveInstanceValue<ViewModelInstanceAssetBlob>(vm, handle);
    if (value != nullptr)
    {
        value->value(nullptr);
    }
}

HostInstanceValue* resolveHostValue(WasmScriptingVM* vm, uint32_t handle)
{
    if (vm == nullptr)
    {
        return nullptr;
    }
    return static_cast<HostInstanceValue*>(vm->handles().resolve(
        handle,
        WasmScriptingVM::HandleTable::Tag::instanceValue));
}

void dataWatchImpl(WasmScriptingVM* vm, uint32_t handle, uint32_t token)
{
    auto host = resolveHostValue(vm, handle);
    if (host == nullptr || host->delegate != nullptr)
    {
        return;
    }
    host->delegate = new HostValueDelegate();
    host->delegate->vm = vm;
    host->delegate->token = token;
    host->value->addDelegate(host->delegate);
}

void dataUnwatchImpl(WasmScriptingVM* vm, uint32_t handle)
{
    auto host = resolveHostValue(vm, handle);
    if (host == nullptr || host->delegate == nullptr)
    {
        return;
    }
    host->value->removeDelegate(host->delegate);
    delete host->delegate;
    host->delegate = nullptr;
}

bool ensureRuntime()
{
    static bool initialized = false;
    static bool ok = false;
    if (initialized)
    {
        return ok;
    }
    initialized = true;

    RuntimeInitArgs args;
    memset(&args, 0, sizeof(args));
    args.mem_alloc_type = Alloc_With_System_Allocator;
    if (!wasm_runtime_full_init(&args))
    {
        return false;
    }
    // Memory grows on demand, so a failed grow is the only sign of a
    // ceiling or device limit before the module traps.
    wasm_runtime_set_enlarge_mem_error_callback(
        [](uint32_t incPages,
           uint64_t currentBytes,
           uint32_t,
           enlarge_memory_error_reason_t reason,
           wasm_module_inst_t,
           wasm_exec_env_t,
           void*) {
            fprintf(stderr,
                    "wasm memory: growing %llu MB by %u pages failed: %s\n",
                    (unsigned long long)(currentBytes >> 20),
                    incPages,
                    reason == MAX_SIZE_REACHED
                        ? "the module hit its wasmMaxPages ceiling"
                        : "the device could not provide the memory");
        },
        nullptr);
    wasm_runtime_register_natives("env",
                                  kEnvNatives,
                                  sizeof(kEnvNatives) / sizeof(NativeSymbol));
    wasm_runtime_register_natives("wasi_snapshot_preview1",
                                  kWasiNatives,
                                  sizeof(kWasiNatives) / sizeof(NativeSymbol));
    if (!registerRiveBindingNatives())
    {
        return false;
    }
    ok = true;
    return ok;
}

} // namespace

uint32_t WasmScriptingVM::HandleTable::mint(Tag tag, void* object)
{
    uint32_t slot;
    if (!freeSlots.empty())
    {
        slot = freeSlots.back();
        freeSlots.pop_back();
    }
    else
    {
        slot = (uint32_t)slots.size();
        slots.push_back({});
    }
    slots[slot].tag = tag;
    slots[slot].object = object;
    // Handle 0 is never valid; slots bias by one.
    return ((slot + 1) & 0xffffff) | ((uint32_t)slots[slot].generation << 24);
}

void* WasmScriptingVM::HandleTable::resolve(uint32_t handle, Tag tag) const
{
    uint32_t slot = (handle & 0xffffff);
    if (slot == 0 || slot > slots.size())
    {
        return nullptr;
    }
    const Slot& entry = slots[slot - 1];
    if (entry.tag != tag || entry.generation != (uint8_t)(handle >> 24))
    {
        return nullptr;
    }
    return entry.object;
}

void WasmScriptingVM::HandleTable::release(uint32_t handle, Tag tag)
{
    uint32_t slot = (handle & 0xffffff);
    if (slot == 0 || slot > slots.size())
    {
        return;
    }
    Slot& entry = slots[slot - 1];
    // Tag mismatch must not free the slot: a mistyped guest release would
    // stale the correctly-typed handle and leak its host wrapper.
    if (entry.generation != (uint8_t)(handle >> 24) || entry.tag != tag)
    {
        return;
    }
    entry.tag = Tag::empty;
    entry.object = nullptr;
    entry.generation++;
    freeSlots.push_back(slot - 1);
}

int WasmScriptingVM::sm_defaultTimeoutMs = 200;

WasmScriptingVM::WasmScriptingVM() = default;

std::unique_ptr<WasmScriptingVM> WasmScriptingVM::make(
    Span<const uint8_t> module,
    Factory* factory,
    std::string& outError,
    std::function<void(const char*, size_t)> print)
{
    std::unique_ptr<WasmScriptingVM> vm(new WasmScriptingVM());
    vm->m_factory = factory;
    vm->m_print = std::move(print);
    if (s_bootHook)
    {
        s_bootHook(*vm, module);
    }
    if (!vm->init(module))
    {
        outError = vm->m_lastError;
        return nullptr;
    }
    return vm;
}

void WasmScriptingVM::callDraw(ScriptedObject* object,
                               int selfRef,
                               Renderer* renderer)
{
    // The handle is scoped to this call; releasing bumps the generation so a
    // stashed renderer goes stale instead of ghost drawing.
    uint32_t handle = m_handles.mint(HandleTable::Tag::renderer, renderer);
    uint32_t args[3] = {m_L, (uint32_t)selfRef, handle};
    callModule("host_obj_draw", 3, args);
    m_handles.release(handle, HandleTable::Tag::renderer);
}

WasmScriptingVM::~WasmScriptingVM()
{
    if (m_budgetSlot != nullptr)
    {
        ScriptWatchdog::instance().remove(m_budgetSlot.get());
    }
    if (m_debugHooks != nullptr)
    {
        m_debugHooks->onDetach(*this);
        m_debugHooks = nullptr;
    }
    // Flag in-flight decodes cancelled before teardown so a later poll
    // cannot call back into this dead VM, mirroring the Luau backend's
    // shutdownAsyncForState.
    if (m_decodeOwnerId != 0)
    {
        auto& pool = getGlobalWorkPoolIfExists();
        if (pool != nullptr)
        {
            pool->cancelAllForOwner(m_decodeOwnerId);
        }
    }
    // Coverage measurement: RIVE_WASM_EXEC_STATS=1 dumps how many frames ran
    // compiled, interpreted, and as guard-exit continuations.
    if (getenv("RIVE_WASM_EXEC_STATS") != nullptr && m_state != nullptr &&
        m_state->execEnv != nullptr)
    {
        uint32_t args[1] = {0};
        uint32_t compiled = callModule("host_exec_stats", 1, args);
        args[0] = 1;
        uint32_t interp = callModule("host_exec_stats", 1, args);
        args[0] = 2;
        uint32_t guardExits = callModule("host_exec_stats", 1, args);
        fprintf(stderr,
                "wasm exec stats: compiled=%u interp=%u guardExits=%u\n",
                compiled,
                interp,
                guardExits);
    }
    // The module never runs guest finalizers at teardown, so host objects
    // behind live handles are swept here; instance values in particular must
    // detach their delegates before the VM goes away.
    for (HandleTable::Slot& slot : m_handles.slots)
    {
        switch (slot.tag)
        {
            case HandleTable::Tag::instanceValue:
                delete static_cast<HostInstanceValue*>(slot.object);
                break;
            case HandleTable::Tag::viewModelInstance:
                delete static_cast<HostViewModelInstance*>(slot.object);
                break;
            case HandleTable::Tag::path:
                delete static_cast<HostPath*>(slot.object);
                break;
            case HandleTable::Tag::measure:
                delete static_cast<HostMeasure*>(slot.object);
                break;
            case HandleTable::Tag::paint:
                delete static_cast<HostPaint*>(slot.object);
                break;
            case HandleTable::Tag::shader:
                delete static_cast<HostShader*>(slot.object);
                break;
            case HandleTable::Tag::image:
                delete static_cast<HostImage*>(slot.object);
                break;
            case HandleTable::Tag::font:
                delete static_cast<HostFont*>(slot.object);
                break;
            case HandleTable::Tag::text:
                deleteHostText(this, static_cast<HostText*>(slot.object));
                break;
            case HandleTable::Tag::buffer:
                delete static_cast<HostBuffer*>(slot.object);
                break;
            case HandleTable::Tag::meshInstances:
                delete static_cast<HostMeshInstances*>(slot.object);
                break;
            case HandleTable::Tag::dataContext:
                delete static_cast<HostDataContext*>(slot.object);
                break;
            case HandleTable::Tag::artboard:
                // Refcounted: animations and nodes may still hold it.
                static_cast<HostArtboard*>(slot.object)->unref();
                break;
            case HandleTable::Tag::animation:
                delete static_cast<HostAnimation*>(slot.object);
                break;
            case HandleTable::Tag::node:
                delete static_cast<HostNode*>(slot.object);
                break;
#ifdef WITH_RIVE_AUDIO
            case HandleTable::Tag::audioSource:
                delete static_cast<HostAudioSource*>(slot.object);
                break;
            case HandleTable::Tag::audioSound:
                delete static_cast<HostAudioSound*>(slot.object);
                break;
#endif
#ifdef RIVE_CANVAS
            case HandleTable::Tag::canvas:
                delete static_cast<HostCanvas*>(slot.object);
                break;
#endif
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
            case HandleTable::Tag::gpuPass:
                delete static_cast<HostGpuPass*>(slot.object);
                break;
            case HandleTable::Tag::gpuCanvas:
                delete static_cast<HostGpuCanvas*>(slot.object);
                break;
            case HandleTable::Tag::gpuBuffer:
                delete static_cast<HostGpuBuffer*>(slot.object);
                break;
            case HandleTable::Tag::gpuTexture:
                delete static_cast<HostGpuTexture*>(slot.object);
                break;
            case HandleTable::Tag::gpuSampler:
                delete static_cast<HostGpuSampler*>(slot.object);
                break;
            case HandleTable::Tag::gpuTextureView:
                delete static_cast<HostGpuTextureView*>(slot.object);
                break;
            case HandleTable::Tag::gpuShaderModule:
                delete static_cast<HostGpuShaderModule*>(slot.object);
                break;
            case HandleTable::Tag::gpuBindGroupLayout:
                delete static_cast<HostGpuBindGroupLayout*>(slot.object);
                break;
            case HandleTable::Tag::gpuBindGroup:
                delete static_cast<HostGpuBindGroup*>(slot.object);
                break;
            case HandleTable::Tag::gpuPipeline:
                delete static_cast<HostGpuPipeline*>(slot.object);
                break;
#endif
            default:
                break;
        }
        slot.tag = HandleTable::Tag::empty;
        slot.object = nullptr;
    }
}

bool WasmScriptingVM::notifyDrawVisit(uint32_t drawable)
{
    uint32_t args[2] = {m_L, drawable};
    return valid() && callModule("host_draw_visit", 2, args) != 0;
}

void WasmScriptingVM::notifyDataValueChanged(uint32_t token)
{
    if (!valid())
    {
        return;
    }
    uint32_t args[2] = {m_L, token};
    callModule("host_data_value_changed", 2, args);
}

// --- context:decodeImage over the module ABI ---------------------------------

#ifdef RIVE_DECODERS
namespace
{

// Mirrors the Luau backend's ImageDecodeTask (lua_image_decode.cpp): same
// Bitmap::decode, same premultiply, same error string, same WorkPool, so the
// wasm lane settles on the same advance as the Luau lane.
class WasmImageDecodeTask : public WorkTask
{
public:
    std::vector<uint8_t> m_encodedData;
    WasmScriptingVM* m_vm = nullptr;
    uint32_t m_token = 0;
    std::unique_ptr<Bitmap> m_bitmap;

    bool execute() override
    {
        m_bitmap = Bitmap::decode(m_encodedData.data(), m_encodedData.size());
        if (!m_bitmap)
        {
            m_errorMessage = "failed to decode image data";
            return false;
        }
        if (m_bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul)
        {
            m_bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul);
        }
        return true;
    }

    void onComplete() override
    {
        if (m_vm != nullptr)
        {
            m_vm->resolveImageDecode(m_token,
                                     m_bitmap->width(),
                                     m_bitmap->height(),
                                     m_bitmap->bytes(),
                                     m_bitmap->width() * m_bitmap->height() *
                                         4);
        }
        m_bitmap.reset();
        m_encodedData.clear();
        m_encodedData.shrink_to_fit();
    }

    void onError(const std::string& error) override
    {
        if (m_vm != nullptr)
        {
            m_vm->rejectImageDecode(m_token, error.c_str());
        }
    }

    void onCancel() override { m_vm = nullptr; }
};

} // namespace
#endif // RIVE_DECODERS

bool WasmScriptingVM::startImageDecode(const uint8_t* bytes,
                                       uint32_t byteCount,
                                       uint32_t token)
{
#ifndef RIVE_DECODERS
    return false;
#else
    if (m_decodeOwnerId == 0)
    {
        m_decodeOwnerId = WorkPool::nextOwnerId();
    }
    auto task = make_rcp<WasmImageDecodeTask>();
    task->m_encodedData.assign(bytes, bytes + byteCount);
    task->m_vm = this;
    task->m_token = token;
    task->setOwnerId(m_decodeOwnerId);
    m_pendingDecodes[token] = task;
    getGlobalWorkPool()->submit(std::move(task));
    return true;
#endif
}

void WasmScriptingVM::cancelImageDecode(uint32_t token)
{
    auto it = m_pendingDecodes.find(token);
    if (it != m_pendingDecodes.end())
    {
        it->second->cancel();
        m_pendingDecodes.erase(it);
    }
}

void WasmScriptingVM::deliverDecodeResult(const DecodeResult& result)
{
    if (result.ok)
    {
        uint32_t byteCount = (uint32_t)result.pixels.size();
        uint32_t sizeArgs[1] = {byteCount};
        uint32_t pixelsPtr = callModule("malloc", 1, sizeArgs);
        if (pixelsPtr == 0)
        {
            DecodeResult failure;
            failure.token = result.token;
            failure.error = "failed to allocate decoded pixels";
            deliverDecodeResult(failure);
            return;
        }
        memcpy(resolveModulePtr(pixelsPtr, byteCount),
               result.pixels.data(),
               byteCount);
        uint32_t args[6] = {m_L,
                            result.token,
                            result.width,
                            result.height,
                            pixelsPtr,
                            byteCount};
        callModule("host_image_decoded", 6, args);
        guestFree(pixelsPtr);
        return;
    }
    uint32_t messagePtr = guestString(result.error.c_str());
    if (messagePtr == 0)
    {
        return;
    }
    uint32_t args[3] = {m_L, result.token, messagePtr};
    callModule("host_image_decode_failed", 3, args);
    guestFree(messagePtr);
}

void WasmScriptingVM::resolveImageDecode(uint32_t token,
                                         uint32_t width,
                                         uint32_t height,
                                         const uint8_t* pixels,
                                         uint32_t byteCount)
{
    m_pendingDecodes.erase(token);
    if (!valid())
    {
        return;
    }
    DecodeResult result;
    result.ok = true;
    result.token = token;
    result.width = width;
    result.height = height;
    result.pixels = Span<const uint8_t>(pixels, byteCount);
    deliverDecodeResult(result);
}

void WasmScriptingVM::rejectImageDecode(uint32_t token, const char* message)
{
    m_pendingDecodes.erase(token);
    if (!valid())
    {
        return;
    }
    DecodeResult result;
    result.token = token;
    result.error = message;
    deliverDecodeResult(result);
}

void WasmScriptingVM::setBootHook(BootHook hook)
{
    s_bootHook = std::move(hook);
}

void WasmScriptingVM::setTimeoutMs(int ms)
{
    m_timeoutMs = ms;
    if (valid())
    {
        uint32_t args[2] = {m_L, (uint32_t)ms};
        callModule("host_set_timeout", 2, args);
    }
}

void WasmScriptingVM::advanceDetachedViewModels()
{
    // Only detached roots; instances with parents are already reached
    // through the bound tree or their detached-root ancestor.
    auto advanceDetached = [](const rcp<ViewModelInstance>& instance) {
        if (instance != nullptr && !instance->hasParents())
        {
            instance->advanced();
        }
    };
    for (auto& slot : m_handles.slots)
    {
        if (slot.tag == HandleTable::Tag::viewModelInstance)
        {
            advanceDetached(
                static_cast<HostViewModelInstance*>(slot.object)->instance);
        }
        else if (slot.tag == HandleTable::Tag::artboard)
        {
            // Artboard inputs keep their bound instance advancing, like the
            // Luau context's tracked instances.
            advanceDetached(
                static_cast<HostArtboard*>(slot.object)->viewModelInstance);
        }
    }
}

#if WASM_ENABLE_PRELINKED_AOT != 0
// Builds the section list for a module whose AOT text is linked into this
// binary and loads it. The relocation section is dropped: the native linker
// already applied every fixup, which is what makes the text usable without
// runtime executable memory.
static wasm_module_t loadPrelinkedModule(const PrelinkedAotModule& prelinked,
                                         char* error,
                                         uint32_t errorSize)
{
    constexpr uint32_t kSectionText = 2;
    constexpr uint32_t kSectionRelocation = 5;
    // .aot container: 8 byte magic+version header, then type/size framed
    // sections. The from-sections loader never sees the header, so an
    // artifact from an incompatible wamrc must be rejected here.
    if (prelinked.aotSize < 8)
    {
        snprintf(error, errorSize, "prelinked aot container too small");
        return nullptr;
    }
    uint32_t magic;
    uint32_t version;
    memcpy(&magic, prelinked.aot, 4);
    memcpy(&version, prelinked.aot + 4, 4);
    if (magic != AOT_MAGIC_NUMBER || version != AOT_CURRENT_VERSION)
    {
        snprintf(error,
                 errorSize,
                 "prelinked aot container magic/version mismatch "
                 "(%08x v%u, runtime expects v%u)",
                 magic,
                 version,
                 (uint32_t)AOT_CURRENT_VERSION);
        return nullptr;
    }
    const uint8_t* p = prelinked.aot + 8;
    const uint8_t* end = prelinked.aot + prelinked.aotSize;
    std::vector<wasm_section_t> sections;
    while (true)
    {
        // The container aligns every u32 read; section headers land on
        // 4 byte boundaries relative to the (aligned) container base.
        // Compare as integers first: the aligned address may lie past end,
        // where pointer arithmetic is undefined.
        uintptr_t aligned = ((uintptr_t)p + 3) & ~(uintptr_t)3;
        if (aligned > (uintptr_t)end || (uintptr_t)end - aligned < 8)
        {
            break;
        }
        p = (const uint8_t*)aligned;
        uint32_t type;
        uint32_t size;
        memcpy(&type, p, 4);
        memcpy(&size, p + 4, 4);
        p += 8;
        if (size > (size_t)(end - p))
        {
            snprintf(error, errorSize, "prelinked aot container truncated");
            return nullptr;
        }
        if (type != kSectionRelocation)
        {
            wasm_section_t section = {};
            section.section_type = (int)type;
            if (type == kSectionText)
            {
                section.section_body = const_cast<uint8_t*>(prelinked.text);
                section.section_body_size = (uint32_t)prelinked.textSize;
            }
            else
            {
                section.section_body = const_cast<uint8_t*>(p);
                section.section_body_size = size;
            }
            sections.push_back(section);
        }
        p += size;
    }
    if (sections.empty())
    {
        snprintf(error, errorSize, "prelinked aot container empty");
        return nullptr;
    }
    for (size_t i = 0; i + 1 < sections.size(); i++)
    {
        sections[i].next = &sections[i + 1];
    }
    sections.back().next = nullptr;
    return wasm_runtime_load_from_sections(sections.data(),
                                           true,
                                           error,
                                           errorSize);
}
#endif

bool WasmScriptingVM::init(Span<const uint8_t> module)
{
    if (!ensureRuntime())
    {
        m_lastError = "wamr runtime init failed";
        return false;
    }

    // wasm_runtime_load keeps referencing the buffer, so hold a copy.
    m_moduleBytes.assign(module.begin(), module.end());
    // Snapshot before load: the loader mutates m_moduleBytes in place
    // (null-terminating names), which corrupts it for wamrc. The AOT lane
    // compiles from this pristine copy instead.
    std::vector<uint8_t> pristineBytes(module.begin(), module.end());
    // One content hash serves the dev AOT artifact lookup and the shared
    // module cache key; the key folds in which artifact actually loads so
    // interp and AOT lanes never share an entry.
    uint64_t moduleKey = 0xcbf29ce484222325ull;
    for (uint8_t byte : m_moduleBytes)
    {
        moduleKey = (moduleKey ^ byte) * 0x100000001b3ull;
    }
    m_state = std::make_unique<WamrState>();
    m_moduleKey = moduleKey;
    char error[256] = {0};
    // Dev AOT lane: with RIVE_WASM_AOT_CACHE set, swap in a wamrc-compiled
    // artifact when one exists for these bytes, else dump the wasm so it can
    // be compiled offline. wasm_runtime_load sniffs the AOT magic.
    char aotPath[1024] = {0};
    bool haveAot = false;
    bool haveHwAot = false;
    bool haveO0Aot = false;
    if (const char* cacheDir = getenv("RIVE_WASM_AOT_CACHE"))
    {
#ifdef RIVE_WASM_HW_BOUNDS
        // Hw artifacts (wamrc --bounds-checks=0 --stack-bounds-checks=1)
        // rely on the guard-page trap handler, so only builds carrying it
        // ever probe the .hw.aot name; sw-only builds cannot load them.
        snprintf(aotPath,
                 sizeof(aotPath),
                 "%s/%016llx.hw.aot",
                 cacheDir,
                 (unsigned long long)moduleKey);
        struct stat hwAotStat;
        haveHwAot = stat(aotPath, &hwAotStat) == 0;
#endif
        if (!haveHwAot)
        {
            snprintf(aotPath,
                     sizeof(aotPath),
                     "%s/%016llx.aot",
                     cacheDir,
                     (unsigned long long)moduleKey);
            struct stat aotStat;
            haveAot = stat(aotPath, &aotStat) == 0;
        }
        if (!haveAot && !haveHwAot)
        {
            char dumpPath[1024];
            snprintf(dumpPath,
                     sizeof(dumpPath),
                     "%s/%016llx.wasm",
                     cacheDir,
                     (unsigned long long)moduleKey);
            struct stat dumpStat;
            if (stat(dumpPath, &dumpStat) != 0)
            {
                if (FILE* dump = fopen(dumpPath, "wb"))
                {
                    fwrite(m_moduleBytes.data(), 1, m_moduleBytes.size(), dump);
                    fclose(dump);
                    fprintf(stderr,
                            "wasm aot: dumped %s for wamrc\n",
                            dumpPath);
                }
            }
        }
    }
    // Ladder cache: content already compiled in a prior session or by a
    // background schedule boots straight onto the artifact - the
    // undo/reopen-instant and permanently-hot-vm_host path.
    // Only the documented values opt into sync boot; any other string (a
    // typo, an empty value) leaves the module on the async ladder rather
    // than silently blocking the load for seconds.
    const char* syncEnv = getenv("RIVE_WASM_AOT_SYNC");
    bool syncO0 = syncEnv != nullptr && strcmp(syncEnv, "o0") == 0;
    bool syncO3 = syncEnv != nullptr && strcmp(syncEnv, "o3") == 0;
    // Debug boot ignores any faster artifact a prior run left in a shared
    // cache; the point is to run -O0, so only the sync-o0 path below acts.
    bool debugBoot = syncO0;
    if (!haveAot && !haveHwAot)
    {
        auto& ladder = ModuleTierLadder::instance();
        if (ladder.enabled())
        {
#ifdef RIVE_WASM_HW_BOUNDS
            std::string hwPath =
                debugBoot ? std::string()
                          : ladder.artifactPath(moduleKey, TierSpecies::hw);
            if (!hwPath.empty() && hwPath.size() < sizeof(aotPath))
            {
                memcpy(aotPath, hwPath.c_str(), hwPath.size() + 1);
                haveHwAot = true;
            }
#endif
            if (!haveHwAot && !debugBoot)
            {
                std::string path =
                    ladder.artifactPath(moduleKey, TierSpecies::o3);
                if (!path.empty() && path.size() < sizeof(aotPath))
                {
                    memcpy(aotPath, path.c_str(), path.size() + 1);
                    haveAot = true;
                }
            }
            // Sync AOT boot, opted in by RIVE_WASM_AOT_SYNC=o3|o0: on a
            // cache miss, compile on this thread and boot the artifact
            // instead of the interpreter. Project-sized modules compile in
            // seconds and the interpreter is never representative of real
            // performance; hosts with large modules stay on the async
            // ladder by not setting this.
            if (!haveAot && !haveHwAot && (syncO0 || syncO3))
            {
#ifdef RIVE_WASM_HW_BOUNDS
                TierSpecies top = TierSpecies::hw;
#else
                TierSpecies top = TierSpecies::o3;
#endif
                TierSpecies species = syncO0 ? TierSpecies::o0 : top;
                auto syncStart = std::chrono::steady_clock::now();
                std::string path = ladder.compileSync(
                    moduleKey,
                    Span<const uint8_t>(pristineBytes.data(),
                                        pristineBytes.size()),
                    species);
                if (!path.empty() && path.size() < sizeof(aotPath))
                {
                    memcpy(aotPath, path.c_str(), path.size() + 1);
                    haveHwAot = species == TierSpecies::hw;
                    haveO0Aot = species == TierSpecies::o0;
                    haveAot = !haveHwAot && !haveO0Aot;
                    m_tierPinned = m_tierPinned || syncO0;
                    auto syncMs =
                        std::chrono::duration_cast<std::chrono::milliseconds>(
                            std::chrono::steady_clock::now() - syncStart)
                            .count();
                    fprintf(stderr,
                            "wasm aot: sync compiled %s in %lld ms\n",
                            path.c_str(),
                            (long long)syncMs);
                }
                else
                {
                    fprintf(stderr,
                            "wasm aot: sync compile failed, booting interp\n");
                }
            }
        }
    }
#if WASM_ENABLE_PRELINKED_AOT != 0
    // Offline-compiled code linked into this binary; the only AOT shape on
    // platforms without runtime executable memory. The file lanes above never
    // fire there, but an explicit artifact still wins if one appears.
    const PrelinkedAotModule* prelinked =
        haveAot || haveHwAot || haveO0Aot
            ? nullptr
            : findPrelinkedAotModule(moduleKey, m_moduleBytes.size());
    if (prelinked != nullptr)
    {
        moduleKey ^= 0x94d049bb133111ebull;
    }
#endif
    if (haveAot || haveHwAot || haveO0Aot)
    {
        moduleKey ^= 0x9e3779b97f4a7c15ull;
    }
    if (haveHwAot)
    {
        // Distinct key: hw and sw artifacts of the same bytes must never
        // share a cached module, the flag below lives on the module.
        moduleKey ^= 0xc2b2ae3d27d4eb4full;
    }
    if (haveO0Aot)
    {
        // Same rule for the -O0 species: its cached module reports aotO0
        // so later VMs still schedule the -O3 upgrade.
        moduleKey ^= 0x27d4eb2f165667c5ull;
    }
    auto& cache = sharedModuleCache();
    auto adoptCached = [&](SharedWasmModule& entry) {
        m_state->module = entry.module;
        m_state->ownsModule = false;
        m_tier = entry.tier;
        // The VM's own copy is redundant against the cache entry, but the
        // tier ladder still needs the pristine bytes; entries live for the
        // process.
        m_scheduleBytes = Span<const uint8_t>(entry.pristineBytes.data(),
                                              entry.pristineBytes.size());
        m_moduleBytes.clear();
    };
    bool adoptedFromCache = false;
    auto cached = cache.find(moduleKey);
    if (cached != cache.end())
    {
        adoptCached(cached->second);
        adoptedFromCache = true;
    }
    else
    {
        if (haveAot || haveHwAot || haveO0Aot)
        {
            if (FILE* aot = fopen(aotPath, "rb"))
            {
                fseek(aot, 0, SEEK_END);
                long size = ftell(aot);
                fseek(aot, 0, SEEK_SET);
                m_moduleBytes.resize(size);
                size_t read = fread(m_moduleBytes.data(), 1, size, aot);
                fclose(aot);
                fprintf(stderr,
                        "wasm aot: loaded %s (%zu bytes)\n",
                        aotPath,
                        read);
                m_tier =
                    haveO0Aot ? ExecutionTier::aotO0 : ExecutionTier::aotO3;
            }
        }
#if WASM_ENABLE_PRELINKED_AOT != 0
        if (prelinked != nullptr)
        {
            m_state->module =
                loadPrelinkedModule(*prelinked, error, sizeof(error));
            if (m_state->module != nullptr)
            {
                m_tier = ExecutionTier::aotO3;
                fprintf(stderr,
                        "wasm aot: prelinked module %016llx (%zu byte text)\n",
                        (unsigned long long)m_moduleKey,
                        prelinked->textSize);
            }
            else
            {
                // A stale or incompatible bake must not fail the file; drop
                // to the wasm bytes under the plain key.
                fprintf(stderr,
                        "wasm aot: prelinked module rejected (%s); "
                        "falling back\n",
                        error);
                prelinked = nullptr;
                moduleKey ^= 0x94d049bb133111ebull;
                auto fallback = cache.find(moduleKey);
                if (fallback != cache.end())
                {
                    adoptCached(fallback->second);
                    adoptedFromCache = true;
                }
            }
        }
        if (m_state->module == nullptr)
#endif
        {
            if (!haveAot && !haveHwAot && !haveO0Aot)
            {
                // The load below rewrites the buffer in place; wamrc needs
                // the module as it is now.
                ModuleTierLadder::instance().stagePristine(
                    m_moduleKey,
                    Span<const uint8_t>(m_moduleBytes.data(),
                                        m_moduleBytes.size()));
            }
            m_state->module = wasm_runtime_load(m_moduleBytes.data(),
                                                (uint32_t)m_moduleBytes.size(),
                                                error,
                                                sizeof(error));
        }
        if (m_state->module != nullptr && !adoptedFromCache)
        {
            if (haveHwAot)
            {
                wasm_runtime_set_module_hw_bounds(m_state->module, true);
            }
            SharedWasmModule entry;
            entry.bytes = std::move(m_moduleBytes);
            entry.pristineBytes = std::move(pristineBytes);
            entry.module = m_state->module;
            entry.tier = m_tier;
            auto inserted = cache.emplace(moduleKey, std::move(entry));
            m_state->ownsModule = false;
            m_scheduleBytes = Span<const uint8_t>(
                inserted.first->second.pristineBytes.data(),
                inserted.first->second.pristineBytes.size());
        }
    }
    if (m_state->module == nullptr)
    {
        m_lastError = std::string("module load failed: ") + error;
        return false;
    }
    // Unresolved function imports link fine and trap only when first called,
    // with no diagnostic; report them here where the failure is actionable.
    int32_t importCount = wasm_runtime_get_import_count(m_state->module);
    for (int32_t i = 0; i < importCount; i++)
    {
        wasm_import_t import;
        wasm_runtime_get_import_type(m_state->module, i, &import);
        if (import.kind == WASM_IMPORT_EXPORT_KIND_FUNC && !import.linked)
        {
            m_unresolvedImports.push_back(std::string(import.module_name) +
                                          "." + import.name);
        }
    }
    // Read off the module, not the instance: module start runs every
    // script's top level, which already passes strings.
    int32_t exportCount = wasm_runtime_get_export_count(m_state->module);
    for (int32_t i = 0; i < exportCount; i++)
    {
        wasm_export_t moduleExport;
        wasm_runtime_get_export_type(m_state->module, i, &moduleExport);
        m_utf16Strings |= strcmp(moduleExport.name, "__riveUtf16Strings") == 0;
        m_utf16HostStrings |=
            strcmp(moduleExport.name, "__riveUtf16HostStrings") == 0;
        m_hostBudget |= strcmp(moduleExport.name, "__riveHostBudget") == 0;
    }
    s_bootPrint = &m_print;
    s_booting = this;
    // Module start is a call into the module like any other: the top
    // level's probes need the bracket, and its trap is the instantiate
    // error.
    if (m_debugHooks != nullptr)
    {
        m_debugHooks->onCallBegin(*this);
    }
    m_state->instance = wasm_runtime_instantiate(m_state->module,
                                                 512 * 1024,
                                                 0,
                                                 error,
                                                 sizeof(error));
    if (m_debugHooks != nullptr)
    {
        m_debugHooks->onCallEnd(*this,
                                m_state->instance == nullptr ? error : nullptr);
    }
    s_booting = nullptr;
    s_bootPrint = nullptr;
    if (m_state->instance == nullptr)
    {
        m_lastError = std::string("module instantiate failed: ") + error;
        return false;
    }
    m_state->execEnv =
        wasm_runtime_create_exec_env(m_state->instance, 512 * 1024);
    if (m_state->execEnv == nullptr)
    {
        m_lastError = "exec env creation failed";
        return false;
    }
    wasm_runtime_set_user_data(m_state->execEnv, this);

    // The leak watch for rasc-linked modules (riveRegister marks one): the
    // stub baseline never frees, and sustained growth on a collecting
    // module is references accumulating.
    const char* leakEnv = getenv("RIVE_WASM_LEAK_WARN");
    m_leakWatch = wasm_runtime_lookup_function(m_state->instance,
                                               "riveRegister") != nullptr &&
                  (leakEnv == nullptr || strcmp(leakEnv, "0") != 0);
    m_collectedRuntime =
        wasm_runtime_lookup_function(m_state->instance, "__riveCollected") !=
        nullptr;
    m_handleWatch = wasm_runtime_lookup_function(m_state->instance,
                                                 "riveRegister") != nullptr &&
                    (leakEnv == nullptr || strcmp(leakEnv, "0") != 0);
    // Frame collector modules scavenge at every boundary instead of
    // rewinding or finalizing.
    m_frameMinor = wasm_runtime_lookup_function(m_state->instance,
                                                "__riveFrameMinor") != nullptr;
    m_frameMajorsProbe =
        wasm_runtime_lookup_function(m_state->instance, "__riveFrameMajors") !=
        nullptr;
    // Stub modules report their bump position, finer than page counts.
    m_heapUsedProbe = wasm_runtime_lookup_function(m_state->instance,
                                                   "__riveHeapUsed") != nullptr;

    callModule("__wasm_call_ctors", 0, nullptr);
    m_L = callModule("host_newstate", 0, nullptr);
    if (m_L == 0)
    {
        m_lastError = "host_newstate failed";
        return false;
    }
    uint32_t largs[1] = {m_L};
    // Same execution budget as the Luau backend's timed pcall.
    uint32_t timeoutArgs[2] = {m_L, (uint32_t)m_timeoutMs};
    callModule("host_set_timeout", 2, timeoutArgs);
    callModule("host_install_require", 1, largs);
    callModule("host_install_rive_math", 1, largs);
    callModule("host_install_rive_input", 1, largs);
    callModule("host_install_rive_renderer", 1, largs);
    callModule("host_install_rive_data", 1, largs);
    callModule("host_install_rive_gpu", 1, largs);
    // Last like the Luau backend's lualibs order, and before host_seal_env
    // so the Promise/async/await globals do not clear the safe-env flag.
    callModule("host_install_rive_promise", 1, largs);
    m_embeddedModules = (int)callModule("host_register_embedded", 1, largs);
    callModule("host_seal_env", 1, largs);
    return true;
}

void WasmScriptingVM::scheduleTierCompiles(const std::string& laneId)
{
    auto& ladder = ModuleTierLadder::instance();
    if (!ladder.enabled() || m_tier == ExecutionTier::aotO3 || m_tierPinned)
    {
        return;
    }
    Span<const uint8_t> bytes = m_scheduleBytes;
    if (bytes.size() == 0)
    {
        bytes = Span<const uint8_t>(m_moduleBytes.data(), m_moduleBytes.size());
    }
    if (bytes.size() == 0)
    {
        return;
    }
    ladder.schedule(laneId, m_moduleKey, bytes);
}

bool WasmScriptingVM::maybeUpgradeTier()
{
    auto& ladder = ModuleTierLadder::instance();
    if (!ladder.enabled() || m_tier == ExecutionTier::aotO3 || m_tierPinned)
    {
        return false;
    }
    ExecutionTier target = ExecutionTier::aotO3;
    bool hwBounds = false;
    std::string path;
#ifdef RIVE_WASM_HW_BOUNDS
    path = ladder.artifactPath(m_moduleKey, TierSpecies::hw);
    hwBounds = !path.empty();
#endif
    if (path.empty())
    {
        path = ladder.artifactPath(m_moduleKey, TierSpecies::o3);
    }
    if (path.empty() && m_tier < ExecutionTier::aotO0)
    {
        target = ExecutionTier::aotO0;
        path = ladder.artifactPath(m_moduleKey, TierSpecies::o0);
    }
    if (path.empty())
    {
        return false;
    }
    FILE* f = fopen(path.c_str(), "rb");
    if (f == nullptr)
    {
        return false;
    }
    fseek(f, 0, SEEK_END);
    long size = ftell(f);
    fseek(f, 0, SEEK_SET);
    std::vector<uint8_t> artifact(size);
    size_t read = fread(artifact.data(), 1, size, f);
    fclose(f);
    if (read != (size_t)size)
    {
        return false;
    }
    std::string error;
    if (!applyTierArtifact(
            Span<const uint8_t>(artifact.data(), artifact.size()),
            target,
            error,
            hwBounds))
    {
        fprintf(stderr, "wasm tier swap failed: %s\n", error.c_str());
        return false;
    }
    return true;
}

const char* WasmScriptingVM::frameBoundary()
{
    if (!valid())
    {
        return nullptr;
    }
    if (m_frameMinor)
    {
        uint32_t promoted = callModule("__riveFrameMinor", 0, nullptr);
        if (getenv("RIVE_FRAME_GC_DEBUG") != nullptr)
        {
            fprintf(stderr, "frameMinor promoted=%u\n", promoted);
            callModule("__riveFrameVerify", 0, nullptr);
        }
        if (!m_frameMinorAnnounced)
        {
            m_frameMinorAnnounced = true;
            return "script frame gc: scavenging per frame";
        }
        if (const char* warning = handleLeakWarning())
        {
            return warning;
        }
        return heapGrowthWarning();
    }
    if (const char* warning = handleLeakWarning())
    {
        return warning;
    }
    return heapGrowthWarning();
}

const char* WasmScriptingVM::heapGrowthWarning()
{
    if (!m_leakWatch || !m_advancedOnce)
    {
        return nullptr;
    }
    wasm_memory_inst_t memory =
        wasm_runtime_get_default_memory(m_state->instance);
    if (memory == nullptr)
    {
        return nullptr;
    }
    // The stub bump position beats page counts when available.
    uint32_t pages =
        m_heapUsedProbe
            ? std::max(1u, callModule("__riveHeapUsed", 0, nullptr) >> 16)
            : (uint32_t)wasm_memory_get_cur_page_count(memory);
    if (m_leakBaselinePages == 0)
    {
        m_leakBaselinePages = pages;
        m_leakFirstBaselinePages = pages;
        return nullptr;
    }
    m_leakFrames++;
    m_leakTotalFrames++;
    // 8MB past baseline over at least two seconds of frames: far beyond any
    // one-time warmup we have measured, reached in seconds by a per-frame
    // leak (box2d hand-optimized leaked ~2.1MB/s). The watch re-arms after
    // each warning, so a leaking session keeps hearing about it every 8MB
    // instead of dying hours after a single line scrolled away.
    constexpr uint32_t kLeakWarnPages = 128;
    constexpr uint32_t kLeakWarnMinFrames = 120;
    if (m_leakFrames < kLeakWarnMinFrames ||
        pages < m_leakBaselinePages + kLeakWarnPages)
    {
        return nullptr;
    }
    if (m_collectedRuntime && !m_leakArmedCollected)
    {
        // Linear memory never shrinks, so a collected runtime's one-time
        // spike would read as growth forever. Demand a second growing
        // window before the first warning.
        m_leakArmedCollected = true;
        m_leakBaselinePages = pages;
        m_leakFrames = 0;
        return nullptr;
    }
    uint32_t grownMB = (pages - m_leakBaselinePages) / 16;
    uint32_t frames = m_leakFrames;
    m_leakBaselinePages = pages;
    m_leakFrames = 0;
    m_leakWarningCount++;

    // Time to the wasmMaxPages trap from the average growth rate at 60fps.
    // Growth arrives in page-doubling steps, so this is an estimate.
    char projection[96] = {0};
    uint32_t maxPages = (uint32_t)wasm_memory_get_max_page_count(memory);
    double pagesPerFrame =
        (double)(pages - m_leakFirstBaselinePages) / (double)m_leakTotalFrames;
    if (maxPages > pages && pagesPerFrame > 0.0)
    {
        double minutes =
            (double)(maxPages - pages) / pagesPerFrame / (60.0 * 60.0);
        snprintf(projection,
                 sizeof(projection),
                 "; at this rate every frame traps in roughly %.0f minutes",
                 minutes < 1.0 ? 1.0 : minutes);
    }
    char buffer[384];
    if (m_collectedRuntime)
    {
        snprintf(buffer,
                 sizeof(buffer),
                 "script heap grew %uMB over %u frames%s; the collector is "
                 "running, so something is accumulating references (a "
                 "growing array, map, or cache). RIVE_WASM_LEAK_WARN=0 "
                 "silences this.",
                 grownMB,
                 frames,
                 projection);
    }
    else
    {
        snprintf(buffer,
                 sizeof(buffer),
                 "script heap grew %uMB over %u frames%s; the stub runtime "
                 "never frees, so per-frame allocations leak. Set "
                 "wasmRuntime: frame. RIVE_WASM_LEAK_WARN=0 silences this.",
                 grownMB,
                 frames,
                 projection);
    }
    m_leakWarning = buffer;
    return m_leakWarning.c_str();
}

static const char* handleTagName(WasmScriptingVM::HandleTable::Tag tag)
{
    using Tag = WasmScriptingVM::HandleTable::Tag;
    switch (tag)
    {
        case Tag::path:
            return "path";
        case Tag::measure:
            return "measure";
        case Tag::paint:
            return "paint";
        case Tag::renderer:
            return "renderer";
        case Tag::shader:
            return "shader";
        case Tag::object:
            return "object";
        case Tag::viewModelInstance:
            return "viewModelInstance";
        case Tag::instanceValue:
            return "instanceValue";
        case Tag::image:
            return "image";
        case Tag::font:
            return "font";
        case Tag::text:
            return "text";
        case Tag::buffer:
            return "buffer";
        case Tag::meshInstances:
            return "meshInstances";
        case Tag::canvas:
            return "canvas";
        case Tag::gpuCanvas:
            return "gpuCanvas";
        case Tag::gpuPass:
            return "gpuPass";
        case Tag::gpuBuffer:
            return "gpuBuffer";
        case Tag::gpuTexture:
            return "gpuTexture";
        case Tag::gpuSampler:
            return "gpuSampler";
        case Tag::gpuTextureView:
            return "gpuTextureView";
        case Tag::gpuShaderModule:
            return "gpuShaderModule";
        case Tag::gpuBindGroupLayout:
            return "gpuBindGroupLayout";
        case Tag::gpuBindGroup:
            return "gpuBindGroup";
        case Tag::gpuPipeline:
            return "gpuPipeline";
        case Tag::dataContext:
            return "dataContext";
        case Tag::artboard:
            return "artboard";
        case Tag::animation:
            return "animation";
        case Tag::node:
            return "node";
        case Tag::audioSource:
            return "audioSource";
        case Tag::audioSound:
            return "audioSound";
        case Tag::drawable:
            return "drawable";
        case Tag::empty:
        case Tag::count:
            break;
    }
    return "unknown";
}

uint32_t WasmScriptingVM::memoryPages() const
{
    if (m_state == nullptr || m_state->instance == nullptr)
    {
        return 0;
    }
    wasm_memory_inst_t memory =
        wasm_runtime_get_default_memory(m_state->instance);
    return memory == nullptr ? 0
                             : (uint32_t)wasm_memory_get_cur_page_count(memory);
}

uint32_t WasmScriptingVM::frameMajors()
{
    return m_frameMajorsProbe ? callModule("__riveFrameMajors", 0, nullptr) : 0;
}

const char* WasmScriptingVM::handleLeakWarning()
{
    if (!m_handleWatch || !m_advancedOnce)
    {
        return nullptr;
    }
    uint32_t live =
        (uint32_t)(m_handles.slots.size() - m_handles.freeSlots.size());
    if (m_handleBaselineLive == 0)
    {
        // Bias by one so a zero-handle module still records its baseline.
        m_handleBaselineLive = live + 1;
        return nullptr;
    }
    m_handleFrames++;
    // Hundreds of handles past warmup over two seconds of frames is a
    // per-frame mint with no release, not a working set.
    constexpr uint32_t kHandleWarnCount = 512;
    constexpr uint32_t kHandleWarnMinFrames = 120;
    if (live + 1 < m_handleBaselineLive + kHandleWarnCount)
    {
        m_handleCollectPending = false;
        return nullptr;
    }
    if (m_handleFrames < kHandleWarnMinFrames)
    {
        return nullptr;
    }
    // Wrappers that outlived a boundary die in the old region, which only
    // a major sweeps, and its size trigger cannot see the host side of a
    // handle. Ask for one and only warn if the growth survives it. A bake
    // without the majors counter cannot say when that is, so it stays quiet.
    if (m_collectedRuntime && !m_frameMajorsProbe)
    {
        return nullptr;
    }
    if (m_collectedRuntime && !m_handleCollectPending)
    {
        m_handleCollectPending = true;
        m_handleCollectMajors = frameMajors();
        callModule("__riveCollect", 0, nullptr);
        return nullptr;
    }
    // A sliced major spans boundaries, so wait for the count to move.
    if (m_handleCollectPending && frameMajors() == m_handleCollectMajors)
    {
        return nullptr;
    }
    m_handleCollectPending = false;
    // Re-arm so a leaking session keeps warning every 512 handles.
    uint32_t grown = live + 1 - m_handleBaselineLive;
    uint32_t frames = m_handleFrames;
    m_handleBaselineLive = live + 1;
    m_handleFrames = 0;
    uint32_t counts[(size_t)HandleTable::Tag::count] = {0};
    for (const HandleTable::Slot& slot : m_handles.slots)
    {
        if (slot.tag != HandleTable::Tag::empty)
        {
            counts[(size_t)slot.tag]++;
        }
    }
    size_t top = 0;
    for (size_t i = 1; i < sizeof(counts) / sizeof(counts[0]); i++)
    {
        if (counts[i] > counts[top])
        {
            top = i;
        }
    }
    char buffer[256];
    snprintf(buffer,
             sizeof(buffer),
             "script leaked %u host handles over %u frames (most: %u %s); "
             "resources created per frame need release() or finish(). "
             "RIVE_WASM_LEAK_WARN=0 silences this.",
             grown,
             frames,
             counts[top],
             handleTagName((HandleTable::Tag)top));
    m_leakWarning = buffer;
    return m_leakWarning.c_str();
}

bool WasmScriptingVM::applyTierArtifact(Span<const uint8_t> artifactBytes,
                                        ExecutionTier tier,
                                        std::string& error,
                                        bool hwBounds)
{
    auto next = std::make_unique<WamrState>();
    next->artifactBytes.assign(artifactBytes.begin(), artifactBytes.end());
    char loadError[256] = {0};
    next->module = wasm_runtime_load(next->artifactBytes.data(),
                                     (uint32_t)next->artifactBytes.size(),
                                     loadError,
                                     sizeof(loadError));
    if (next->module == nullptr)
    {
        error = std::string("artifact load failed: ") + loadError;
        return false;
    }
    if (hwBounds)
    {
        wasm_runtime_set_module_hw_bounds(next->module, true);
    }
    next->instance = wasm_runtime_instantiate(next->module,
                                              512 * 1024,
                                              0,
                                              loadError,
                                              sizeof(loadError));
    if (next->instance == nullptr)
    {
        error = std::string("artifact instantiate failed: ") + loadError;
        return false;
    }
    // No ctors on the target: every byte of initialized state arrives from
    // the live instance.
    if (!wamrTransplantState(m_state->instance, next->instance, error))
    {
        return false;
    }
    next->execEnv = wasm_runtime_create_exec_env(next->instance, 512 * 1024);
    if (next->execEnv == nullptr)
    {
        error = "artifact exec env creation failed";
        return false;
    }
    wasm_runtime_set_user_data(next->execEnv, this);
    next->guestNames = std::move(m_state->guestNames);
    m_state = std::move(next);
    m_tier = tier;
    return true;
}

bool WasmScriptingVM::registerBytecode(const std::string& name,
                                       Span<const uint8_t> bytecode)
{
    uint32_t nameSizeArgs[1] = {(uint32_t)name.size() + 1};
    uint32_t namePtr = callModule("malloc", 1, nameSizeArgs);
    uint32_t bcSizeArgs[1] = {(uint32_t)bytecode.size()};
    uint32_t bcPtr = callModule("malloc", 1, bcSizeArgs);
    if (namePtr == 0 || bcPtr == 0)
    {
        m_lastError = "bytecode allocation failed";
        return false;
    }
    memcpy(resolveModulePtr(namePtr, (uint32_t)name.size() + 1),
           name.c_str(),
           name.size() + 1);
    memcpy(resolveModulePtr(bcPtr, (uint32_t)bytecode.size()),
           bytecode.data(),
           bytecode.size());

    uint32_t args[4] = {m_L, namePtr, bcPtr, (uint32_t)bytecode.size()};
    callModule("host_register_module", 4, args);

    uint32_t freeName[1] = {namePtr};
    callModule("free", 1, freeName);
    // The registry keeps its own copy via lua_pushlstring; the staging
    // buffer frees.
    uint32_t freeBc[1] = {bcPtr};
    callModule("free", 1, freeBc);
    return true;
}

#ifdef WITH_RIVE_TOOLS
void WasmScriptingVM::registerShaderRstb(std::string name,
                                         std::vector<uint8_t> bytes)
{
    m_shaderRstbs[std::move(name)] = std::move(bytes);
}

const std::vector<uint8_t>* WasmScriptingVM::findShaderRstb(
    const std::string& name) const
{
    auto it = m_shaderRstbs.find(name);
    if (it != m_shaderRstbs.end())
    {
        return &it->second;
    }
    // Registered names are library-mangled paths; scripts ask by short name.
    for (const auto& entry : m_shaderRstbs)
    {
        size_t slash = entry.first.rfind('/');
        if (slash != std::string::npos && entry.first.substr(slash + 1) == name)
        {
            return &entry.second;
        }
    }
    return nullptr;
}
#endif

bool WasmScriptingVM::requireModule(const std::string& name, int* outResultRef)
{
    uint32_t namePtr = guestString(name.c_str());
    if (namePtr == 0)
    {
        m_lastError = "module name allocation failed";
        return false;
    }

    uint32_t requireArgs[2] = {m_L, namePtr};
    uint32_t status = 0;
    CallOutcome outcome =
        callModuleChecked("host_require", 2, requireArgs, &status);

    guestFree(namePtr);

    if (outcome != CallOutcome::ok)
    {
        // Folding a trap into "status 0" once read as a successful require
        // with no generator; fail the require instead.
        m_lastError = outcome == CallOutcome::trapped
                          ? "module require trapped"
                          : "module has no host_require export";
        uint32_t topArgs[2] = {m_L, 0};
        callModule("host_settop", 2, topArgs);
        return false;
    }
    if (status != 0)
    {
        uint32_t strArgs[2] = {m_L, (uint32_t)-1};
        uint32_t messagePtr = callModule("host_tostring", 2, strArgs);
        const char* message = messagePtr != 0
                                  ? (const char*)resolveModulePtr(messagePtr, 1)
                                  : nullptr;
        m_lastError = message != nullptr ? message : "module execution failed";
    }
    else if (outResultRef != nullptr)
    {
        uint32_t refArgs[1] = {m_L};
        *outResultRef = (int)callModule("host_ref", 1, refArgs);
    }
    uint32_t topArgs[2] = {m_L, 0};
    callModule("host_settop", 2, topArgs);
    return status == 0;
}

// --- ScriptBackend over the module's host_obj_* exports ---------------------

bool WasmScriptingVM::valid() const
{
    return m_state != nullptr && m_state->execEnv != nullptr && m_L != 0 &&
           !m_poisoned;
}

void WasmScriptingVM::releaseRef(int ref)
{
    if (!valid() || ref == 0)
    {
        return;
    }
    auto it = m_contextObjects.find(ref);
    if (it != m_contextObjects.end())
    {
        m_handles.release(it->second, HandleTable::Tag::object);
        m_contextObjects.erase(it);
    }
    m_inputSlots.erase(ref);
    uint32_t args[2] = {m_L, (uint32_t)ref};
    // Listeners owned by this script instance stop immediately, mirroring the
    // Luau backend's tracked property dispose.
    callModule("host_obj_dispose", 2, args);
    callModule("host_unref", 2, args);
}

int WasmScriptingVM::instantiate(int generatorRef,
                                 ScriptedObject* object,
                                 int* outContextRef,
                                 ScriptedContext** outContextPtr)
{
    uint32_t objectHandle = m_handles.mint(HandleTable::Tag::object, object);
    uint32_t args[3] = {m_L, (uint32_t)generatorRef, objectHandle};
    int selfRef = (int)callModule("host_obj_instantiate", 3, args);
    if (selfRef == 0)
    {
        m_handles.release(objectHandle, HandleTable::Tag::object);
        return 0;
    }
    uint32_t contextArgs[1] = {m_L};
    *outContextRef = (int)callModule("host_obj_context", 1, contextArgs);
    if (*outContextRef != 0)
    {
        m_contextObjects[*outContextRef] = objectHandle;
    }
    else
    {
        m_handles.release(objectHandle, HandleTable::Tag::object);
    }
    // The wasm context lives entirely in the module until the binding layer
    // moves in; there is no host-side ScriptedContext.
    *outContextPtr = nullptr;
    return selfRef;
}

ScriptBackend::InitResult WasmScriptingVM::callUserInit(ScriptedObject* object,
                                                        int selfRef,
                                                        int contextRef)
{
    // callRet folds a trap into 0, which here would read as notImplemented
    // and mark a crashed init as done; call directly so failure is failure.
    wasm_function_inst_t f =
        wasm_runtime_lookup_function(m_state->instance, "host_obj_user_init");
    if (f == nullptr)
    {
        return InitResult::notImplemented;
    }
    uint32_t buf[3] = {m_L, (uint32_t)selfRef, (uint32_t)contextRef};
    uint32_t status = 2;
    // An init can run a nested one; each reads only its own misses.
    bool outerMissing = m_missingRequestedData;
    m_missingRequestedData = false;
    ScriptCallScope callScope(this);
    if (!wasm_runtime_call_wasm(m_state->execEnv, f, 3, buf))
    {
        const char* exception =
            fullTrapMessage(wasm_runtime_get_exception(m_state->instance));
        m_lastError = exception != nullptr ? exception : "script init trapped";
        fprintf(stderr, "script init trapped: %s\n", m_lastError.c_str());
#if WASM_ENABLE_DUMP_CALL_STACK
        wasm_runtime_dump_call_stack(m_state->execEnv);
#endif
        wasm_runtime_clear_exception(m_state->instance);
    }
    else
    {
        status = buf[0];
    }
    bool missing = m_missingRequestedData;
    m_missingRequestedData = outerMissing;
    switch (status)
    {
        case 0:
            return InitResult::notImplemented;
        case 1:
            return missing ? InitResult::failed : InitResult::succeeded;
        default:
            return InitResult::failed;
    }
}

bool WasmScriptingVM::callAdvance(ScriptedObject* object,
                                  int selfRef,
                                  float elapsedSeconds)
{
    wasm_function_inst_t f =
        wasm_runtime_lookup_function(m_state->instance, "host_obj_advance");
    if (f == nullptr)
    {
        return false;
    }
    wasm_val_t args[3];
    args[0].kind = WASM_I32;
    args[0].of.i32 = (int32_t)m_L;
    args[1].kind = WASM_I32;
    args[1].of.i32 = selfRef;
    args[2].kind = WASM_F64;
    args[2].of.f64 = elapsedSeconds;
    wasm_val_t results[1];
    results[0].kind = WASM_I32;
    ScriptCallScope callScope(this);
    if (!wasm_runtime_call_wasm_a(m_state->execEnv, f, 1, results, 3, args))
    {
        reportTrap("host_obj_advance");
        return false;
    }
    if (!m_advancedOnce)
    {
        m_advancedOnce = true;
    }
    return results[0].of.i32 != 0;
}

void WasmScriptingVM::callUpdate(ScriptedObject* object, int selfRef)
{
    // Marks issued during update must not re-arm it, like the Luau backend.
    object->setInUpdatePhase(true);
    uint32_t args[2] = {m_L, (uint32_t)selfRef};
    callModule("host_obj_update", 2, args);
    object->setInUpdatePhase(false);
}

void WasmScriptingVM::callTrigger(ScriptedObject* object,
                                  int selfRef,
                                  const char* name)
{
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    uint32_t args[3] = {m_L, (uint32_t)selfRef, arg};
    callModule("host_obj_trigger", 3, args);
    guestFree(owned);
}

bool WasmScriptingVM::callNumberMethod(ScriptedObject* object,
                                       int selfRef,
                                       const char* name,
                                       const float* args,
                                       size_t argCount,
                                       float* outResult)
{
    GuestName nameCopy(this, name);
    uint32_t namePtr = nameCopy.ptr;
    if (namePtr == 0)
    {
        return false;
    }
    uint32_t scratchSize = (uint32_t)(argCount * sizeof(float)) + sizeof(float);
    uint32_t sizeArgs[1] = {scratchSize};
    uint32_t scratch = callModule("malloc", 1, sizeArgs);
    if (scratch == 0)
    {
        return false;
    }
    memcpy(resolveModulePtr(scratch, scratchSize),
           args,
           argCount * sizeof(float));
    uint32_t outPtr = scratch + (uint32_t)(argCount * sizeof(float));
    uint32_t callArgs[6] =
        {m_L, (uint32_t)selfRef, namePtr, scratch, (uint32_t)argCount, outPtr};
    uint32_t ok = callModule("host_obj_number_method", 6, callArgs);
    if (ok != 0)
    {
        memcpy(outResult,
               resolveModulePtr(outPtr, sizeof(float)),
               sizeof(float));
    }
    guestFree(scratch);
    return ok != 0;
}

bool WasmScriptingVM::callBooleanMethod(ScriptedObject* object,
                                        int selfRef,
                                        const char* name)
{
    GuestName nameCopy(this, name);
    uint32_t namePtr = nameCopy.ptr;
    if (namePtr == 0)
    {
        return false;
    }
    uint32_t args[3] = {m_L, (uint32_t)selfRef, namePtr};
    uint32_t result = callModule("host_obj_boolean_method", 3, args);
    return result != 0;
}

bool WasmScriptingVM::callPathEffectUpdate(ScriptedObject* object,
                                           int selfRef,
                                           const RawPath& sourcePath,
                                           const ShapePaint* shapePaint,
                                           RawPath* outPath)
{
    if (!valid() || shapePaint == nullptr || outPath == nullptr)
    {
        return false;
    }
    // The exact subset the Luau lane's ScriptedPaintData(ShapePaint*)
    // snapshot captures; gradients stay host side there too.
    PathEffectPaintWire paint;
    paint.style = (uint32_t)RenderPaintStyle::fill;
    paint.blendMode = (uint32_t)BlendMode::srcOver;
    paint.thickness = 1;
    paint.color = 0xFF000000;
    if (shapePaint->is<Stroke>())
    {
        auto stroke = shapePaint->as<Stroke>();
        paint.style = (uint32_t)RenderPaintStyle::stroke;
        paint.thickness = stroke->thickness();
        paint.cap = stroke->cap();
        paint.join = stroke->join();
    }
    for (auto& child : shapePaint->children())
    {
        if (child->is<SolidColor>())
        {
            paint.color = child->as<SolidColor>()->colorValue();
            break;
        }
    }
    if (shapePaint->feather() != nullptr)
    {
        paint.feather = shapePaint->feather()->strength();
    }
    paint.blendMode = (uint32_t)shapePaint->blendModeValue();

    uint32_t verbCount = (uint32_t)sourcePath.verbs().size();
    uint32_t floatCount = (uint32_t)sourcePath.points().size() * 2;
    uint32_t pointBytes = floatCount * (uint32_t)sizeof(float);
    // One staging block, float-aligned parts first: [paint][points][verbs].
    uint32_t byteCount = (uint32_t)sizeof(paint) + pointBytes + verbCount;
    uint32_t sizeArgs[1] = {byteCount};
    uint32_t dataPtr = callModule("malloc", 1, sizeArgs);
    if (dataPtr == 0)
    {
        return false;
    }
    uint8_t* out = (uint8_t*)resolveModulePtr(dataPtr, byteCount);
    memcpy(out, &paint, sizeof(paint));
    memcpy(out + sizeof(paint), sourcePath.points().data(), pointBytes);
    memcpy(out + sizeof(paint) + pointBytes,
           sourcePath.verbs().data(),
           verbCount);
    m_pathEffectOut = outPath;
    uint32_t args[7] = {m_L,
                        (uint32_t)selfRef,
                        dataPtr + (uint32_t)sizeof(paint) + pointBytes,
                        verbCount,
                        dataPtr + (uint32_t)sizeof(paint),
                        floatCount,
                        dataPtr};
    uint32_t ok = callModule("host_obj_path_effect", 7, args);
    m_pathEffectOut = nullptr;
    guestFree(dataPtr);
    return ok != 0;
}

bool WasmScriptingVM::callDataConvert(ScriptedObject* object,
                                      int selfRef,
                                      const char* method,
                                      DataValue* input,
                                      ScriptDataResult* outResult)
{
    if (!valid() || input == nullptr)
    {
        return false;
    }
    DataConvertWire wire;
    std::string text;
    if (input->is<DataValueNumber>())
    {
        wire.kind = DataConvertWire::kindNumber;
        wire.number = input->as<DataValueNumber>()->value();
    }
    else if (input->is<DataValueString>())
    {
        wire.kind = DataConvertWire::kindString;
        const std::string& value = input->as<DataValueString>()->value();
        text = moduleStringBytes(this, value.data(), value.size());
        wire.stringLength = (uint32_t)text.size();
    }
    else if (input->is<DataValueBoolean>())
    {
        wire.kind = DataConvertWire::kindBoolean;
        wire.boolean = input->as<DataValueBoolean>()->value() ? 1 : 0;
    }
    else if (input->is<DataValueColor>())
    {
        wire.kind = DataConvertWire::kindColor;
        wire.color = input->as<DataValueColor>()->value();
    }
    else
    {
        // Unsupported input kinds report handled with no result, so the
        // converter yields an empty DataValue like the Luau backend.
        return true;
    }
    GuestName methodCopy(this, method);
    uint32_t methodPtr = methodCopy.ptr;
    if (methodPtr == 0)
    {
        return false;
    }
    uint32_t byteCount = (uint32_t)sizeof(wire) + wire.stringLength;
    uint32_t sizeArgs[1] = {byteCount};
    uint32_t wirePtr = callModule("malloc", 1, sizeArgs);
    if (wirePtr == 0)
    {
        return false;
    }
    uint8_t* out = (uint8_t*)resolveModulePtr(wirePtr, byteCount);
    memcpy(out, &wire, sizeof(wire));
    memcpy(out + sizeof(wire), text.data(), wire.stringLength);
    m_convertResultOut = outResult;
    uint32_t args[4] = {m_L, (uint32_t)selfRef, methodPtr, wirePtr};
    uint32_t ran = callModule("host_obj_data_convert", 4, args);
    m_convertResultOut = nullptr;
    guestFree(wirePtr);
    return ran != 0;
}

bool WasmScriptingVM::callPointerEvent(ScriptedObject* object,
                                       int selfRef,
                                       const char* method,
                                       int pointerId,
                                       Vec2D localPosition,
                                       ListenerType hitType,
                                       float timeStamp,
                                       HitResult* outResult)
{
    // Not forwarded yet: host_obj_pointer_event's guest ABI has no slots.
    (void)hitType;
    (void)timeStamp;
    if (!valid())
    {
        return false;
    }
    wasm_function_inst_t f =
        wasm_runtime_lookup_function(m_state->instance,
                                     "host_obj_pointer_event");
    if (f == nullptr)
    {
        return false;
    }
    GuestName methodCopy(this, method);
    uint32_t methodPtr = methodCopy.ptr;
    if (methodPtr == 0)
    {
        return false;
    }
    wasm_val_t args[6];
    args[0].kind = WASM_I32;
    args[0].of.i32 = (int32_t)m_L;
    args[1].kind = WASM_I32;
    args[1].of.i32 = selfRef;
    args[2].kind = WASM_I32;
    args[2].of.i32 = (int32_t)methodPtr;
    args[3].kind = WASM_I32;
    args[3].of.i32 = pointerId;
    args[4].kind = WASM_F64;
    args[4].of.f64 = localPosition.x;
    args[5].kind = WASM_F64;
    args[5].of.f64 = localPosition.y;
    wasm_val_t results[1];
    results[0].kind = WASM_I32;
    ScriptCallScope callScope(this);
    if (!wasm_runtime_call_wasm_a(m_state->execEnv, f, 1, results, 6, args))
    {
        reportTrap("host_obj_pointer_event");
        return false;
    }
    if (results[0].of.i32 == 0)
    {
        return false;
    }
    *outResult = (HitResult)(results[0].of.i32 - 1);
    return true;
}

bool WasmScriptingVM::callKeyboardEvent(ScriptedObject* object,
                                        int selfRef,
                                        Key key,
                                        KeyModifiers modifiers,
                                        bool isPressed,
                                        bool isRepeat)
{
    if (!valid())
    {
        return false;
    }
    uint32_t args[6] = {m_L,
                        (uint32_t)selfRef,
                        (uint32_t)key,
                        (uint32_t)modifiers,
                        isPressed ? 1u : 0u,
                        isRepeat ? 1u : 0u};
    return callModule("host_obj_keyboard_event", 6, args) != 0;
}

bool WasmScriptingVM::callTextEvent(ScriptedObject* object,
                                    int selfRef,
                                    const std::string& text)
{
    if (!valid())
    {
        return false;
    }
    // Length crosses explicitly, so embedded nulls survive.
    std::string bytes = moduleStringBytes(this, text.data(), text.size());
    uint32_t sizeArgs[1] = {(uint32_t)bytes.size() + 1};
    uint32_t textPtr = callModule("malloc", 1, sizeArgs);
    if (textPtr == 0)
    {
        return false;
    }
    memcpy(resolveModulePtr(textPtr, (uint32_t)bytes.size() + 1),
           bytes.data(),
           bytes.size());
    uint32_t args[4] = {m_L,
                        (uint32_t)selfRef,
                        textPtr,
                        (uint32_t)bytes.size()};
    uint32_t result = callModule("host_obj_text_event", 4, args);
    guestFree(textPtr);
    return result != 0;
}

// Flattens the gamepad alternatives into the wire layout the module rebuilds
// snapshots from; false for non-gamepad kinds. Shared by callGamepadEvent and
// callListenerPerform.
static bool packGamepadWire(const ListenerInvocation& invocation,
                            GamepadWire& wire,
                            const GamepadSnapshot*& snapshot)
{
    if (const GamepadConnectedInvocation* c = invocation.asGamepadConnected())
    {
        wire.kind = GamepadWire::kindConnected;
        snapshot = &c->snapshot;
    }
    else if (const GamepadEventInvocation* e = invocation.asGamepadEvent())
    {
        wire.kind = GamepadWire::kindEvent;
        snapshot = &e->fullState;
        wire.changeKind = (uint32_t)e->change.kind;
        wire.changeIndex = e->change.index;
        wire.changeValue = e->change.value;
        wire.hasStandardButtonIntent = e->hasStandardButtonIntent ? 1 : 0;
        wire.standardButton = (uint32_t)e->standardButton;
        wire.hasStandardAxisIntent = e->hasStandardAxisIntent ? 1 : 0;
        wire.standardAxis = (uint32_t)e->standardAxis;
    }
    else if (const GamepadDisconnectedInvocation* d =
                 invocation.asGamepadDisconnected())
    {
        wire.kind = GamepadWire::kindDisconnected;
        wire.deviceId = d->deviceId;
    }
    else
    {
        return false;
    }
    if (snapshot != nullptr)
    {
        wire.deviceId = snapshot->deviceId;
        wire.mapping = (uint32_t)snapshot->mapping;
        wire.buttonMaskLo = (uint32_t)snapshot->buttonMask;
        wire.buttonMaskHi = (uint32_t)(snapshot->buttonMask >> 32);
        wire.buttonCount = (uint32_t)snapshot->buttonValues.size();
        wire.axisCount = (uint32_t)snapshot->axes.size();
    }
    return true;
}

static void writeGamepadPayload(uint8_t* out,
                                const GamepadWire& wire,
                                const GamepadSnapshot* snapshot)
{
    memcpy(out, &wire, sizeof(wire));
    if (snapshot == nullptr)
    {
        return;
    }
    float* values = (float*)(out + sizeof(wire));
    if (wire.buttonCount != 0)
    {
        memcpy(values,
               snapshot->buttonValues.data(),
               wire.buttonCount * sizeof(float));
    }
    if (wire.axisCount != 0)
    {
        memcpy(values + wire.buttonCount,
               snapshot->axes.data(),
               wire.axisCount * sizeof(float));
    }
}

bool WasmScriptingVM::callGamepadEvent(ScriptedObject* object,
                                       int selfRef,
                                       const char* method,
                                       const ListenerInvocation& invocation)
{
    if (!valid())
    {
        return false;
    }
    GamepadWire wire;
    const GamepadSnapshot* snapshot = nullptr;
    if (!packGamepadWire(invocation, wire, snapshot))
    {
        return false;
    }
    GuestName methodCopy(this, method);
    uint32_t methodPtr = methodCopy.ptr;
    if (methodPtr == 0)
    {
        return false;
    }
    uint32_t byteCount =
        (uint32_t)(sizeof(wire) +
                   (wire.buttonCount + wire.axisCount) * sizeof(float));
    uint32_t sizeArgs[1] = {byteCount};
    uint32_t dataPtr = callModule("malloc", 1, sizeArgs);
    if (dataPtr == 0)
    {
        return false;
    }
    writeGamepadPayload((uint8_t*)resolveModulePtr(dataPtr, byteCount),
                        wire,
                        snapshot);
    uint32_t args[5] = {m_L, (uint32_t)selfRef, methodPtr, dataPtr, byteCount};
    uint32_t result = callModule("host_obj_gamepad_event", 5, args);
    guestFree(dataPtr);
    return result != 0;
}

void WasmScriptingVM::callListenerPerform(ScriptedObject* object,
                                          int selfRef,
                                          const ListenerInvocation& invocation)
{
    if (!valid())
    {
        return;
    }
    ListenerWire wire;
    wire.kind = (uint32_t)invocation.kind();
    std::string textBytes;
    const std::string* text = nullptr;
    GamepadWire gamepad;
    const GamepadSnapshot* snapshot = nullptr;
    bool hasGamepad = false;
    if (const PointerInvocation* p = invocation.asPointer())
    {
        wire.posX = p->position.x;
        wire.posY = p->position.y;
        wire.prevX = p->previousPosition.x;
        wire.prevY = p->previousPosition.y;
        wire.pointerId = p->pointerId;
        wire.hitEvent = (uint32_t)p->hitEvent;
        wire.timeStamp = p->timeStamp;
    }
    else if (const KeyboardInvocation* k = invocation.asKeyboard())
    {
        wire.key = (uint32_t)k->key;
        wire.modifiers = (uint32_t)k->modifiers;
        wire.isPressed = k->isPressed ? 1 : 0;
        wire.isRepeat = k->isRepeat ? 1 : 0;
    }
    else if (const TextInputInvocation* t = invocation.asTextInput())
    {
        textBytes = moduleStringBytes(this, t->text.data(), t->text.size());
        text = &textBytes;
        wire.textLength = (uint32_t)textBytes.size();
    }
    else if (const FocusInvocation* f = invocation.asFocus())
    {
        wire.isFocus = f->isFocus ? 1 : 0;
    }
    else if (const ReportedEventInvocation* e = invocation.asReportedEvent())
    {
        wire.delaySeconds = e->delaySeconds;
    }
    else if (const SemanticInvocation* s = invocation.asSemantic())
    {
        wire.semanticAction = (uint32_t)s->actionType;
    }
    else
    {
        // viewModelChange and none carry only their kind; the gamepad kinds
        // append their own payload.
        hasGamepad = packGamepadWire(invocation, gamepad, snapshot);
    }
    uint32_t tailBytes =
        text != nullptr
            ? wire.textLength
            : (hasGamepad ? (uint32_t)(sizeof(gamepad) + (gamepad.buttonCount +
                                                          gamepad.axisCount) *
                                                             sizeof(float))
                          : 0);
    uint32_t byteCount = (uint32_t)sizeof(wire) + tailBytes;
    uint32_t sizeArgs[1] = {byteCount};
    uint32_t dataPtr = callModule("malloc", 1, sizeArgs);
    if (dataPtr == 0)
    {
        return;
    }
    uint8_t* out = (uint8_t*)resolveModulePtr(dataPtr, byteCount);
    memcpy(out, &wire, sizeof(wire));
    if (text != nullptr)
    {
        memcpy(out + sizeof(wire), text->data(), wire.textLength);
    }
    else if (hasGamepad)
    {
        writeGamepadPayload(out + sizeof(wire), gamepad, snapshot);
    }
    uint32_t args[4] = {m_L, (uint32_t)selfRef, dataPtr, byteCount};
    callModule("host_obj_listener_perform", 4, args);
    guestFree(dataPtr);
}

// The transition protocol has no module-lane wire type for TransitionChild
// yet, so these hold the host-side defaults: the container composites nothing.
// Because callTransitionDraw below is a no-op, we must NOT claim to manage the
// incoming child -- otherwise it would be hidden from the normal draw loop for
// the duration of every transition and nothing at all would render.
bool WasmScriptingVM::transitionManagesTo(int selfRef) { return false; }

void WasmScriptingVM::callTransitionChanged(ScriptedObject* object,
                                            int selfRef,
                                            const TransitionChildRef& from,
                                            const TransitionChildRef& to,
                                            int direction)
{}

void WasmScriptingVM::callTransitionDraw(ScriptedObject* object,
                                         int selfRef,
                                         Renderer* renderer,
                                         const TransitionChildRef& from,
                                         const TransitionChildRef& to)
{}

void WasmScriptingVM::callLayoutResize(ScriptedObject* object,
                                       int selfRef,
                                       Vec2D size)
{
    if (!valid())
    {
        return;
    }
    // _v2 carries the surface scale; vm modules built before it export
    // only the four-argument name, which must be called as such.
    wasm_function_inst_t f =
        wasm_runtime_lookup_function(m_state->instance,
                                     "host_obj_layout_resize_v2");
    bool legacy = f == nullptr;
    if (legacy)
    {
        f = wasm_runtime_lookup_function(m_state->instance,
                                         "host_obj_layout_resize");
    }
    if (f == nullptr)
    {
        return;
    }
    wasm_val_t args[5];
    args[0].kind = WASM_I32;
    args[0].of.i32 = (int32_t)m_L;
    args[1].kind = WASM_I32;
    args[1].of.i32 = selfRef;
    args[2].kind = WASM_F64;
    args[2].of.f64 = size.x;
    args[3].kind = WASM_F64;
    args[3].of.f64 = size.y;
    args[4].kind = WASM_F64;
    args[4].of.f64 = displayScale();
    ScriptCallScope callScope(this);
    if (!wasm_runtime_call_wasm_a(m_state->execEnv,
                                  f,
                                  0,
                                  nullptr,
                                  legacy ? 4 : 5,
                                  args))
    {
        reportTrap("host_obj_layout_resize");
    }
}

bool WasmScriptingVM::callLayoutMeasure(ScriptedObject* object,
                                        int selfRef,
                                        Vec2D* outSize)
{
    if (!valid())
    {
        return false;
    }
    uint32_t sizeArgs[1] = {2 * sizeof(float)};
    uint32_t scratch = callModule("malloc", 1, sizeArgs);
    if (scratch == 0)
    {
        return false;
    }
    // Prefill so the module's error paths leave outSize untouched, like the
    // Luau backend.
    float* out = (float*)resolveModulePtr(scratch, 2 * sizeof(float));
    out[0] = outSize->x;
    out[1] = outSize->y;
    uint32_t args[3] = {m_L, (uint32_t)selfRef, scratch};
    uint32_t measured = callModule("host_obj_layout_measure", 3, args);
    if (measured != 0)
    {
        out = (float*)resolveModulePtr(scratch, 2 * sizeof(float));
        outSize->x = out[0];
        outSize->y = out[1];
    }
    guestFree(scratch);
    return measured != 0;
}

int32_t WasmScriptingVM::inputSlot(int selfRef, const char* name)
{
    auto& slots = m_inputSlots[selfRef];
    auto it = slots.find(name);
    if (it != slots.end())
    {
        return it->second;
    }
    int32_t slot = -1;
    uint32_t namePtr = guestString(name);
    if (namePtr != 0)
    {
        uint32_t args[3] = {m_L, (uint32_t)selfRef, namePtr};
        slot = (int32_t)callModule("host_obj_input_slot", 3, args);
        guestFree(namePtr);
    }
    slots.emplace(name, slot);
    return slot;
}

bool WasmScriptingVM::legacyInputs() const
{
    return wasm_runtime_lookup_function(m_state->instance,
                                        "host_obj_input_slot") == nullptr;
}

bool WasmScriptingVM::inputArg(int selfRef,
                               const char* name,
                               uint32_t& arg,
                               uint32_t& owned)
{
    owned = 0;
    if (legacyInputs())
    {
        owned = arg = guestString(name);
        return arg != 0;
    }
    int32_t slot = inputSlot(selfRef, name);
    if (slot < 0)
    {
        return false;
    }
    arg = (uint32_t)slot;
    return true;
}

void WasmScriptingVM::setInputBoolean(int selfRef, const char* name, bool value)
{
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    uint32_t args[4] = {m_L, (uint32_t)selfRef, arg, value ? 1u : 0u};
    callModule("host_obj_set_boolean", 4, args);
    guestFree(owned);
}

void WasmScriptingVM::setInputNumber(int selfRef, const char* name, float value)
{
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    wasm_function_inst_t f =
        wasm_runtime_lookup_function(m_state->instance, "host_obj_set_number");
    if (f != nullptr)
    {
        wasm_val_t args[4];
        args[0].kind = WASM_I32;
        args[0].of.i32 = (int32_t)m_L;
        args[1].kind = WASM_I32;
        args[1].of.i32 = selfRef;
        args[2].kind = WASM_I32;
        args[2].of.i32 = (int32_t)arg;
        args[3].kind = WASM_F64;
        args[3].of.f64 = value;
        ScriptCallScope callScope(this);
        if (!wasm_runtime_call_wasm_a(m_state->execEnv, f, 0, nullptr, 4, args))
        {
            reportTrap("host_obj_set_number");
        }
    }
    guestFree(owned);
}

void WasmScriptingVM::setInputUnsigned(int selfRef,
                                       const char* name,
                                       uint32_t value)
{
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    uint32_t args[4] = {m_L, (uint32_t)selfRef, arg, value};
    callModule(owned != 0 ? "host_obj_set_unsigned" : "host_obj_set_color",
               4,
               args);
    guestFree(owned);
}

void WasmScriptingVM::setInputString(int selfRef,
                                     const char* name,
                                     const char* value)
{
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    uint32_t valuePtr = guestString(value);
    if (valuePtr != 0)
    {
        uint32_t args[4] = {m_L, (uint32_t)selfRef, arg, valuePtr};
        callModule("host_obj_set_string", 4, args);
        guestFree(valuePtr);
    }
    guestFree(owned);
}

void WasmScriptingVM::setInputViewModel(int selfRef,
                                        const char* name,
                                        ViewModelInstanceValue* value)
{
    if (!valid() || value == nullptr)
    {
        return;
    }
    switch (value->coreType())
    {
        case ViewModelInstanceViewModelBase::typeKey:
        {
            auto viewModel = value->as<ViewModelInstanceViewModel>();
            auto vmi = viewModel->referenceViewModelInstance();
            if (vmi == nullptr)
            {
                fprintf(stderr,
                        "setInputViewModel - passed in a "
                        "ViewModelInstanceViewModel with no associated "
                        "ViewModelInstance.\n");
                return;
            }
            uint32_t arg = 0;
            uint32_t owned = 0;
            if (!inputArg(selfRef, name, arg, owned))
            {
                return;
            }
            // The module's view model userdata owns the handle and releases
            // it from its finalizer.
            uint32_t handle =
                m_handles.mint(HandleTable::Tag::viewModelInstance,
                               new HostViewModelInstance{std::move(vmi)});
            uint32_t args[4] = {m_L, (uint32_t)selfRef, arg, handle};
            callModule("host_obj_set_view_model", 4, args);
            guestFree(owned);
            break;
        }
        default:
            // Nothing assigned; leave self untouched, like the Luau backend.
            break;
    }
}

void WasmScriptingVM::setInputArtboard(int selfRef,
                                       const char* name,
                                       ScriptedObject* object,
                                       Artboard* artboard)
{
    if (!valid() || object == nullptr || object->scriptAsset() == nullptr ||
        object->scriptAsset()->file() == nullptr || artboard == nullptr)
    {
        return;
    }
    uint32_t arg = 0;
    uint32_t owned = 0;
    if (!inputArg(selfRef, name, arg, owned))
    {
        return;
    }
    auto artboardInstance = artboard->instance();
    artboardInstance->frameOrigin(false);
    // The module's artboard userdata owns the handle and releases it from
    // its finalizer.
    uint32_t handle =
        m_handles.mint(HandleTable::Tag::artboard,
                       new HostArtboard(object->scriptAsset()->file(),
                                        std::move(artboardInstance),
                                        nullptr,
                                        object->dataContext()));
    uint32_t args[4] = {m_L, (uint32_t)selfRef, arg, handle};
    callModule("host_obj_set_artboard", 4, args);
    guestFree(owned);
}

uint32_t WasmScriptingVM::guestString(const char* text, const char* allocator)
{
    if (text == nullptr)
    {
        return 0;
    }
    std::string bytes = moduleStringBytes(this, text, strlen(text));
    // The terminator is one unit wide.
    bytes.append(m_utf16HostStrings ? 2 : 1, '\0');
    uint32_t sizeArgs[1] = {(uint32_t)bytes.size()};
    uint32_t ptr = callModule(allocator, 1, sizeArgs);
    if (ptr != 0)
    {
        memcpy(resolveModulePtr(ptr, (uint32_t)bytes.size()),
               bytes.data(),
               bytes.size());
    }
    return ptr;
}

WasmScriptingVM::GuestName::GuestName(WasmScriptingVM* vm, const char* name) :
    m_vm(vm)
{
    if (vm->m_state->lookupExport("__riveRawAlloc") == nullptr)
    {
        ptr = vm->guestString(name);
        m_owned = true;
        return;
    }
    auto& names = vm->m_state->guestNames;
    auto it = names.find(name);
    if (it != names.end())
    {
        ptr = it->second;
        return;
    }
    ptr = vm->guestString(name, "__riveRawAlloc");
    if (ptr != 0)
    {
        names.emplace(name, ptr);
    }
}

WasmScriptingVM::GuestName::~GuestName()
{
    if (m_owned)
    {
        m_vm->guestFree(ptr);
    }
}

void WasmScriptingVM::guestFree(uint32_t ptr)
{
    if (ptr == 0)
    {
        return;
    }
    uint32_t args[1] = {ptr};
    callModule("free", 1, args);
}

// Browser-lane exports over the same impl cores; nothing off emscripten.
#include "wasm_natives_web_gen.hpp"

#endif
