#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/wasm_lane.hpp"
#include "rive/async/compare_exchange.hpp"
#include "rive/wasm/wasm_lane_policy.hpp"
#include "rive/wasm/wasm_shared.hpp"
#include "wasm_lane_imports_gen.hpp"
#include "wasm_utf16.hpp"

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#include <emscripten/threading.h>
#else
#include "rive/wasm/wasm_scripting_vm.hpp"
#include "wasm_export.h"
#endif

#include <charconv>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string_view>

using namespace rive;

namespace
{
thread_local WasmLane* t_lane = nullptr;

bool readLeb(Span<const uint8_t> bytes, size_t& at, uint32_t& value)
{
  value = 0;
  for (uint32_t shift = 0; shift < 35; shift += 7)
  {
    if (at >= bytes.size())
    {
      return false;
    }
    uint8_t byte = bytes[at++];
    value |= (uint32_t)(byte & 0x7f) << shift;
    if ((byte & 0x80) == 0)
    {
      return true;
    }
  }
  return false;
}
} // namespace

LaneSpec rive::laneSpec(LaneKind kind)
{
  int i = (int)kind;
  return {
      kLaneSections[i],
      kLaneEntryPrefixes[i],
      kLaneModuleNames[i],
      kLaneTrapTexts[i]};
}

const char* rive::laneNoun(LaneKind kind) { return kLaneKindNames[(int)kind]; }

const char* rive::trapText(const char* exception)
{
  constexpr char kPrefix[] = "Exception: ";
  constexpr size_t kPrefixLength = sizeof(kPrefix) - 1;
  return exception != nullptr && strncmp(exception, kPrefix, kPrefixLength) == 0
             ? exception + kPrefixLength
             : exception;
}

std::string WasmLane::name() const
{
  const std::vector<std::string>& names = m_module->scriptNames;
  std::string name = laneNoun(m_kind);
  if (m_entry < names.size())
  {
    name += ' ';
    name += names[m_entry];
  }
  return name;
}

// --- text a lane reports -----------------------------------------------------

// UTF-8, or the UTF-16 a module passes, encoded as UTF-8 one byte at a time,
// so writing it into a lane's fixed buffers never allocates.
struct WasmLane::Text
{
  const uint8_t* data;
  uint32_t bytes;
  bool utf16;

  // Answers how many bytes the whole characters that fit limit take, and
  // writes the first room of them to buffer from at, wrapping by mask.
  uint32_t encode(
      uint32_t limit,
      uint8_t* buffer,
      uint32_t at,
      uint32_t room,
      uint32_t mask) const
  {
    uint32_t out = 0;
    uint8_t chunk[4];
    for (uint32_t i = 0; i < bytes;)
    {
      uint32_t size = 0;
      if (!utf16)
      {
        uint8_t lead = data[i];
        size = lead < 0xc0 ? 1 : lead < 0xe0 ? 2 : lead < 0xf0 ? 3 : 4;
        size = std::min(size, bytes - i);
        memcpy(chunk, data + i, size);
        i += size;
      }
      else if (i + 1 < bytes)
      {
        size = utf8Of(nextUtf16(data, bytes, i), chunk);
      }
      else
      {
        break;
      }
      if (out + size > limit)
      {
        break;
      }
      for (uint32_t k = 0; k < size; k++, out++)
      {
        if (out < room)
        {
          buffer[(at + out) & mask] = chunk[k];
        }
      }
    }
    return out;
  }
};

// A worker's console holds long dumps, while every job makes a console of its
// own and a processor writes from the audio thread.
static constexpr uint32_t kWorkerLogBytes = 64 * 1024;
static constexpr uint32_t kLogBytes = 8 * 1024;
// The ring's counters wrap at 2^32, which only a power of two divides.
static_assert(
    (kWorkerLogBytes & (kWorkerLogBytes - 1)) == 0 &&
    (kLogBytes & (kLogBytes - 1)) == 0);

WasmLane::WasmLane(
    LaneKind kind,
    rcp<WasmLaneModule> module,
    uint32_t entry,
    std::vector<uint8_t> input)
    : m_module(std::move(module))
    , m_entry(entry)
    , m_input(std::move(input))
    , m_kind(kind)
    , m_logCapacity(kind == LaneKind::worker ? kWorkerLogBytes : kLogBytes)
    , m_logBytes(new uint8_t[m_logCapacity])
{}

WasmLane::~WasmLane()
{
  // What it created outlives it only where another hold remains, as the
  // main lane takes on decoding its result.
  for (const auto* ids : {&m_holds, &m_created})
  {
    for (uint32_t id : *ids)
    {
      SharedRegistry::release(id, m_sharedOwner);
    }
  }
}

static bool eraseId(std::vector<uint32_t>& ids, uint32_t id)
{
  auto found = std::find(ids.begin(), ids.end(), id);
  if (found == ids.end())
  {
    return false;
  }
  *found = ids.back();
  ids.pop_back();
  return true;
}

bool WasmLane::holds(uint32_t id) const
{
  return std::find(m_holds.begin(), m_holds.end(), id) != m_holds.end();
}

void WasmLane::holdShared(Span<const uint32_t> ids)
{
  std::lock_guard<std::mutex> guard(m_holdsMutex);
  for (uint32_t id : ids)
  {
    if (!holds(id) && SharedRegistry::retain(id, m_sharedOwner))
    {
      m_holds.push_back(id);
    }
  }
}

void WasmLane::adoptShared(Span<const uint32_t> ids)
{
  std::lock_guard<std::mutex> guard(m_holdsMutex);
  for (uint32_t id : ids)
  {
    if (holds(id))
    {
      SharedRegistry::release(id, m_sharedOwner);
    }
    else
    {
      m_holds.push_back(id);
    }
  }
}

bool WasmLane::dropShared(uint32_t id)
{
  std::lock_guard<std::mutex> guard(m_holdsMutex);
  return eraseId(m_created, id) || eraseId(m_holds, id);
}

WasmLane* WasmLane::current() { return t_lane; }

WasmLane* WasmLane::setCurrent(WasmLane* lane)
{
  WasmLane* outer = t_lane;
  t_lane = lane;
  return outer;
}

// Never waits on the reader: a line that does not fit is dropped.
void WasmLane::writeLine(const Text& text)
{
  // Cut, so a line always fits an empty ring.
  constexpr uint32_t kLineBytes = 1024;
  uint32_t write = m_logWrite.load(std::memory_order_relaxed);
  uint32_t read = m_logRead.load(std::memory_order_acquire);
  uint32_t space = m_logCapacity - (write - read);
  uint32_t mask = m_logCapacity - 1;
  // Writes only into free space, which the reader sees once published.
  uint32_t length = text.encode(
      kLineBytes,
      m_logBytes.get(),
      write + 2,
      space - std::min(space, 2u),
      mask);
  if (2 + length > space)
  {
    m_logsDropped.fetch_add(1);
    return;
  }
  m_logBytes[write & mask] = (uint8_t)length;
  m_logBytes[(write + 1) & mask] = (uint8_t)(length >> 8);
  m_logWrite.store(write + 2 + length, std::memory_order_release);
}

void WasmLane::writeFailure(const Text& text)
{
  if (m_failureClaimed.exchange(true))
  {
    return;
  }
  m_failureLength.store(
      text.encode(
          kFailureBytes,
          (uint8_t*)m_failure,
          0,
          kFailureBytes,
          UINT32_MAX),
      std::memory_order_release);
}

void WasmLane::log(std::string_view line)
{
  writeLine({(const uint8_t*)line.data(), (uint32_t)line.size(), false});
}

void WasmLane::logUtf16(const uint8_t* text, uint32_t bytes)
{
  writeLine({text, bytes, true});
}

void WasmLane::fail(std::string_view message)
{
  writeFailure(
      {(const uint8_t*)message.data(), (uint32_t)message.size(), false});
}

void WasmLane::failUtf16(const uint8_t* text, uint32_t bytes)
{
  writeFailure({text, bytes, true});
}

void WasmLane::takeLogs(
    void (*deliver)(void* context, std::string_view line),
    void* context)
{
  uint32_t read = m_logRead.load(std::memory_order_relaxed);
  uint32_t write = m_logWrite.load(std::memory_order_acquire);
  uint32_t mask = m_logCapacity - 1;
  std::string lines(write - read, '\0');
  for (uint32_t i = 0; i < lines.size(); i++)
  {
    lines[i] = (char)m_logBytes[(read + i) & mask];
  }
  m_logRead.store(write, std::memory_order_release);
  uint32_t dropped = m_logsDropped.exchange(0);
  for (size_t at = 0; at < lines.size();)
  {
    size_t length = (uint8_t)lines[at] | ((uint8_t)lines[at + 1] << 8);
    deliver(context, std::string_view(lines.data() + at + 2, length));
    at += 2 + length;
  }
  if (dropped != 0)
  {
    char note[96];
    snprintf(
        note,
        sizeof(note),
        " dropped %u console lines: it wrote more than %u KB between two "
        "handovers",
        dropped,
        m_logCapacity / 1024);
    deliver(context, name() + note);
  }
}

std::string WasmLane::failure() const
{
  return std::string(
      m_failure,
      m_failureLength.load(std::memory_order_acquire));
}

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

void rive::startConsoleTimer(ConsoleTimers& timers, const std::string& label)
{
  timers[label] = steadyNanos();
}

std::string rive::reportConsoleTimer(
    ConsoleTimers& timers,
    const std::string& label,
    bool end)
{
  auto timer = timers.find(label);
  if (timer == timers.end())
  {
    return "Timer '" + label + "' does not exist";
  }
  char elapsed[32];
  snprintf(
      elapsed,
      sizeof(elapsed),
      ": %.3fms",
      (double)(steadyNanos() - timer->second) / 1e6);
  if (end)
  {
    timers.erase(timer);
  }
  return label + elapsed;
}

// --- lane modules ------------------------------------------------------------

namespace
{
// Calls visit with each section's id and bytes until it answers true.
template <typename Visit>
void visitSections(Span<const uint8_t> module, Visit&& visit)
{
  static const uint8_t kHeader[] = {0x00, 0x61, 0x73, 0x6d};
  if (module.size() < 8 || memcmp(module.data(), kHeader, 4) != 0)
  {
    return;
  }
  size_t at = 8;
  while (at < module.size())
  {
    uint8_t id = module[at++];
    uint32_t size = 0;
    if (!readLeb(module, at, size) || size > module.size() - at ||
        visit(id, module.subset(at, size)))
    {
      return;
    }
    at += size;
  }
}

// Reads a length prefixed name; false when it runs past bytes.
bool readName(Span<const uint8_t> bytes, size_t& at, std::string_view& name)
{
  uint32_t length = 0;
  if (!readLeb(bytes, at, length) || length > bytes.size() - at)
  {
    return false;
  }
  name = std::string_view((const char*)bytes.data() + at, length);
  at += length;
  return true;
}

// Calls visit with each function export's name until it answers true.
template <typename Visit>
void visitFunctionExports(Span<const uint8_t> module, Visit&& visit)
{
  visitSections(module, [&](uint8_t id, Span<const uint8_t> section) {
    constexpr uint8_t kExportSection = 7;
    constexpr uint8_t kFunctionExport = 0;
    if (id != kExportSection)
    {
      return false;
    }
    size_t at = 0;
    uint32_t count = 0;
    readLeb(section, at, count);
    for (uint32_t i = 0; i < count; i++)
    {
      std::string_view name;
      uint32_t index = 0;
      if (!readName(section, at, name) || at >= section.size())
      {
        break;
      }
      uint8_t kind = section[at++];
      if (!readLeb(section, at, index) ||
          (kind == kFunctionExport && visit(name, count)))
      {
        break;
      }
    }
    return true;
  });
}

// One past the highest index of the functions a module exports under prefix.
uint32_t laneEntryCount(Span<const uint8_t> module, std::string_view prefix)
{
  uint32_t entries = 0;
  visitFunctionExports(module, [&](std::string_view name, uint32_t count) {
    uint32_t entry = 0;
    if (name.size() > prefix.size() &&
        name.substr(0, prefix.size()) == prefix &&
        std::from_chars(
            name.data() + prefix.size(),
            name.data() + name.size(),
            entry)
                .ec == std::errc() &&
        entry < count)
    {
      entries = std::max(entries, entry + 1);
    }
    return false;
  });
  return entries;
}

// The name a names section gives each entry; none unless it names every
// entry, so a line never names the wrong one.
std::vector<std::string> readScriptNames(
    Span<const uint8_t> section,
    uint32_t entries)
{
  size_t at = 0;
  uint32_t count = 0;
  std::vector<std::string> names;
  if (!readLeb(section, at, count) || count != entries)
  {
    return names;
  }
  for (uint32_t i = 0; i < count; i++)
  {
    std::string_view name;
    if (!readName(section, at, name))
    {
      return {};
    }
    names.emplace_back(name);
  }
  return names;
}
} // namespace

bool rive::exportsFunction(Span<const uint8_t> module, std::string_view name)
{
  bool found = false;
  visitFunctionExports(module, [&](std::string_view exported, uint32_t) {
    found = exported == name;
    return found;
  });
  return found;
}

namespace
{
void writeLeb(std::vector<uint8_t>& out, uint32_t value)
{
  do
  {
    uint8_t byte = value & 0x7f;
    value >>= 7;
    out.push_back(value != 0 ? byte | 0x80 : byte);
  } while (value != 0);
}

// Exports the start function, which runs rasc's global initializers, for the
// host to call where a stop or bound reaches it, and drops its section.
std::vector<uint8_t> liftStart(Span<const uint8_t> module)
{
  constexpr uint8_t kExportSection = 7;
  constexpr uint8_t kStartSection = 8;
  uint32_t start = 0;
  bool hasStart = false;
  bool hasExports = false;
  visitSections(module, [&](uint8_t id, Span<const uint8_t> body) {
    size_t at = 0;
    hasStart |= id == kStartSection && readLeb(body, at, start);
    hasExports |= id == kExportSection;
    return false;
  });
  if (!hasStart || !hasExports)
  {
    return std::vector<uint8_t>(module.begin(), module.end());
  }
  std::vector<uint8_t> out(module.begin(), module.begin() + 8);
  std::vector<uint8_t> exports;
  visitSections(module, [&](uint8_t id, Span<const uint8_t> body) {
    if (id == kStartSection)
    {
      return false;
    }
    if (id == kExportSection)
    {
      size_t at = 0;
      uint32_t count = 0;
      readLeb(body, at, count);
      writeLeb(exports, count + 1);
      exports.insert(exports.end(), body.begin() + at, body.end());
      std::string_view name = lane_layout::kLiftedStartExport;
      writeLeb(exports, (uint32_t)name.size());
      exports.insert(exports.end(), name.begin(), name.end());
      constexpr uint8_t kFunctionExport = 0;
      exports.push_back(kFunctionExport);
      writeLeb(exports, start);
      body = Span<const uint8_t>(exports.data(), exports.size());
    }
    out.push_back(id);
    writeLeb(out, (uint32_t)body.size());
    out.insert(out.end(), body.begin(), body.end());
    return false;
  });
  return out;
}
#ifdef __EMSCRIPTEN__
// Runners cache compiled lane modules by id, so equal bytes, not just equal
// hashes, share one whichever file carries them.
uint32_t laneModuleId(const std::vector<uint8_t>& bytes)
{
  // Past this many modules the list starts over, which costs only a miss.
  constexpr uint32_t kKeptModules = 32;
  static std::mutex* mutex = new std::mutex();
  static auto* kept = new std::vector<uint8_t>[kKeptModules];
  static uint32_t count = 0;
  // The first kept module's id; each one after it has the next.
  static uint32_t first = 1;
  std::lock_guard<std::mutex> lock(*mutex);
  for (uint32_t i = 0; i < count; i++)
  {
    if (kept[i] == bytes)
    {
      return first + i;
    }
  }
  if (count == kKeptModules)
  {
    first += count;
    // Assigning {} would keep each copy's memory.
    while (count > 0)
    {
      kept[--count] = std::vector<uint8_t>();
    }
  }
  kept[count] = bytes;
  return first + count++;
}
#endif
} // namespace

std::vector<std::vector<uint8_t>> rive::laneModules(
    Span<const uint8_t> mainModule)
{
  std::vector<std::vector<uint8_t>> modules;
  for (const char* name : kLaneSections)
  {
    Span<const uint8_t> section = findLaneSection(mainModule, name);
    if (!section.empty())
    {
      modules.push_back(liftStart(section));
    }
  }
  return modules;
}

Span<const uint8_t> rive::findLaneSection(
    Span<const uint8_t> module,
    const char* name)
{
  constexpr uint8_t kCustomSection = 0;
  Span<const uint8_t> found;
  visitSections(module, [&](uint8_t id, Span<const uint8_t> section) {
    size_t at = 0;
    std::string_view sectionName;
    if (id != kCustomSection || !readName(section, at, sectionName) ||
        sectionName != name)
    {
      return false;
    }
    found = section.subset(at, section.size() - at);
    return true;
  });
  return found;
}

// --- host limits -------------------------------------------------------------

namespace
{
std::mutex& limitsMutex()
{
  static std::mutex mutex;
  return mutex;
}

ScriptingLimits& limitsSlot()
{
  static ScriptingLimits limits;
  return limits;
}
} // namespace

void ScriptingLimits::set(const ScriptingLimits& limits)
{
  std::lock_guard<std::mutex> lock(limitsMutex());
#ifndef __EMSCRIPTEN__
  static_assert(kHardwareBoundsDefault == WASM_RIVE_HW_RESERVES_DEFAULT);
  // Only a change applies, so setting other limits keeps a cap set in WAMR.
  if (limits.hardwareBoundsMemories != limitsSlot().hardwareBoundsMemories)
  {
    wasm_runtime_rive_limit_hw_reserves(limits.hardwareBoundsMemories);
  }
#endif
  limitsSlot() = limits;
}

ScriptingLimits ScriptingLimits::get()
{
  std::lock_guard<std::mutex> lock(limitsMutex());
  return limitsSlot();
}

#ifdef __EMSCRIPTEN__
// The page runner reports a lane's throws and console lines through these,
// with the lane it was handed.
extern "C" EMSCRIPTEN_KEEPALIVE void rive_web_lane_fail(
    uint32_t lane,
    const char* text)
{
  ((WasmLane*)(uintptr_t)lane)->fail(text);
}

extern "C" EMSCRIPTEN_KEEPALIVE void rive_web_lane_log(
    uint32_t lane,
    const char* text)
{
  ((WasmLane*)(uintptr_t)lane)->log(text);
}

// A metered lane's fuel check throws what this answers.
extern "C" EMSCRIPTEN_KEEPALIVE const char* rive_web_lane_fuel(uint32_t lane)
{
  return ((WasmLane*)(uintptr_t)lane)->fuelStop();
}

void WasmLane::failTaken(char* text)
{
  fail(text);
  free(text);
}

void WasmLane::interruptCall() { m_interruptAt.store(0); }

void WasmLane::interruptAfter(uint32_t ms)
{
  int64_t unarmed = kNoInterrupt;
  compareExchangeStrong(
      m_interruptAt,
      unarmed,
      steadyNanos() + (int64_t)ms * 1000000);
}

void WasmLane::dropInterrupt() { m_interruptAt.store(kNoInterrupt); }

const char* WasmLane::fuelStop() const
{
  using Clock = std::chrono::steady_clock;
  int64_t interruptAt = m_interruptAt.load();
  if (interruptAt != kNoInterrupt && steadyNanos() >= interruptAt)
  {
    return "lane was stopped";
  }
  Clock::time_point deadline = callDeadline();
  return deadline != Clock::time_point::max() && Clock::now() >= deadline
             ? "execution exceeded timeout on the page's thread"
             : nullptr;
}

PageThreadBudget::PageThreadBudget(const WasmLane& lane)
{
  using Clock = std::chrono::steady_clock;
  uint32_t ms = emscripten_is_main_browser_thread() ? lane.pageThreadBudgetMs()
                                                    : 0;
  m_outer = armCallDeadline(
      ms == 0 ? Clock::time_point::max()
              : Clock::now() + std::chrono::milliseconds(ms));
}

PageThreadBudget::~PageThreadBudget() { restoreCallDeadline(m_outer); }
#else

namespace
{
void laneError(wasm_exec_env_t env, uint32_t text, uint32_t bytes)
{
  WasmLane* lane = WasmLane::current();
  auto data = (const uint8_t*)
      wasmAppBytes(wasm_runtime_get_module_inst(env), text, bytes);
  if (lane != nullptr && data != nullptr)
  {
    lane->failUtf16(data, bytes);
  }
}

// The watchdog's interrupts stop and bound every lane here, so a metered
// lane's check has nothing to ask.
void laneFuelCheck(wasm_exec_env_t) {}

NativeSymbol kLaneNatives[] = {
    {"error", (void*)laneError, "(ii)", nullptr},
    {"fuel_check", (void*)laneFuelCheck, "()", nullptr},
};
} // namespace

void rive::registerLaneNatives()
{
  static std::once_flag once;
  std::call_once(once, []() {
    wasm_runtime_register_natives(
        "rive_lane_v1",
        kLaneNatives,
        sizeof(kLaneNatives) / sizeof(kLaneNatives[0]));
  });
}

uint32_t rive::wasmCallCells(void* instance, void* function, uint32_t limit)
{
  auto inst = (wasm_module_inst_t)instance;
  auto fn = (wasm_function_inst_t)function;
  auto cells = [](wasm_valkind_t kind) -> uint32_t {
    return kind == WASM_I64 || kind == WASM_F64 ? 2 : kind == WASM_V128 ? 4 : 1;
  };
  constexpr uint32_t kMaxCells = 8;
  limit = std::min(limit, kMaxCells);
  uint32_t params = wasm_func_get_param_count(fn, inst);
  uint32_t results = wasm_func_get_result_count(fn, inst);
  if (params > limit || results > limit)
  {
    return ~0u;
  }
  wasm_valkind_t kinds[kMaxCells];
  uint32_t paramCells = 0;
  wasm_func_get_param_types(fn, inst, kinds);
  for (uint32_t i = 0; i < params; i++)
  {
    paramCells += cells(kinds[i]);
  }
  uint32_t resultCells = 0;
  wasm_func_get_result_types(fn, inst, kinds);
  for (uint32_t i = 0; i < results; i++)
  {
    resultCells += cells(kinds[i]);
  }
  return resultCells > limit ? ~0u : paramCells;
}

void* rive::wasmAppBytes(void* instance, uint32_t appAddr, uint32_t size)
{
  auto inst = (wasm_module_inst_t)instance;
  return wasm_runtime_validate_app_addr(inst, appAddr, size)
             ? wasm_runtime_addr_app_to_native(inst, appAddr)
             : nullptr;
}

void rive::ensureWasmThreadEnv()
{
  struct ThreadEnv
  {
    ThreadEnv() { wasm_runtime_init_thread_env(); }
    ~ThreadEnv() { wasm_runtime_destroy_thread_env(); }
  };
  static thread_local ThreadEnv env;
  (void)env;
}

const uint8_t* rive::wasmConsoleText(
    void* instance,
    uint32_t text,
    uint32_t& bytes)
{
  bytes = 0;
  if (text >= 4)
  {
    const void* length = wasmAppBytes(instance, text - 4, 4);
    if (length == nullptr)
    {
      return nullptr;
    }
    memcpy(&bytes, length, 4);
  }
  // WAMR has no address for an empty string at the end of memory.
  return (const uint8_t*)(bytes == 0 ? ""
                                     : wasmAppBytes(instance, text, bytes));
}

// The std's console string as its UTF-16 bytes, null when out of bounds.
static std::string_view consoleUtf16(void* execEnv, uint32_t text)
{
  uint32_t bytes = 0;
  const uint8_t* data = wasmConsoleText(
      wasm_runtime_get_module_inst((wasm_exec_env_t)execEnv),
      text,
      bytes);
  return data != nullptr ? std::string_view((const char*)data, bytes)
                         : std::string_view();
}

void WasmLane::logConsole(void* execEnv, uint32_t text)
{
  std::string_view line = consoleUtf16(execEnv, text);
  if (line.data() != nullptr)
  {
    logUtf16((const uint8_t*)line.data(), (uint32_t)line.size());
  }
}

void WasmLane::consoleTimer(
    void* execEnv,
    uint32_t label,
    bool report,
    bool end)
{
  std::string_view utf16 = consoleUtf16(execEnv, label);
  Text text{(const uint8_t*)utf16.data(), (uint32_t)utf16.size(), true};
  std::string name(text.encode(UINT32_MAX, nullptr, 0, 0, 0), '\0');
  text.encode(UINT32_MAX, (uint8_t*)name.data(), 0, UINT32_MAX, UINT32_MAX);
  if (!report)
  {
    startConsoleTimer(m_consoleTimers, name);
    return;
  }
  log(reportConsoleTimer(m_consoleTimers, name, end));
}

bool WasmLane::instantiate(uint32_t stackBytes)
{
  char error[256] = {};
  auto inst = wasm_runtime_instantiate(
      (wasm_module_t)m_module->module.get(),
      stackBytes,
      0,
      error,
      sizeof(error));
  if (inst == nullptr && strstr(error, WASM_RIVE_HW_RESERVE_FAILED) != nullptr)
  {
    if (void* checked = m_module->fallbackModule(laneSpec(m_kind).module))
    {
      inst = wasm_runtime_instantiate(
          (wasm_module_t)checked,
          stackBytes,
          0,
          error,
          sizeof(error));
    }
  }
  wasm_exec_env_t env = inst != nullptr
                            ? wasm_runtime_create_exec_env(inst, stackBytes)
                            : nullptr;
  if (env == nullptr)
  {
    if (inst != nullptr)
    {
      wasm_runtime_deinstantiate(inst);
    }
    fail(std::string(laneNoun(m_kind)) + " instantiation failed: " + error);
    return false;
  }
  std::lock_guard<std::mutex> lock(m_envMutex);
  m_instance = inst;
  m_execEnv = env;
  return true;
}

bool WasmLane::reuse()
{
  WasmLaneModule::Instance parked = m_module->unpark();
  std::lock_guard<std::mutex> lock(m_envMutex);
  m_instance = parked.instance;
  m_execEnv = parked.execEnv;
  return m_instance != nullptr;
}

bool WasmLane::runStart(uint32_t* entry, bool reused)
{
  std::vector<uint8_t> input = takeInput();
  uint32_t argv[1] = {};
  // The reset runs the start itself.
  void* start = reused ? lookup(lane_layout::kLaneResetExport, 0, 1)
                       : lookup(lane_layout::kLiftedStartExport, 0, 1, true);
  if (hasFailure() || (start != nullptr && !call(start, 0, argv)))
  {
    return false;
  }
  argv[0] = (uint32_t)input.size();
  if (!call(lane_layout::kLaneAllocExport, 1, argv))
  {
    return false;
  }
  void* at = wasmAppBytes(m_instance, argv[0], (uint32_t)input.size());
  if (at == nullptr)
  {
    fail("lane allocated its input outside its memory");
    return false;
  }
  if (!input.empty())
  {
    memcpy(at, input.data(), input.size());
  }
  entry[0] = argv[0];
  entry[1] = (uint32_t)input.size();
  return true;
}

void* WasmLane::lookup(
    const char* name,
    uint32_t argc,
    uint32_t cells,
    bool optional)
{
  wasm_function_inst_t fn = wasm_runtime_lookup_function(
      (wasm_module_inst_t)m_instance,
      name);
  if (fn == nullptr)
  {
    if (!optional)
    {
      fail(std::string(spec().module) + " has no " + name);
    }
    return nullptr;
  }
  // WAMR writes results over the argument cells.
  if (wasmCallCells(m_instance, fn, cells) != argc)
  {
    fail(
        std::string(spec().module) + " exports " + name +
        " with the wrong signature");
    return nullptr;
  }
  return fn;
}

bool WasmLane::call(void* fn, uint32_t argc, uint32_t* argv)
{
  return wasm_runtime_call_wasm(
      (wasm_exec_env_t)m_execEnv,
      (wasm_function_inst_t)fn,
      argc,
      argv);
}

void WasmLane::failTrap(std::string_view message)
{
  auto inst = (wasm_module_inst_t)m_instance;
  const char* exception = trapText(wasm_runtime_get_exception(inst));
  fail(
      !message.empty()       ? message
      : exception != nullptr ? std::string_view(exception)
                             : std::string_view(spec().trapped));
  wasm_runtime_clear_exception(inst);
}

void WasmLane::interruptCall()
{
  std::lock_guard<std::mutex> lock(m_envMutex);
  if (m_execEnv != nullptr)
  {
    wasm_runtime_rive_interrupt((wasm_exec_env_t)m_execEnv);
  }
}

void WasmLane::interruptAfter(uint32_t ms)
{
  std::lock_guard<std::mutex> lock(m_envMutex);
  // Replacing an armed one would postpone it, or clear an interrupt it fired.
  if (m_execEnv != nullptr && m_interruptBudget == nullptr)
  {
    m_interruptBudget = std::make_unique<WasmCallBudget>(m_execEnv);
    m_interruptBudget->arm(ms);
  }
}

void WasmLane::dropInterrupt()
{
  std::lock_guard<std::mutex> lock(m_envMutex);
  m_interruptBudget = nullptr;
}

WasmLaneModule::Instance WasmLane::detach()
{
  std::lock_guard<std::mutex> lock(m_envMutex);
  m_interruptBudget = nullptr;
  WasmLaneModule::Instance detached{m_instance, m_execEnv};
  m_execEnv = nullptr;
  m_instance = nullptr;
  return detached;
}

void WasmLane::teardown() { WasmLaneModule::destroy(detach()); }

void WasmLaneModule::destroy(Instance instance)
{
  if (instance.execEnv != nullptr)
  {
    wasm_runtime_destroy_exec_env((wasm_exec_env_t)instance.execEnv);
  }
  if (instance.instance != nullptr)
  {
    wasm_runtime_deinstantiate((wasm_module_inst_t)instance.instance);
  }
}

WasmLaneModule::~WasmLaneModule()
{
  for (Instance parked : m_parked)
  {
    destroy(parked);
  }
}

void WasmLaneModule::park(Instance instance)
{
  std::lock_guard<std::mutex> lock(m_parkedMutex);
  m_parked.push_back(instance);
}

void* WasmLaneModule::fallbackModule(const char* what)
{
  std::lock_guard<std::mutex> lock(m_fallbackMutex);
  if (m_fallback != nullptr)
  {
    return m_fallback.get();
  }
  Span<const uint8_t> wasm = WasmScriptingVM::hardwareBoundsWasm(module);
  if (wasm.empty())
  {
    return nullptr;
  }
  WasmScriptingVM::ExecutionTier fallbackTier;
  std::string interpReason;
  m_fallback = WasmScriptingVM::loadFallbackModule(
      wasm,
      what,
      fallbackTier,
      interpReason);
  if (m_fallback != nullptr)
  {
    m_fallbackTier = WasmScriptingVM::tierName(fallbackTier, interpReason);
    m_fallbackCompiled = fallbackTier != WasmScriptingVM::ExecutionTier::interp;
    m_fellBack.store(true, std::memory_order_release);
  }
  return m_fallback.get();
}

bool WasmLaneModule::hardwareBounds() const
{
  return !m_fellBack.load(std::memory_order_acquire) &&
         wasm_runtime_rive_module_hw_bounds((wasm_module_t)module.get());
}

WasmLaneModule::Instance WasmLaneModule::unpark()
{
  std::lock_guard<std::mutex> lock(m_parkedMutex);
  if (m_parked.empty())
  {
    return {};
  }
  Instance parked = m_parked.back();
  m_parked.pop_back();
  return parked;
}

static bool checkLaneImports(
    wasm_module_t module,
    LaneKind kind,
    std::string& error)
{
  int32_t count = wasm_runtime_get_import_count(module);
  for (int32_t i = 0; i < count; i++)
  {
    wasm_import_t import;
    wasm_runtime_get_import_type(module, i, &import);
    if (laneImportRefusal((uint32_t)kind, import.module_name, import.name) !=
        nullptr)
    {
      error = lane_layout::laneImportError(import.module_name, import.name);
      return false;
    }
  }
  return true;
}

#endif

rcp<WasmLaneModule> rive::loadLaneModule(
    Span<const uint8_t> mainModule,
    LaneKind kind,
    std::string& error)
{
  const LaneSpec& spec = laneSpec(kind);
  Span<const uint8_t> section = findLaneSection(mainModule, spec.section);
  if (section.empty())
  {
    return nullptr;
  }
  auto lane = make_rcp<WasmLaneModule>();
  lane->entryCount = laneEntryCount(section, spec.prefix);
  if (lane->entryCount == 0)
  {
    error = std::string(spec.module) + ": it exports no entries";
    return nullptr;
  }
  lane->scriptNames = readScriptNames(
      findLaneSection(mainModule, kLaneNameSections[(int)kind]),
      lane->entryCount);
  std::vector<uint8_t> lifted = liftStart(section);
#ifdef __EMSCRIPTEN__
  lane->bytes = std::move(lifted);
  lane->id = laneModuleId(lane->bytes);
  return lane;
#else
  WasmScriptingVM::ExecutionTier tier;
  std::string interpReason;
  std::string loadError;
  lane->module = WasmScriptingVM::loadSharedModule(
      Span<const uint8_t>(lifted.data(), lifted.size()),
      tier,
      interpReason,
      loadError);
  if (lane->module == nullptr)
  {
    error = std::string(spec.module) +
            ": lane module failed to load: " + loadError;
    return nullptr;
  }
  lane->compiled = tier != WasmScriptingVM::ExecutionTier::interp;
  lane->tier = WasmScriptingVM::tierName(tier, interpReason);
  lane->resets = kind == LaneKind::job &&
                 exportsFunction(
                     Span<const uint8_t>(lifted.data(), lifted.size()),
                     lane_layout::kLaneResetExport);
  for (uint32_t i = 0; i < lane->entryCount; i++)
  {
    lane->entryNames.push_back(spec.prefix + std::to_string(i));
  }
  if (!checkLaneImports((wasm_module_t)lane->module.get(), kind, error))
  {
    error = std::string(spec.module) + ": " + error;
    return nullptr;
  }
  return lane;
#endif
}

#endif
