#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/wasm_shared.hpp"
#include "rive/async/compare_exchange.hpp"
#include "rive/async/timeouts.hpp"
#include "rive/wasm/wasm_lane_policy.hpp"
#include "rive/wasm/wasm_processors.hpp"

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
#ifdef __EMSCRIPTEN_PTHREADS__
#include <emscripten/threading.h>
#endif

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <cstring>

using namespace rive;

using Clock = std::chrono::steady_clock;
using namespace rive::shared_layout;

static_assert(kChunkCount * kChunkSlots == 1u << (31 - kIdSlotShift), "");
static_assert(kSlotLive == kIdGenerationMask + 1, "");
static_assert(kSlotPin == kSlotLive << 1, "");
#ifdef __EMSCRIPTEN__
static_assert(offsetof(SharedHeader, kind) == kHeaderKind, "");
static_assert(offsetof(SharedHeader, lock) == kHeaderLock, "");
static_assert(offsetof(SharedHeader, capacity) == kHeaderCapacity, "");
static_assert(offsetof(SharedHeader, closed) == kHeaderClosed, "");
static_assert(sizeof(SharedHeader) == kHeaderSize, "");
static_assert(offsetof(SharedRegion::Block, poisoned) == kRegionPoisoned, "");
static_assert(sizeof(SharedRegion::Block) == kRegionData, "");
static_assert(offsetof(SharedRing::Block, head) == kRingHead, "");
static_assert(offsetof(SharedRing::Block, used) == kRingUsed, "");
static_assert(offsetof(SharedRing::Block, dataSignal) == kRingDataSignal, "");
static_assert(offsetof(SharedRing::Block, spaceSignal) == kRingSpaceSignal, "");
static_assert(sizeof(SharedRing::Block) == kRingData, "");
static_assert(offsetof(SharedSnapshot::Block, latest) == kSnapshotLatest, "");
static_assert(offsetof(SharedSnapshot::Block, seq.low) == kSnapshotSeq, "");
static_assert(
    offsetof(SharedSnapshot::Block, seq.high) == kSnapshotSeqHigh,
    "");
static_assert(
    offsetof(SharedSnapshot::Block, versions) == kSnapshotVersions,
    "");
static_assert(offsetof(SharedSnapshot::Block, sizes) == kSnapshotSizes, "");
static_assert(sizeof(SharedSnapshot::Block) == kSnapshotData, "");
static_assert(
    offsetof(SharedSignal::Block, watcherCount) == kSignalWatcherCount,
    "");
static_assert(
    offsetof(SharedSignal::Block, watcherCapacity) == kSignalWatcherCapacity,
    "");
static_assert(offsetof(SharedSignal::Block, seq.low) == kSignalSeq, "");
static_assert(offsetof(SharedSignal::Block, seq.high) == kSignalSeqHigh, "");
static_assert(offsetof(SharedSignal::Block, watchers) == kSignalWatchers, "");
static_assert(sizeof(SharedHeader) == kBlobData, "");
static_assert(offsetof(SharedTable, lock) == kTableLock, "");
static_assert(offsetof(SharedTable, count) == kTableCount, "");
static_assert(offsetof(SharedTable, freeHead) == kTableFreeHead, "");
static_assert(offsetof(SharedTable, freeTail) == kTableFreeTail, "");
static_assert(offsetof(SharedTable, lanes) == kTableLanes, "");
static_assert(offsetof(SharedTable, tokens) == kTableTokens, "");
static_assert(offsetof(SharedTable, chunks) == kTableChunks, "");
static_assert(offsetof(SharedSlot, state) == kSlotState, "");
static_assert(offsetof(SharedSlot, block) == kSlotBlock, "");
static_assert(offsetof(SharedSlot, owner) == kSlotOwner, "");
static_assert(kSlotOwnerHigh == kSlotOwner + 4, "");
static_assert(sizeof(SharedSlot) == kSlotSize, "");
#endif
static_assert((uint32_t)SharedObject::Kind::region == kKindRegion, "");
static_assert((uint32_t)SharedObject::Kind::ring == kKindRing, "");
static_assert((uint32_t)SharedObject::Kind::snapshot == kKindSnapshot, "");
static_assert((uint32_t)SharedObject::Kind::signal == kKindSignal, "");
static_assert((uint32_t)SharedObject::Kind::blob == kKindBlob, "");

void rive::lockWord(std::atomic<int32_t>& word)
{
  spinUntil([&word]() {
    int32_t expected = 0;
    return compareExchangeWeak(word, expected, 1, std::memory_order_acquire);
  });
}

void rive::unlockWord(std::atomic<int32_t>& word)
{
  word.store(0, std::memory_order_release);
}

namespace
{
thread_local Clock::time_point t_callDeadline = Clock::time_point::max();

struct WordGuard
{
  explicit WordGuard(std::atomic<int32_t>& word) : word(word)
  {
    lockWord(word);
  }
  ~WordGuard() { unlockWord(word); }
  std::atomic<int32_t>& word;
};
} // namespace

Clock::time_point rive::armCallDeadline(Clock::time_point deadline)
{
  Clock::time_point outer = t_callDeadline;
  t_callDeadline = std::min(outer, deadline);
  return outer;
}

void rive::restoreCallDeadline(Clock::time_point outer)
{
  t_callDeadline = outer;
}

Clock::time_point rive::callDeadline() { return t_callDeadline; }

std::chrono::milliseconds rive::waitLimit()
{
#ifdef __EMSCRIPTEN_PTHREADS__
  if (emscripten_is_main_browser_thread())
  {
    return std::chrono::milliseconds(lane_timing::kMainWaitMs);
  }
#endif
  return std::chrono::milliseconds(lane_timing::kLaneWaitMs);
}

// --- wake word ---------------------------------------------------------------

void WakeWord::wake()
{
#ifdef __EMSCRIPTEN__
  static_assert(offsetof(WakeWord, m_word) == kWakeWordWord, "");
#endif
  m_word.fetch_add(1, std::memory_order_acq_rel);
#ifdef __EMSCRIPTEN_PTHREADS__
  emscripten_futex_wake(&m_word, INT_MAX);
#elif !defined(__EMSCRIPTEN__)
  // The waiter checks the word under the mutex, so taking it here, after
  // the bump, means it either sees the bump or is already waiting.
  lockSpinning(m_mutex);
  m_mutex.unlock();
  m_cv.notify_all();
#endif
}

void WakeWord::wait(uint32_t seen, Clock::time_point deadline)
{
#ifdef __EMSCRIPTEN_PTHREADS__
  double ms = INFINITY;
  if (deadline != Clock::time_point::max())
  {
    ms = std::max(
        0.0,
        std::chrono::duration<double, std::milli>(deadline - Clock::now())
            .count());
  }
  emscripten_futex_wait(&m_word, seen, ms);
#elif !defined(__EMSCRIPTEN__)
  std::unique_lock<std::mutex> lock(m_mutex);
  auto moved = [this, seen]() { return value() != seen; };
  if (deadline == Clock::time_point::max())
  {
    m_cv.wait(lock, moved);
  }
  else
  {
    m_cv.wait_until(lock, deadline, moved);
  }
#else
  // Without threads nothing waits: a cooperative worker steps instead.
  (void)seen;
  (void)deadline;
#endif
}

// --- objects -----------------------------------------------------------------

SharedObject::SharedObject(
    Kind kind,
    size_t blockSize,
    uint32_t capacity,
    size_t dataSize)
    : m_block((SharedHeader*)calloc(1, blockSize + dataSize))
    , m_blockSize(blockSize)
{
  if (m_block != nullptr)
  {
    m_block->kind = (uint32_t)kind;
    m_block->capacity = capacity;
  }
}

SharedObject::~SharedObject() { free(m_block); }

// --- signal ------------------------------------------------------------------

SharedSignal::SharedSignal() : SharedObject(Kind::signal, sizeof(Block), 0, 0)
{}

SharedSignal::~SharedSignal()
{
  if (made())
  {
    free(signal()->watchers);
  }
  free(m_watchCounts);
}

uint64_t SharedSignal::seq() const { return signal()->seq.load(); }

void SharedSignal::notify()
{
  Block* block = signal();
  block->seq.bump();
  WordGuard guard(block->header.lock);
  for (uint32_t i = 0; i < block->watcherCount; i++)
  {
    block->watchers[i]->wake();
  }
}

void SharedSignal::takeHolds(std::vector<uint32_t>&) { notify(); }

void SharedSignal::addWatcher(WakeWord* watcher)
{
  Block* block = signal();
  WordGuard guard(block->header.lock);
  for (uint32_t i = 0; i < block->watcherCount; i++)
  {
    if (block->watchers[i] == watcher)
    {
      m_watchCounts[i]++;
      return;
    }
  }
  if (block->watcherCount == block->watcherCapacity)
  {
    // Without memory it stays unwatched, and its waiter sees the notify
    // at its next wake.
    uint32_t capacity = std::max(4u, block->watcherCapacity * 2);
    auto* watchers = (WakeWord**)realloc(
        block->watchers,
        capacity * sizeof(WakeWord*));
    if (watchers == nullptr)
    {
      return;
    }
    block->watchers = watchers;
    auto* counts = (uint32_t*)realloc(
        m_watchCounts,
        capacity * sizeof(uint32_t));
    if (counts == nullptr)
    {
      return;
    }
    m_watchCounts = counts;
    block->watcherCapacity = capacity;
  }
  m_watchCounts[block->watcherCount] = 1;
  block->watchers[block->watcherCount++] = watcher;
}

void SharedSignal::removeWatcher(WakeWord* watcher)
{
  Block* block = signal();
  WordGuard guard(block->header.lock);
  for (uint32_t i = 0; i < block->watcherCount; i++)
  {
    if (block->watchers[i] == watcher)
    {
      if (--m_watchCounts[i] == 0)
      {
        uint32_t last = --block->watcherCount;
        block->watchers[i] = block->watchers[last];
        m_watchCounts[i] = m_watchCounts[last];
      }
      return;
    }
  }
}

// --- region ------------------------------------------------------------------

SharedRegion::SharedRegion(uint32_t size)
    : SharedObject(Kind::region, sizeof(Block), size, size)
{}

#if defined(WITH_RIVE_TOOLS) || defined(TESTING)
static std::atomic<uint32_t> s_wakeDelayMs{0};

void SharedRegion::delayWakes(uint32_t ms) { s_wakeDelayMs = ms; }
#endif

bool SharedRegion::lock(double timeoutSeconds)
{
  Clock::time_point deadline = std::min(
      Clock::now() + waitLimit(),
      t_callDeadline);
  if (!unboundedSeconds(timeoutSeconds))
  {
    deadline = std::min(deadline, deadlineAfter(timeoutSeconds));
  }
#if defined(WITH_RIVE_TOOLS) || defined(TESTING)
  if (s_wakeDelayMs != 0 && deadline > Clock::now())
  {
    deadline += std::chrono::milliseconds(s_wakeDelayMs.load());
  }
#endif
#if RIVE_ONE_THREAD()
  // Nothing can unlock it while the only thread waits, so a held region
  // times out at the deadline as the timed wait would.
  if (m_locked)
  {
    while (Clock::now() < deadline)
    {
    }
    return false;
  }
  m_locked = true;
  return true;
#elif defined(_GLIBCXX_TSAN)
  // libstdc++ 14 before 14.4 and 15 before 15.3 cannot compile a steady clock
  // deadline under TSan.
  return m_lock.try_lock_for(deadline - Clock::now());
#else
  // Most holders let go within microseconds, sooner than a parked wait wakes.
  Clock::time_point spinEnd = std::min(
      deadline,
      Clock::now() + std::chrono::microseconds(20));
  do
  {
    if (m_lock.try_lock())
    {
      return true;
    }
  } while (Clock::now() < spinEnd);
  return m_lock.try_lock_until(deadline);
#endif
}

void SharedRegion::unlock()
{
#if RIVE_ONE_THREAD()
  m_locked = false;
#else
  m_lock.unlock();
#endif
}

std::atomic<uint32_t>* SharedRegion::word(uint32_t offset)
{
  if ((offset & 3) != 0 || (uint64_t)offset + 4 > size())
  {
    return nullptr;
  }
  return reinterpret_cast<std::atomic<uint32_t>*>(bytes() + offset);
}

bool SharedRegion::poisoned() const
{
  return ((Block*)block())->poisoned.load() != 0;
}

void SharedRegion::poison() { ((Block*)block())->poisoned.store(1); }

// --- ring --------------------------------------------------------------------

SharedRing::SharedRing(uint32_t capacity)
    : SharedObject(Kind::ring, sizeof(Block), capacity, capacity)
    , m_data(make_rcp<SharedSignal>())
    , m_space(make_rcp<SharedSignal>())
{}

bool SharedRing::made() const
{
  return SharedObject::made() && m_data->made() && m_space->made();
}

void SharedRing::setSignalIds(uint32_t data, uint32_t space)
{
  ring()->dataSignal = data;
  ring()->spaceSignal = space;
}

void SharedRing::copyIn(const uint8_t* from, uint32_t size)
{
  Block* block = ring();
  uint32_t capacity = block->header.capacity;
  uint32_t at = (block->head + block->used) % capacity;
  uint32_t first = std::min(size, capacity - at);
  memcpy(data() + at, from, first);
  memcpy(data(), from + first, size - first);
  block->used += size;
}

void SharedRing::copyOut(uint32_t at, uint8_t* to, uint32_t size) const
{
  uint32_t capacity = ring()->header.capacity;
  at %= capacity;
  uint32_t first = std::min(size, capacity - at);
  memcpy(to, data() + at, first);
  memcpy(to + first, data(), size - first);
}

namespace
{
// The holds after a value, and their count.
uint64_t holdBytes(size_t count) { return count == 0 ? 0 : 4 * count + 4; }

uint32_t sizeWord(size_t size, size_t holdCount)
{
  return (uint32_t)(size + holdBytes(holdCount)) |
         (holdCount != 0 ? kRecordHolds : 0);
}

// A publisher may overwrite the copy meanwhile and the version check then
// discards it, so tsan_suppressions.txt names this race.
void copyTorn(void* to, const void* from, size_t size)
{
  memcpy(to, from, size);
}
} // namespace

uint64_t SharedRing::recordBytes(size_t size, size_t holdCount)
{
  return 4 + size + holdBytes(holdCount);
}

bool SharedRing::write(Span<const uint8_t> record, Span<const uint32_t> holds)
{
  uint32_t size = sizeWord(record.size(), holds.size());
  uint32_t count = (uint32_t)holds.size();
  Block* block = ring();
  {
    WordGuard guard(block->header.lock);
    if (block->header.closed != 0 ||
        block->used + recordBytes(record.size(), holds.size()) >
            block->header.capacity)
    {
      return false;
    }
    copyIn((const uint8_t*)&size, 4);
    copyIn(record.data(), (uint32_t)record.size());
    if (count != 0)
    {
      copyIn((const uint8_t*)holds.data(), count * 4);
      copyIn((const uint8_t*)&count, 4);
    }
  }
  m_data->notify();
  return true;
}

void SharedRing::peekRecord(uint32_t at, uint32_t& bytes, uint32_t& count) const
{
  uint32_t word;
  copyOut(at, (uint8_t*)&word, 4);
  bytes = word & ~kRecordHolds;
  count = 0;
  if ((word & kRecordHolds) != 0)
  {
    copyOut(at + bytes, (uint8_t*)&count, 4);
  }
}

void SharedRing::copyHolds(
    uint32_t at,
    uint32_t bytes,
    uint32_t count,
    std::vector<uint32_t>& out) const
{
  for (uint32_t i = 0; i < count; i++)
  {
    uint32_t id;
    copyOut(at + bytes - (count - i) * 4, (uint8_t*)&id, 4);
    out.push_back(id);
  }
}

template <typename Take>
uint32_t SharedRing::takeHead(
    std::vector<uint32_t>* holds,
    bool& popped,
    Take&& take)
{
  popped = false;
  uint32_t size;
  Block* block = ring();
  {
    WordGuard guard(block->header.lock);
    if (block->used == 0)
    {
      return 0;
    }
    uint32_t bytes;
    uint32_t count;
    peekRecord(block->head, bytes, count);
    if (holds == nullptr && count != 0)
    {
      return kCarriesHolds;
    }
    size = bytes - (uint32_t)holdBytes(count);
    if (!take(size))
    {
      return size + 1;
    }
    pop(bytes, count, holds);
  }
  popped = true;
  m_space->notify();
  return size + 1;
}

uint32_t SharedRing::read(
    uint8_t* out,
    uint32_t capacity,
    std::vector<uint32_t>* holds)
{
  bool popped;
  return takeHead(holds, popped, [&](uint32_t size) {
    if (out == nullptr || size > capacity)
    {
      return false;
    }
    copyOut(ring()->head + 4, out, size);
    return true;
  });
}

void SharedRing::pop(
    uint32_t bytes,
    uint32_t count,
    std::vector<uint32_t>* holds)
{
  Block* block = ring();
  if (holds != nullptr)
  {
    copyHolds(block->head, bytes, count, *holds);
  }
  block->head = (block->head + 4 + bytes) % block->header.capacity;
  block->used -= 4 + bytes;
}

uint32_t SharedRing::drop(uint32_t capacity, std::vector<uint32_t>* holds)
{
  bool popped;
  uint32_t answer = takeHead(holds, popped, [capacity](uint32_t size) {
    return size > capacity;
  });
  return popped || answer == kCarriesHolds ? answer : 0;
}

void SharedRing::takeHolds(std::vector<uint32_t>& out)
{
  out.push_back(dataSignalId());
  out.push_back(spaceSignalId());
  Block* block = ring();
  {
    WordGuard guard(block->header.lock);
    for (uint32_t at = 0; at < block->used;)
    {
      uint32_t bytes;
      uint32_t count;
      peekRecord(block->head + at, bytes, count);
      copyHolds(block->head + at, bytes, count, out);
      at += 4 + bytes;
    }
    // A call still holding the ring must not hand these holds out again,
    // nor write ones nobody would give back.
    block->used = 0;
    block->header.closed = 1;
  }
  // A handle may keep a signal past the ring, and its waits must wake.
  m_data->notify();
  m_space->notify();
}

uint32_t SharedRing::used()
{
  WordGuard guard(ring()->header.lock);
  return ring()->used;
}

// --- snapshot ----------------------------------------------------------------

SharedSnapshot::SharedSnapshot(uint32_t capacity)
    : SharedObject(
          Kind::snapshot,
          sizeof(Block),
          capacity,
          (size_t)capacity * kCopies)
{}

uint64_t SharedSnapshot::seq() const { return snapshot()->seq.load(); }

uint32_t SharedSnapshot::valueSize(
    uint32_t index,
    std::vector<uint32_t>* holds,
    bool torn) const
{
  const Block* block = snapshot();
  uint32_t word = block->sizes[index].load(std::memory_order_relaxed);
  uint32_t bytes = std::min(word & ~kRecordHolds, block->header.capacity);
  // Locked reads skip copyTorn, so tsan still checks them.
  auto load = [&](uint32_t at) {
    uint32_t value;
    if (torn)
    {
      copyTorn(&value, copy(index) + at, 4);
    }
    else
    {
      memcpy(&value, copy(index) + at, 4);
    }
    return value;
  };
  uint32_t count = 0;
  if ((word & kRecordHolds) != 0 && bytes >= 4)
  {
    count = std::min(load(bytes - 4), (bytes - 4) / 4);
  }
  uint32_t size = bytes - (uint32_t)holdBytes(count);
  for (uint32_t i = 0; holds != nullptr && i < count; i++)
  {
    holds->push_back(load(size + i * 4));
  }
  return size;
}

bool SharedSnapshot::carriesHolds(uint32_t index) const
{
  return (snapshot()->sizes[index].load(std::memory_order_relaxed) &
          kRecordHolds) != 0;
}

bool SharedSnapshot::publish(
    Span<const uint8_t> value,
    Span<const uint32_t> holds,
    std::vector<uint32_t>* replaced)
{
  Block* block = snapshot();
  uint32_t count = (uint32_t)holds.size();
  if (value.size() + holdBytes(count) > block->header.capacity)
  {
    return false;
  }
  // Publishers take turns; readers never take the lock.
  WordGuard guard(block->header.lock);
  uint32_t latest = block->latest.load(std::memory_order_relaxed);
  if (block->header.closed != 0 ||
      (latest != 0 && replaced == nullptr && carriesHolds(latest - 1)))
  {
    return false;
  }
  if (latest != 0 && replaced != nullptr)
  {
    valueSize(latest - 1, replaced, false);
  }
  uint32_t index = latest % kCopies;
  // A publisher that died mid write left the version odd.
  uint32_t version = block->versions[index].load(std::memory_order_relaxed) | 1;
  block->versions[index].store(version, std::memory_order_relaxed);
  // Orders the odd version before the bytes, as a reader checks them.
  std::atomic_thread_fence(std::memory_order_release);
  uint8_t* to = copy(index);
  memcpy(to, value.data(), value.size());
  if (count != 0)
  {
    memcpy(to + value.size(), holds.data(), count * 4);
    memcpy(to + value.size() + count * 4, &count, 4);
  }
  block->sizes[index].store(
      sizeWord(value.size(), count),
      std::memory_order_relaxed);
  block->versions[index].store(version + 1, std::memory_order_release);
  block->latest.store(index + 1, std::memory_order_release);
  block->seq.bump();
  return true;
}

uint32_t SharedSnapshot::read(
    uint8_t* out,
    uint32_t capacity,
    std::vector<uint32_t>* holds)
{
  Block* block = snapshot();
  size_t kept = holds != nullptr ? holds->size() : 0;
  // Retries only when publishes overtook the copy.
  for (;;)
  {
    uint32_t latest = block->latest.load(std::memory_order_acquire);
    if (latest == 0)
    {
      return 0;
    }
    uint32_t index = latest - 1;
    uint32_t version = block->versions[index].load(std::memory_order_acquire);
    if ((version & 1) != 0)
    {
      continue;
    }
    uint32_t size = valueSize(index, nullptr, true);
    bool refused = holds == nullptr && carriesHolds(index);
    bool fits = !refused && out != nullptr && size <= capacity;
    if (fits && size != 0)
    {
      copyTorn(out, copy(index), size);
    }
    if (fits && holds != nullptr)
    {
      valueSize(index, holds, true);
    }
    std::atomic_thread_fence(std::memory_order_acquire);
    if (block->versions[index].load(std::memory_order_relaxed) == version)
    {
      return refused ? kCarriesHolds : size + 1;
    }
    if (holds != nullptr)
    {
      holds->resize(kept);
    }
  }
}

void SharedSnapshot::takeHolds(std::vector<uint32_t>& out)
{
  Block* block = snapshot();
  WordGuard guard(block->header.lock);
  uint32_t latest = block->latest.load(std::memory_order_relaxed);
  if (latest != 0)
  {
    valueSize(latest - 1, &out, false);
  }
  // A publish still holding the snapshot must not give them back again,
  // nor publish ones nobody would give back.
  block->latest.store(0, std::memory_order_release);
  block->header.closed = 1;
}

// --- blob --------------------------------------------------------------------

SharedBlob::SharedBlob(Span<const uint8_t> bytes)
    : SharedObject(
          Kind::blob,
          sizeof(SharedHeader),
          (uint32_t)bytes.size(),
          bytes.size())
{
  if (made() && !bytes.empty())
  {
    memcpy(data(), bytes.data(), bytes.size());
  }
}

uint32_t SharedBlob::read(uint32_t offset, uint8_t* out, uint32_t capacity)
    const
{
  if (offset >= size())
  {
    return 0;
  }
  uint32_t count = std::min(capacity, size() - offset);
  memcpy(out, data() + offset, count);
  return count;
}

// --- registry ----------------------------------------------------------------

namespace
{
constexpr uint32_t kNoSlot = UINT32_MAX;

SharedTable& sharedTable()
{
  // Never destroyed, so an object released during static teardown finds
  // it, and never allocated, so it cannot fail.
  static SharedTable table;
  static SharedSlot firstChunk[kChunkSlots];
  static bool ready = []() {
    table.freeHead = kNoSlot;
    table.freeTail = kNoSlot;
    table.chunks[0].store(firstChunk);
    return true;
  }();
  (void)ready;
  return table;
}

struct OwnerBudget
{
  uint64_t owner;
  uint64_t charged;
  uint64_t limit;
  uint32_t objects;
  OwnerBudget* next;
};

LaneMutex& budgetMutex()
{
  static LaneMutex mutex;
  return mutex;
}

// One per live VM, few enough to scan; never destroyed, as a release in
// static teardown refunds.
OwnerBudget* s_ownerBudgets = nullptr;

// The link holding owner's budget, null once its VM went; under budgetMutex.
OwnerBudget*& budgetOf(uint64_t owner)
{
  OwnerBudget** at = &s_ownerBudgets;
  while (*at != nullptr && (*at)->owner != owner)
  {
    at = &(*at)->next;
  }
  return *at;
}

// Counts one more object against owner's cap; false when it has them all or
// its VM went, though a lane of it may still run.
bool countObject(uint64_t owner)
{
  std::lock_guard<LaneMutex> lock(budgetMutex());
  OwnerBudget* budget = budgetOf(owner);
  if (budget == nullptr || budget->objects == kSharedMaxObjects)
  {
    return false;
  }
  budget->objects++;
  return true;
}

void giveBack(uint64_t owner, uint64_t bytes, uint32_t objects)
{
  std::lock_guard<LaneMutex> lock(budgetMutex());
  if (OwnerBudget* budget = budgetOf(owner))
  {
    budget->charged -= std::min(budget->charged, bytes);
    budget->objects -= std::min(budget->objects, objects);
  }
}

thread_local uint32_t t_heldRegion = 0;
thread_local SharedRegion* t_heldObject = nullptr;

// Regions this thread's call used lately, so an atomic skips the pin writes
// on the registry slot every lane of the region shares.
struct RecentRegion
{
  uint32_t id;
  uint64_t owner;
  SharedSlot* slot;
  SharedRegion* region;
};
thread_local RecentRegion t_recentRegions[4] = {};
thread_local uint32_t t_recentNext = 0;

uint32_t indexOf(uint32_t id) { return (id & ~kIdBit) >> kIdSlotShift; }

uint32_t idOf(uint32_t index, uint32_t state)
{
  return kIdBit | (index << kIdSlotShift) | (state & kIdGenerationMask);
}

bool names(uint32_t state, uint32_t id)
{
  return (state & kSlotLive) != 0 && ((state ^ id) & kIdGenerationMask) == 0;
}

SharedSlot* slotAt(SharedTable& table, uint32_t index)
{
  SharedSlot* chunk = table.chunks[index >> kChunkShift].load(
      std::memory_order_acquire);
  return chunk != nullptr ? chunk + (index & (kChunkSlots - 1)) : nullptr;
}

SharedSlot* slotOf(SharedTable& table, uint32_t id)
{
  return (id & kIdBit) != 0 ? slotAt(table, indexOf(id)) : nullptr;
}

bool pin(SharedSlot& slot, uint32_t id)
{
  uint32_t state = slot.state.load(std::memory_order_relaxed);
  do
  {
    if (!names(state, id))
    {
      return false;
    }
  } while (!compareExchangeWeak(
      slot.state,
      state,
      state + kSlotPin,
      std::memory_order_acquire,
      std::memory_order_relaxed));
  return true;
}

bool held(const SharedTable& table, const SharedSlot& slot)
{
  if (slot.state.load(std::memory_order_acquire) >= kSlotPin)
  {
    return true;
  }
  // Sequentially consistent against the release's retire: a lane either
  // sees the slot retired or is seen here.
  for (const auto& lane : table.lanes)
  {
    if (lane.load(std::memory_order_seq_cst) == (uintptr_t)&slot)
    {
      return true;
    }
  }
  return false;
}

// Waits out the slot's lookups outside the lock, then frees it for reuse,
// appending the holds its object carried for the caller to give back.
void retire(
    SharedTable& table,
    SharedSlot& slot,
    uint32_t index,
    std::vector<uint32_t>& holds)
{
  spinUntil([&]() { return !held(table, slot); });
  SharedObject* object = slot.object.exchange(
      nullptr,
      std::memory_order_relaxed);
  uint64_t owner = slot.owner.load(std::memory_order_relaxed);
  slot.block.store(nullptr, std::memory_order_relaxed);
  slot.owner.store(0, std::memory_order_relaxed);
  {
    // Oldest first, so a stale id only aliases a new object after its
    // slot went round every free slot 4096 times.
    WordGuard guard(table.lock);
    slot.nextFree = kNoSlot;
    if (table.freeTail == kNoSlot)
    {
      table.freeHead = index;
    }
    else
    {
      slotAt(table, table.freeTail)->nextFree = index;
    }
    table.freeTail = index;
  }
  object->takeHolds(holds);
  giveBack(owner, object->charge, 1);
  object->unref();
}

// Gives back a hold, or every hold when forced, answering whether that was
// the last, so the caller retires the slot it now took out of use.
bool dropHold(SharedSlot& slot, uint32_t id, uint64_t owner, bool force)
{
  uint32_t state = slot.state.load(std::memory_order_relaxed);
  if (!names(state, id) || slot.owner.load(std::memory_order_relaxed) != owner)
  {
    return false;
  }
  SharedObject* object = slot.object.load(std::memory_order_relaxed);
  if (!force && --object->holds != 0)
  {
    return false;
  }
  // Lookups still move the pins; only the lock holder moves the rest.
  uint32_t retired;
  do
  {
    retired = (state & ~(kSlotLive | kIdGenerationMask)) |
              ((state + 1) & kIdGenerationMask);
  } while (!compareExchangeWeak(
      slot.state,
      state,
      retired,
      std::memory_order_seq_cst,
      std::memory_order_relaxed));
  return true;
}

// A retired object's holds go in turn rather than by recursion, which a long
// chain of objects holding the next would overflow the stack with.
void releaseSlot(uint32_t id, uint64_t owner, bool force)
{
  SharedTable& table = sharedTable();
  std::vector<uint32_t> holds;
  for (;;)
  {
    SharedSlot* slot = slotOf(table, id);
    bool last = false;
    if (slot != nullptr)
    {
      WordGuard guard(table.lock);
      last = dropHold(*slot, id, owner, force);
    }
    if (last)
    {
      retire(table, *slot, indexOf(id), holds);
    }
    if (holds.empty())
    {
      return;
    }
    id = holds.back();
    holds.pop_back();
    force = false;
  }
}
} // namespace

SharedTable* SharedRegistry::table() { return &sharedTable(); }

#if defined(__EMSCRIPTEN__) && RIVE_PROCESSOR_AUDIO()
// For a lane without librive, which reaches shared objects through it.
extern "C" EMSCRIPTEN_KEEPALIVE uint32_t rive_shared_table()
{
  return (uint32_t)(uintptr_t)SharedRegistry::table();
}
#endif

uint32_t SharedRegistry::add(rcp<SharedObject> object, uint64_t owner)
{
  if (!countObject(owner))
  {
    return kCreateTooMany;
  }
  SharedTable& table = sharedTable();
  uint32_t index;
  for (;;)
  {
    uint32_t next;
    {
      WordGuard guard(table.lock);
      index = table.freeHead;
      if (index != kNoSlot)
      {
        table.freeHead = slotAt(table, index)->nextFree;
        if (table.freeHead == kNoSlot)
        {
          table.freeTail = kNoSlot;
        }
        break;
      }
      index = table.count.load(std::memory_order_relaxed);
      if (index == kChunkCount * kChunkSlots)
      {
        index = kNoSlot;
        break;
      }
      next = index >> kChunkShift;
      if (table.chunks[next].load(std::memory_order_relaxed) != nullptr)
      {
        table.count.store(index + 1, std::memory_order_release);
        break;
      }
    }
    // Made outside the lock before its first slot is taken, so a taken
    // slot always has one; a racing add that made one too frees its own.
    auto* made = (SharedSlot*)calloc(kChunkSlots, sizeof(SharedSlot));
    if (made == nullptr)
    {
      index = kNoSlot;
      break;
    }
    SharedSlot* expected = nullptr;
    if (!compareExchangeStrong(
            table.chunks[next],
            expected,
            made,
            std::memory_order_acq_rel))
    {
      free(made);
    }
  }
  if (index == kNoSlot)
  {
    giveBack(owner, 0, 1);
    return kCreateFull;
  }
  SharedSlot* slot = slotAt(table, index);
  slot->owner.store(owner, std::memory_order_relaxed);
  slot->block.store(object->block(), std::memory_order_relaxed);
  slot->object.store(object.release(), std::memory_order_relaxed);
  // Nothing pins a slot that is not live, so its state is the generation.
  uint32_t state = slot->state.load(std::memory_order_relaxed);
  slot->state.store(state | kSlotLive, std::memory_order_release);
  return idOf(index, state);
}

rcp<SharedObject> SharedRegistry::find(
    uint32_t id,
    SharedObject::Kind kind,
    uint64_t owner)
{
  SharedSlot* slot = slotOf(sharedTable(), id);
  if (slot == nullptr || !pin(*slot, id))
  {
    return nullptr;
  }
  SharedObject* object = slot->object.load(std::memory_order_relaxed);
  rcp<SharedObject> found = object->kind() == kind &&
                                    slot->owner.load(
                                        std::memory_order_relaxed) == owner
                                ? ref_rcp(object)
                                : nullptr;
  slot->state.fetch_sub(kSlotPin, std::memory_order_release);
  return found;
}

// What id names for owner, called under the table's lock; else null.
static SharedObject* ownedObject(SharedSlot* slot, uint32_t id, uint64_t owner)
{
  if (slot == nullptr ||
      !names(slot->state.load(std::memory_order_relaxed), id) ||
      slot->owner.load(std::memory_order_relaxed) != owner)
  {
    return nullptr;
  }
  return slot->object.load(std::memory_order_relaxed);
}

bool SharedRegistry::retain(uint32_t id, uint64_t owner)
{
  SharedTable& table = sharedTable();
  SharedSlot* slot = slotOf(table, id);
  WordGuard guard(table.lock);
  SharedObject* object = ownedObject(slot, id, owner);
  if (object == nullptr)
  {
    return false;
  }
  object->holds++;
  return true;
}

uint32_t SharedRegistry::holds(uint32_t id, uint64_t owner)
{
  SharedTable& table = sharedTable();
  SharedSlot* slot = slotOf(table, id);
  WordGuard guard(table.lock);
  SharedObject* object = ownedObject(slot, id, owner);
  return object != nullptr ? object->holds : 0;
}

void SharedRegistry::release(uint32_t id, uint64_t owner)
{
  releaseSlot(id, owner, false);
}

void SharedRegistry::releaseOwner(uint64_t owner)
{
  // First, so a lane still running creates no more.
  {
    std::lock_guard<LaneMutex> lock(budgetMutex());
    OwnerBudget*& link = budgetOf(owner);
    if (OwnerBudget* gone = link)
    {
      link = gone->next;
      delete gone;
    }
  }
  SharedTable& table = sharedTable();
  uint32_t count = table.count.load(std::memory_order_acquire);
  for (uint32_t index = 0; index < count; index++)
  {
    SharedSlot* slot = slotAt(table, index);
    if (slot == nullptr)
    {
      continue;
    }
    uint32_t state = slot->state.load(std::memory_order_acquire);
    if ((state & kSlotLive) != 0 &&
        slot->owner.load(std::memory_order_relaxed) == owner)
    {
      releaseSlot(idOf(index, state), owner, true);
    }
  }
}

uint32_t SharedRegistry::ringOf(uint32_t signal, uint64_t owner, bool& space)
{
  SharedTable& table = sharedTable();
  uint32_t count = table.count.load(std::memory_order_acquire);
  for (uint32_t index = 0; index < count; index++)
  {
    SharedSlot* slot = slotAt(table, index);
    if (slot == nullptr)
    {
      continue;
    }
    uint32_t id = idOf(index, slot->state.load(std::memory_order_acquire));
    rcp<SharedRing> ring = find<SharedRing>(id, owner);
    if (ring != nullptr &&
        (ring->dataSignalId() == signal || ring->spaceSignalId() == signal))
    {
      space = ring->spaceSignalId() == signal;
      return id;
    }
  }
  return 0;
}

bool SharedRegistry::charge(uint64_t owner, uint64_t bytes)
{
  if (bytes == 0)
  {
    return true;
  }
  std::lock_guard<LaneMutex> lock(budgetMutex());
  OwnerBudget* budget = budgetOf(owner);
  if (budget == nullptr || bytes > budget->limit - budget->charged)
  {
    return false;
  }
  budget->charged += bytes;
  return true;
}

void SharedRegistry::refund(uint64_t owner, uint64_t bytes)
{
  giveBack(owner, bytes, 0);
}

uint64_t SharedRegistry::nextOwner(uint64_t byteBudget)
{
  static std::atomic<uint64_t> next{1};
  uint64_t owner = next.fetch_add(1);
  std::lock_guard<LaneMutex> lock(budgetMutex());
  s_ownerBudgets = new OwnerBudget{owner, 0, byteBudget, 0, s_ownerBudgets};
  return owner;
}

uint32_t rive::sharedHeldRegion() { return t_heldRegion; }

SharedRegion* rive::sharedHeld(uint32_t id)
{
  return id != 0 && id == t_heldRegion ? t_heldObject : nullptr;
}

void rive::setSharedHeldRegion(uint32_t id, rcp<SharedRegion> region)
{
  // The held reference is manual so a thread_local needs no destructor.
  safe_unref(t_heldObject);
  t_heldRegion = id;
  t_heldObject = region.release();
}

SharedRegion* rive::sharedRecentRegion(uint32_t id, uint64_t owner)
{
  for (RecentRegion& recent : t_recentRegions)
  {
    if (recent.region != nullptr && recent.id == id && recent.owner == owner)
    {
      // The generation wraps, so the slot must still hold this very region.
      if (names(recent.slot->state.load(std::memory_order_acquire), id) &&
          recent.slot->object.load(std::memory_order_relaxed) == recent.region)
      {
        return recent.region;
      }
      safe_unref(recent.region);
      recent = {};
    }
  }
  rcp<SharedRegion> found = SharedRegistry::find<SharedRegion>(id, owner);
  if (found == nullptr)
  {
    return nullptr;
  }
  RecentRegion& recent = t_recentRegions[t_recentNext++ & 3];
  safe_unref(recent.region);
  recent = {id, owner, slotOf(sharedTable(), id), found.release()};
  return recent.region;
}

void rive::forgetRecentRegions()
{
  for (RecentRegion& recent : t_recentRegions)
  {
    safe_unref(recent.region);
    recent = {};
  }
}

void rive::releaseTrappedRegion()
{
  forgetRecentRegions();
  SharedRegion* region = t_heldObject;
  if (region == nullptr)
  {
    return;
  }
  // The trap may have stopped mid update, so the bytes are suspect.
  region->poison();
  region->unlock();
  setSharedHeldRegion(0, nullptr);
}

SharedRegion* rive::stashHeldRegion(uint32_t* id)
{
  SharedRegion* region = t_heldObject;
  *id = t_heldRegion;
  t_heldRegion = 0;
  t_heldObject = nullptr;
  return region;
}

void rive::restoreHeldRegion(uint32_t id, SharedRegion* region)
{
  releaseTrappedRegion();
  t_heldRegion = id;
  t_heldObject = region;
}

#endif
