22 #ifndef MTROPOLIS_COROUTINES_H 23 #define MTROPOLIS_COROUTINES_H 25 #include "mtropolis/coroutine_protos.h" 26 #include "mtropolis/miniscript_protos.h" 27 #include "mtropolis/vthread.h" 32 struct CoroutineRuntimeState;
34 typedef VThreadState (*CoroutineFragmentFunction_t)(CoroutineRuntimeState &coroState);
42 MiniscriptInstructionOutcome _miniscriptOutcome;
54 CoroutineFrameConstructor_t _frameConstructor;
55 CoroutineGetFrameParametersFunction_t _getFrameParameters;
59 uint _numInstructions;
70 VThreadState execute(
VThread *thread)
override;
122 virtual void defineFunction(CoroutineFrameConstructor_t frameConstructor, CoroutineGetFrameParametersFunction_t frameGetParams) = 0;
123 virtual void addOp(CoroOps op, CoroutineFragmentFunction_t fragmentFunc) = 0;
126 #define CORO_START_CODE_BLOCK(op) \ 127 compiler->addOp(op, [](CoroutineRuntimeState &coroRuntime) -> VThreadState { \ 128 Params *params = &static_cast<CoroStackFrame *>(coroRuntime._frame)->_params; \ 129 Locals *locals = &static_cast<CoroStackFrame *>(coroRuntime._frame)->_locals; \ 130 CoroutineReturnValueRef<ReturnValue_t> coroReturnValueRef = (static_cast<CoroStackFrame *>(coroRuntime._frame)->_rvRef); 132 #define CORO_AWAIT_PUSHED_TASK \ 133 return kVThreadReturn 135 #define CORO_DISUSE_CODE_BLOCK_VARS \ 138 (void)coroReturnValueRef; 140 #define CORO_END_CODE_BLOCK \ 141 CORO_DISUSE_CODE_BLOCK_VARS \ 142 return kVThreadReturn; \ 145 #define CORO_BEGIN_DEFINITION(type) \ 146 CompiledCoroutine *type::ms_compiledCoro = nullptr;\ 147 void type::compileCoroutine(ICoroutineCompiler *compiler) { 149 #define CORO_END_DEFINITION \ 152 #define CORO_BEGIN_FUNCTION \ 153 struct CoroStackFrame : public CoroutineStackFrame2 {\ 156 CoroutineReturnValueRef<ReturnValue_t> _rvRef;\ 157 explicit CoroStackFrame(const CompiledCoroutine *compiledCoro, const Params ¶ms, const CoroutineReturnValueRef<ReturnValue_t> &rvRef)\ 158 : CoroutineStackFrame2(compiledCoro), _params(params), _rvRef(rvRef) {\ 160 static CoroutineStackFrame2 *constructFrame(void *ptr, const CompiledCoroutine *compiledCoro, const CoroutineParamsBase ¶ms, const CoroutineReturnValueRefBase &returnValueRef) {\ 161 return new (ptr) CoroStackFrame(compiledCoro, static_cast<const Params &>(params), static_cast<const CoroutineReturnValueRef<ReturnValue_t>&>(returnValueRef));\ 163 static void getFrameParameters(size_t &outSize, size_t &outAlignment) { \ 164 outSize = sizeof(CoroStackFrame); \ 165 outAlignment = alignof(CoroStackFrame); \ 168 compiler->defineFunction(CoroStackFrame::constructFrame, CoroStackFrame::getFrameParameters); \ 169 CORO_START_CODE_BLOCK(CoroOps::BeginFunction) 171 #define CORO_END_FUNCTION \ 172 CORO_END_CODE_BLOCK \ 173 CORO_START_CODE_BLOCK(CoroOps::EndFunction) \ 176 #define CORO_AWAIT(expr) \ 178 CORO_END_CODE_BLOCK \ 179 CORO_START_CODE_BLOCK(CoroOps::YieldToFunction) \ 180 CORO_END_CODE_BLOCK \ 181 CORO_START_CODE_BLOCK(CoroOps::Code) 183 #define CORO_AWAIT_MINISCRIPT(expr) \ 184 coroRuntime._miniscriptOutcome = ((expr)); \ 185 CORO_END_CODE_BLOCK \ 186 CORO_START_CODE_BLOCK(CoroOps::CheckMiniscript) \ 187 CORO_END_CODE_BLOCK \ 188 CORO_START_CODE_BLOCK(CoroOps::Code) 190 #define CORO_IF(expr) \ 191 CORO_END_CODE_BLOCK \ 192 CORO_START_CODE_BLOCK(CoroOps::IfCond) \ 193 coroRuntime._condition = !!(expr); \ 194 CORO_END_CODE_BLOCK \ 195 CORO_START_CODE_BLOCK(CoroOps::IfBody) 198 CORO_END_CODE_BLOCK \ 199 CORO_START_CODE_BLOCK(CoroOps::Else) 201 #define CORO_ELSE_IF(expr) \ 202 CORO_END_CODE_BLOCK \ 203 CORO_START_CODE_BLOCK(CoroOps::ElseIfCond) \ 204 coroRuntime._condition = !!(expr); \ 205 CORO_END_CODE_BLOCK \ 206 CORO_START_CODE_BLOCK(CoroOps::ElseIfBody) 208 #define CORO_END_IF \ 209 CORO_END_CODE_BLOCK \ 210 CORO_START_CODE_BLOCK(CoroOps::EndIf) 212 #define CORO_WHILE(expr) \ 213 CORO_END_CODE_BLOCK \ 214 CORO_START_CODE_BLOCK(CoroOps::WhileCond) \ 215 coroRuntime._condition = !!(expr); \ 216 CORO_END_CODE_BLOCK \ 217 CORO_START_CODE_BLOCK(CoroOps::WhileBody) 219 #define CORO_END_WHILE \ 220 CORO_END_CODE_BLOCK \ 221 CORO_START_CODE_BLOCK(CoroOps::EndWhile) 224 CORO_END_CODE_BLOCK \ 225 CORO_START_CODE_BLOCK(CoroOps::Do) 227 #define CORO_DO_WHILE(expr) \ 228 CORO_END_CODE_BLOCK \ 229 CORO_START_CODE_BLOCK(CoroOps::DoWhileCond) \ 230 coroCondition = !(expr); \ 231 CORO_END_CODE_BLOCK \ 232 CORO_START_CODE_BLOCK(CoroOps::DoWhile) 234 #define CORO_FOR(initExpr, condExpr, nextExpr) \ 236 CORO_END_CODE_BLOCK \ 237 CORO_START_CODE_BLOCK(CoroOps::ForNext) \ 239 CORO_END_CODE_BLOCK \ 240 CORO_START_CODE_BLOCK(CoroOps::ForCond) \ 241 coroRuntime._condition = !!(condExpr); \ 242 CORO_END_CODE_BLOCK \ 243 CORO_START_CODE_BLOCK(CoroOps::ForBody) 245 #define CORO_END_FOR \ 246 CORO_END_CODE_BLOCK \ 247 CORO_START_CODE_BLOCK(CoroOps::EndFor) 249 #define CORO_RETURN_VALUE(expr) \ 250 coroReturnValueRef.set((expr)); \ 251 CORO_END_CODE_BLOCK \ 252 CORO_START_CODE_BLOCK(CoroOps::Return) 255 CORO_END_CODE_BLOCK \ 256 CORO_START_CODE_BLOCK(CoroOps::Error) 259 #define CORO_RETURN \ 260 coroReturnValueRef.voidSet(); \ 261 CORO_END_CODE_BLOCK \ 262 CORO_START_CODE_BLOCK(CoroOps::Return) 264 #define CORO_RETURN_CALL(func, ...) \ 265 coroFrame->pushFrame<CoroAutoFrame<func> >(coroReturnValueRef._returnValue, __VA_ARGS__); \ 266 CORO_END_CODE_BLOCK \ 267 CORO_START_CODE_BLOCK(CoroOps::YieldToFunction) \ 268 CORO_END_CODE_BLOCK \ 269 CORO_START_CODE_BLOCK(CoroOps::Return) 271 #define CORO_SET_CALL(dest, func, ...) \ 272 CORO_AWAIT(coroRuntime._vthread->pushCoroutineWithReturn<func>(&(dest), __VA_ARGS__)) 274 #define CORO_CALL(func, ...) \ 275 CORO_AWAIT(coroRuntime._vthread->pushCoroutine<func>(__VA_ARGS__)) Definition: coroutines.h:66
Definition: coroutine_exec.h:42
Definition: coroutines.h:36
Definition: coroutines.h:119
Definition: coroutines.h:50
Definition: vthread.h:133