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)); }
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); }