IO_METHOD(IoCoroutine, currentCoroutine) { /*doc Coroutine currentCoroutine Returns currently running coroutine in Io state. */ return IoState_currentCoroutine(IOSTATE); }
IoObject *IoObject_performWithDebugger(IoCoroutine *self, IoObject *locals, IoMessage *m) { IoState *state = IOSTATE; IoObject *currentCoroutine = IoState_currentCoroutine(state); if (IoCoroutine_rawDebuggingOn(currentCoroutine)) { IoObject *debugger = state->debugger; // stack retain it? if (debugger) { IoObject_setSlot_to_(debugger, IOSYMBOL("messageCoroutine"), currentCoroutine); IoObject_setSlot_to_(debugger, IOSYMBOL("messageSelf"), self); IoObject_setSlot_to_(debugger, IOSYMBOL("messageLocals"), locals); IoObject_setSlot_to_(debugger, IOSYMBOL("message"), m); { IoObject *context; IoCoroutine *c = IoObject_rawGetSlot_context_(debugger, IOSYMBOL("debuggerCoroutine"), &context); IOASSERT(c, "Debugger needs a debuggerCoroutine slot"); IoCoroutine_rawResume(c); } } } return IoObject_perform(self, locals, m); }
void IoCoroutine_rawRun(IoCoroutine *self) { Coro *coro = DATA(self)->cid; if (!coro) { coro = Coro_new(); DATA(self)->cid = coro; } { IoObject *stackSize = IoObject_getSlot_(self, IOSTATE->stackSizeSymbol); if(ISNUMBER(stackSize)) { Coro_setStackSize_(coro, CNUMBER(stackSize)); } } { IoCoroutine *current = IoState_currentCoroutine(IOSTATE); Coro *currentCoro = IoCoroutine_rawCoro(current); //IoState_stackRetain_(IOSTATE, self); Coro_startCoro_(currentCoro, coro, self, (CoroStartCallback *)IoCoroutine_coroStart); //IoState_setCurrentCoroutine_(IOSTATE, current); } }
IoCoroutine *IoCoroutine_newWithTry(void *state, IoObject *target, IoObject *locals, IoMessage *message) { IoCoroutine *self = IoCoroutine_new(state); //IoCoroutine_try(self, target, locals, message); IoCoroutine *currentCoro = (IoCoroutine *)IoState_currentCoroutine((IoState *)IOSTATE); IoCoroutine_rawSetRunTarget_(self, target); IoCoroutine_rawSetRunLocals_(self, locals); IoCoroutine_rawSetRunMessage_(self, message); IoCoroutine_rawSetParentCoroutine_(self, currentCoro); IoCoroutine *self = (IoCoroutine *)context; IoObject *result; IoState_setCurrentCoroutine_(IOSTATE, self); //printf("%p-%p start\n", (void *)self, (void *)DATA(self)->cid); result = IoMessage_locals_performOn_(IOSTATE->mainMessage, self, self); IoCoroutine_rawSetResult_(self, result); IoCoroutine_rawReturnToParent(self); // return from newwithTry return self; }
IO_METHOD(IoCoroutine, isCurrent) { /*doc Coroutine isCurrent Returns true if the receiver is currently running coroutine. */ IoObject *v = IOBOOL(self, self == IoState_currentCoroutine(IOSTATE)); return v; }
void IoCoroutine_try(IoCoroutine *self, IoObject *target, IoObject *locals, IoMessage *message) { IoCoroutine *currentCoro = (IoCoroutine *)IoState_currentCoroutine((IoState *)IOSTATE); IoCoroutine_rawSetRunTarget_(self, target); IoCoroutine_rawSetRunLocals_(self, locals); IoCoroutine_rawSetRunMessage_(self, message); IoCoroutine_rawSetParentCoroutine_(self, currentCoro); IoCoroutine_rawRun(self); }
IoMessage *IoMessage_newParseNextMessageChain(void *state, IoLexer *lexer) { IoCoroutine *current = IoState_currentCoroutine(state); Coro *coro = IoCoroutine_cid(current); size_t left = Coro_bytesLeftOnStack(coro); /* if (Coro_stackSpaceAlmostGone(coro)) { // need to make Coroutine support a stack of Coros which it frees when released // return IoCoroutine_internallyChain(current, context, IoMessage_...); Coro *newCoro = Coro_new(); ParseContext p = {state, lexer, newCoro, coro, NULL}; printf("Warning IoMessage_newParseNextMessageChain doing callc with %i bytes left to avoid stack overflow\n", left); Coro_startCoro_(coro, newCoro, &p, (CoroStartCallback *)IoMessage_coroNewParseNextMessageChain); Coro_free(newCoro); return p.result; } */ IoMessage *self = IoMessage_new(state); if (IoTokenType_isValidMessageName(IoLexer_topType(lexer))) { IoMessage_parseName(self, lexer); } if (IoLexer_topType(lexer) == OPENPAREN_TOKEN) { IoMessage_parseArgs(self, lexer); } if (IoTokenType_isValidMessageName(IoLexer_topType(lexer))) { IoMessage_parseNext(self, lexer); } while (IoLexer_topType(lexer) == TERMINATOR_TOKEN) { IoLexer_pop(lexer); if (IoTokenType_isValidMessageName(IoLexer_topType(lexer))) { IoMessage *eol = IoMessage_newWithName_(state, ((IoState*)state)->semicolonSymbol); IoMessage_rawSetNext(self, eol); IoMessage_parseNext(eol, lexer); } } return self; }
IoObject *IoCoroutine_freeStack(IoCoroutine *self, IoObject *locals, IoMessage *m) { IoCoroutine *current = IoState_currentCoroutine(IOSTATE); if (current != self && DATA(self)->cid) { Coro_free(DATA(self)->cid); DATA(self)->cid = NULL; } return self; }
IO_METHOD(IoCoroutine, freeStack) { /*doc Coroutine freeStack Frees all the internal data from the receiver's stack. Returns self. */ IoCoroutine *current = IoState_currentCoroutine(IOSTATE); if (current != self && DATA(self)->cid) { Coro_free(DATA(self)->cid); DATA(self)->cid = NULL; } return self; }
IoObject *IoCoroutine_rawResume(IoCoroutine *self) { if(DATA(self)->cid) { IoCoroutine *current = IoState_currentCoroutine(IOSTATE); IoState_setCurrentCoroutine_(IOSTATE, self); //printf("IoCoroutine resuming %p\n", (void *)self); Coro_switchTo_(IoCoroutine_rawCoro(current), IoCoroutine_rawCoro(self)); //IoState_setCurrentCoroutine_(IOSTATE, current); } else { //printf("IoCoroutine_rawResume: can't resume coro that hasn't been run - so running it\n"); IoCoroutine_rawRun(self); } return self; }
void IoState_error_(IoState *self, IoMessage *m, const char *format, ...) { IoSymbol *description; va_list ap; va_start(ap, format); description = IoState_symbolWithUArray_copy_(self, UArray_newWithVargs_(format, ap), 0); va_end(ap); /* fputs("\nIoState_error_: ", stderr); fputs(CSTRING(description), stderr); fputs("\n\n", stderr); */ { IoCoroutine *coroutine = IoState_currentCoroutine(self); IoCoroutine_raiseError(coroutine, description, m); } }
IoObject *IoCoroutine_currentCoroutine(IoCoroutine *self, IoObject *locals, IoMessage *m) { return IoState_currentCoroutine(IOSTATE); }
IoObject *IoCoroutine_isCurrent(IoCoroutine *self, IoObject *locals, IoMessage *m) { IoObject *v = IOBOOL(self, self == IoState_currentCoroutine(IOSTATE)); return v; }