Ejemplo n.º 1
0
void emitCreateCont(IRGS& env) {
  auto const resumeOffset = nextBcOff(env);
  assertx(!resumed(env));
  assertx(curFunc(env)->isGenerator());

  if (curFunc(env)->isAsyncGenerator()) PUNT(CreateCont-AsyncGenerator);

  // Create the Generator object. CreateCont takes care of copying local
  // variables and iterators.
  auto const func = curFunc(env);
  auto const resumeSk = SrcKey(func, resumeOffset, true);
  auto const bind_data = LdBindAddrData { resumeSk, invSPOff(env) + 1 };
  auto const resumeAddr = gen(env, LdBindAddr, bind_data);
  auto const cont =
    gen(env,
        CreateCont,
        fp(env),
        cns(env, func->numSlotsInFrame()),
        resumeAddr,
        cns(env, resumeOffset));

  // The suspend hook will decref the newly created generator if it throws.
  auto const contAR =
    gen(env,
        LdContActRec,
        IsAsyncData(curFunc(env)->isAsync()),
        cont);
  suspendHookE(env, fp(env), contAR, cont);

  // Grab caller info from ActRec, free ActRec, store the return value
  // and return control to the caller.
  gen(env, StRetVal, fp(env), cont);
  auto const ret_data = RetCtrlData { offsetToReturnSlot(env), false };
  gen(env, RetCtrl, ret_data, sp(env), fp(env));
}
Ejemplo n.º 2
0
void emitCreateCont(HTS& env) {
  auto const resumeOffset = nextBcOff(env);
  assert(!resumed(env));
  assert(curFunc(env)->isGenerator());

  if (curFunc(env)->isAsyncGenerator()) PUNT(CreateCont-AsyncGenerator);

  // Create the Generator object. CreateCont takes care of copying local
  // variables and iterators.
  auto const func = curFunc(env);
  auto const resumeSk = SrcKey(func, resumeOffset, true);
  auto const resumeAddr = gen(env, LdBindAddr, LdBindAddrData(resumeSk));
  auto const cont =
    gen(env,
        CreateCont,
        fp(env),
        cns(env, func->numSlotsInFrame()),
        resumeAddr,
        cns(env, resumeOffset));

  // The suspend hook will decref the newly created generator if it throws.
  auto const contAR = gen(env, LdContActRec, cont);
  suspendHookE(env, fp(env), contAR);

  // Grab caller info from ActRec, free ActRec, store the return value
  // and return control to the caller.
  gen(env, StRetVal, fp(env), cont);
  auto const retAddr = gen(env, LdRetAddr, fp(env));
  auto const stack = gen(env, RetAdjustStack, fp(env));
  auto const frame = gen(env, FreeActRec, fp(env));
  gen(env, RetCtrl, RetCtrlData(false), stack, frame, retAddr);
}