Eager execution of async function.

Currently, a call to an async function returns a (Continuation)WaitHandle
object but the excution of the function body doesn't start before await
(or join()) on the WaitHandle is called. This changes it to start the
execution immediately and the control is returned to the caller only
after it's blocked.

Differential Revision: D946914
Esse commit está contido em:
Mirek Klimos
2013-08-05 20:04:50 -07:00
commit de Sara Golemon
commit 705d2ac5cd
19 arquivos alterados com 313 adições e 42 exclusões
+32
Ver Arquivo
@@ -6651,6 +6651,38 @@ inline void OPTBLD_INLINE VMExecutionContext::iopCreateCont(PC& pc) {
ret->m_data.pobj = cont;
}
inline void OPTBLD_INLINE VMExecutionContext::iopCreateAsync(PC& pc) {
NEXT();
DECODE_LITSTR(genName);
DECODE_IVA(label);
DECODE_IVA(iters);
const Func* origFunc = m_fp->m_func;
const Func* genFunc = origFunc->getGeneratorBody(genName);
assert(genFunc != nullptr);
c_Continuation* cont = origFunc->isMethod()
? createContMeth(origFunc, genFunc, m_fp->getThisOrClass())
: createContFunc(origFunc, genFunc);
// TODO: we should check that the value on top of the stack is indeed
// a WaitHandle and fatal if not. Also, if it is a wait handle, assert
// that it is not finished.
cont->t_update(label, tvAsCVarRef(m_stack.topTV()));
m_stack.popTV();
fillContinuationVars(m_fp, origFunc, cont->actRec(), genFunc);
// copy the state of all the iterators at once
memcpy(frame_iter(cont->actRec(), iters-1),
frame_iter(m_fp, iters-1),
iters * sizeof(Iter));
TypedValue* ret = m_stack.allocTV();
ret->m_type = KindOfObject;
ret->m_data.pobj = cont;
}
static inline c_Continuation* this_continuation(const ActRec* fp) {
ObjectData* obj = fp->getThis();
assert(obj->instanceof(c_Continuation::s_cls));