c_AsyncFunctionWaitHandle*
c_AsyncFunctionWaitHandle::Create(const ActRec* fp,
                                  size_t numSlots,
                                  jit::TCA resumeAddr,
                                  Offset resumeOffset,
                                  c_WaitableWaitHandle* child) {
  assert(fp);
  assert(!fp->resumed());
  assert(fp->func()->isAsyncFunction());
  assert(child);
  assert(child->instanceof(c_WaitableWaitHandle::classof()));
  assert(!child->isFinished());

  constexpr const size_t objSize = sizeof(c_AsyncFunctionWaitHandle);
  void* obj = Resumable::Create<false, objSize, mayUseVV>(fp,
                                                          numSlots,
                                                          resumeAddr,
                                                          resumeOffset);
  auto const waitHandle = new (obj) c_AsyncFunctionWaitHandle();
  assert(waitHandle->hasExactlyOneRef());
  waitHandle->actRec()->setReturnVMExit();
  assert(waitHandle->noDestruct());
  waitHandle->initialize(child);
  return waitHandle;
}
c_AsyncFunctionWaitHandle*
c_AsyncFunctionWaitHandle::Create(const ActRec* fp,
                                  size_t numSlots,
                                  jit::TCA resumeAddr,
                                  Offset resumeOffset,
                                  c_WaitableWaitHandle* child) {
  assert(fp);
  assert(!fp->resumed());
  assert(fp->func()->isAsyncFunction());
  assert(child);
  assert(child->instanceof(c_WaitableWaitHandle::classof()));
  assert(!child->isFinished());

  const size_t frameSize = Resumable::getFrameSize(numSlots);
  const size_t totalSize = sizeof(ResumableNode) + frameSize +
                           sizeof(Resumable) +
                           sizeof(c_AsyncFunctionWaitHandle);
  auto const resumable = Resumable::Create(frameSize, totalSize);
  resumable->initialize<false, mayUseVV>(fp,
                                         resumeAddr,
                                         resumeOffset,
                                         frameSize,
                                         totalSize);
  auto const waitHandle = new (resumable + 1) c_AsyncFunctionWaitHandle();
  assert(waitHandle->hasExactlyOneRef());
  waitHandle->actRec()->setReturnVMExit();
  assert(waitHandle->noDestruct());
  waitHandle->initialize(child);
  return waitHandle;
}
ObjectData*
AsyncGenerator::Create(const ActRec* fp, size_t numSlots,
                       jit::TCA resumeAddr, Offset resumeOffset) {
  assert(fp);
  assert(!fp->resumed());
  assert(fp->func()->isAsyncGenerator());
  void* genDataPtr = Resumable::Create<false,
                       sizeof(AsyncGenerator) + sizeof(c_AsyncGenerator)>(
                       fp, numSlots, resumeAddr, resumeOffset);
  AsyncGenerator* genData = new (genDataPtr) AsyncGenerator();
  auto const gen = new (genData + 1) c_AsyncGenerator();
  assert(gen->hasExactlyOneRef());
  assert(gen->noDestruct());
  genData->setState(State::Created);
  genData->m_waitHandle = nullptr;
  return static_cast<ObjectData*>(gen);
}