void IoState_setupSingletons(IoState *self) { IoObject *core = self->core; // nil self->ioNil = IOCLONE(self->objectProto); IoObject_setSlot_to_(core, SIOSYMBOL("nil"), self->ioNil); //IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil); IoObject_setSlot_to_(core, SIOSYMBOL("Message"), IoMessage_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Call"), IoCall_proto(self)); self->nilMessage = IoMessage_newWithName_(self, SIOSYMBOL("nil")); IoMessage_cachedResult_(self->nilMessage, self->ioNil); IoState_retain_(self, self->nilMessage); // true self->ioTrue = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("true"), self->ioTrue); IoObject_setSlot_to_(self->ioTrue, SIOSYMBOL("type"), SIOSYMBOL("true")); IoState_retain_(self, self->ioTrue); // false self->ioFalse = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("false"), self->ioFalse); IoObject_setSlot_to_(self->ioFalse, SIOSYMBOL("type"), SIOSYMBOL("false")); IoState_retain_(self, self->ioFalse); // Flow control: Normal self->ioNormal = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("Normal"), self->ioNormal); IoObject_setSlot_to_(self->ioNormal, SIOSYMBOL("type"), SIOSYMBOL("Normal")); IoState_retain_(self, self->ioNormal); // Flow control: Break self->ioBreak = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("Break"), self->ioBreak); IoObject_setSlot_to_(self->ioBreak, SIOSYMBOL("type"), SIOSYMBOL("Break")); IoState_retain_(self, self->ioBreak); // Flow control: Continue self->ioContinue = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("Continue"), self->ioContinue); IoObject_setSlot_to_(self->ioContinue, SIOSYMBOL("type"), SIOSYMBOL("Continue")); IoState_retain_(self, self->ioContinue); // Flow control: Return self->ioReturn = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("Return"), self->ioReturn); IoObject_setSlot_to_(self->ioReturn, SIOSYMBOL("type"), SIOSYMBOL("Return")); IoState_retain_(self, self->ioReturn); // Flow control: Eol self->ioEol = IoObject_new(self); IoObject_setSlot_to_(core, SIOSYMBOL("Eol"), self->ioEol); IoObject_setSlot_to_(self->ioEol, SIOSYMBOL("type"), SIOSYMBOL("Eol")); IoState_retain_(self, self->ioEol); }
void IoSandbox_printCallback(void *voidSelf, const UArray *ba) { IoSandbox *self = voidSelf; IoState *state = IOSTATE; IoSeq *buf = IoSeq_newWithUArray_copy_(IOSTATE, (UArray *)ba, 1); IoMessage *m = IoMessage_newWithName_(state, IOSYMBOL("printCallback")); IoMessage *arg = IoMessage_newWithName_returnsValue_(state, IOSYMBOL("buffer"), buf); IoMessage_addArg_(m, arg); IoMessage_locals_performOn_(m, state->lobby, 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; }
IoEventManager *IoEventManager_proto(void *state) { IoObject *self = IoObject_new(state); IoObject_tag_(self, IoEventManager_newTag(state)); IoObject_setDataPointer_(self, calloc(1, sizeof(IoEventManagerData))); DATA(self)->handleEventMessage = IoMessage_newWithName_(state, IOSYMBOL("handleEvent")); DATA(self)->activeEvents = List_new(); IoState_registerProtoWithFunc_((IoState *)state, self, IoEventManager_proto); { IoMethodTable methodTable[] = { {"addEvent", IoEventManager_addEvent}, {"removeEvent", IoEventManager_removeEvent}, {"listen", IoEventManager_listen}, {"listenUntilEvent", IoEventManager_listenUntilEvent}, {"setListenTimeout", IoEventManager_setListenTimeout}, {"hasActiveEvents", IoEventManager_hasActiveEvents}, {"activeEvents", IoEventManager_activeEvents}, {NULL, NULL}, }; IoObject_addMethodTable_(self, methodTable); } //#if !defined(AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER) #if defined(__APPLE__) setenv("EVENT_NOKQUEUE", "1", 1); //printf("EventManager warning: disabling libevent kqueue support to avoid bug in OSX < 10.4\n"); setenv("EVENT_NOPOLL", "1", 1); //setenv("EVENT_NOSELECT", "1", 1); #endif DATA(self)->eventBase = event_init(); //IoEventManager_setDescriptorLimitToMax(self); Socket_SetDescriptorLimitToMax(); return self; }
// Serialize/Deserialize char *IoMemcached_serialize(IoMemcached *self, IoObject *locals, IoObject *object, size_t *size, uint32_t *flags) { char *cvalue; if(ISSEQ(object)) { *flags = _FLAG_SEQUENCE; *size = IOSEQ_LENGTH(object); cvalue = (char *) malloc(*size); strncpy(cvalue, CSTRING(object), *size); } else if(ISNUMBER(object)) { *flags = _FLAG_NUMBER; double cnumber = IoNumber_asDouble(object); cvalue = (char *) malloc(128 * sizeof(char)); *size = snprintf(cvalue, 127, "%.16f", cnumber); } else if(ISNIL(object)) { *flags = _FLAG_NIL; *size = 3; cvalue = (char *) malloc(3 * sizeof(char)); strncpy(cvalue, "nil", 3); } else if(ISBOOL(object)) { *flags = _FLAG_BOOLEAN; *size = 1; cvalue = (char *) malloc(sizeof(char)); if(object == IOSTATE->ioTrue) strncpy(cvalue, "1", 1); if(object == IOSTATE->ioFalse) strncpy(cvalue, "0", 1); } else { *flags = _FLAG_OBJECT; IoMessage *serialize = IoMessage_newWithName_(IOSTATE, IOSYMBOL("serialized")); IoSeq *serialized = IoMessage_locals_performOn_(serialize, locals, object); *size = IOSEQ_LENGTH(serialized); cvalue = (char *) malloc(*size); strncpy(cvalue, CSTRING(serialized), *size); } return cvalue; }
IoMessage *IoMessage_newWithName_andCachedArg_(void *state, IoSymbol *symbol, IoObject *arg) { IoMessage *self = IoMessage_newWithName_(state, symbol); IoMessage_addCachedArg_(self, arg); return self; }
void IoState_new_atAddress(void *address) { IoState *self = (IoState *)address; IoCFunction *cFunctionProto; IoSeq *seqProto; // collector self->collector = Collector_new(); IoState_pushCollectorPause(self); Collector_setMarkFunc_(self->collector, (CollectorMarkFunc *)IoObject_mark); Collector_setWillFreeFunc_(self->collector, (CollectorWillFreeFunc *)IoObject_willFree); Collector_setFreeFunc_(self->collector, (CollectorFreeFunc *)IoObject_free); self->mainArgs = MainArgs_new(); self->primitives = PHash_new(); self->recycledObjects = List_new(); self->maxRecycledObjects = IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS; // Sandbox self->messageCount = 0; self->messageCountLimit = 0; self->endTime = 0; // symbol table self->symbols = SHash_new(); SHash_setKeysEqualCallback(self->symbols, (SHashKeysEqualCallback *)UArray_equalsWithHashCheck_); SHash_setHashForKeyCallback(self->symbols, (SHashHashforKeyCallback *)UArray_hash); /* Problem: - there are some interdependencies here: - creating instances requires a retain stack - we need a Coroutine to use for our retainStack - defining any primitive methods requires Strings and CFunctions Solution: - create a temporary fake stack - create Object, CFunction and String protos sans methods. - then add methods to Object, CFunction and String */ self->currentIoStack = Stack_new(); // temp retain stack until coro is up self->objectProto = IoObject_proto(self); // need to do this first, so we have a retain stack //IoState_retain_(self, self->objectProto); self->mainCoroutine = IoCoroutine_proto(self); Stack_free(self->currentIoStack); self->currentIoStack = NULL; IoState_setCurrentCoroutine_(self, self->mainCoroutine); seqProto = IoSeq_proto(self); IoState_setupQuickAccessSymbols(self); IoObject_rawSetProto_(seqProto, self->objectProto); cFunctionProto = IoCFunction_proto(self); self->localsUpdateSlotCFunc = IoState_retain_(self, IoCFunction_newWithFunctionPointer_tag_name_(self, IoObject_localsUpdateSlot, NULL, "localsUpdate")); IoSeq_protoFinish(seqProto); IoObject_protoFinish(self); IoCFunction_protoFinish(self); IoCoroutine_protoFinish(self->mainCoroutine); self->setSlotBlock = IoState_retain_(self, IoObject_getSlot_(self->objectProto, SIOSYMBOL("setSlot"))); // setup lobby { IoObject *objectProto = self->objectProto; IoObject *protos = IOCLONE(objectProto); IoObject *core = IOCLONE(objectProto); self->core = core; self->lobby = IOCLONE(objectProto); IoState_retain_(self, self->lobby); IoState_retain_(self, self->core); // setup namespace IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Lobby"), self->lobby); IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Protos"), protos); IoObject_setSlot_to_(protos, SIOSYMBOL("Core"), core); IoObject_setSlot_to_(protos, SIOSYMBOL("Addons"), IOCLONE(objectProto)); IoObject_setSlot_to_(core, SIOSYMBOL("Compiler"), IoCompiler_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Collector"), IoCollector_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Exception"), IOCLONE(objectProto)); // setup proto chain IoObject_rawSetProto_(objectProto, self->lobby); IoObject_rawSetProto_(self->lobby, protos); IoObject_rawSetProto_(protos, core); // add protos to namespace IoObject_setSlot_to_(core, SIOSYMBOL("Object"), objectProto); IoObject_setSlot_to_(core, SIOSYMBOL("Sequence"), seqProto); IoObject_setSlot_to_(core, SIOSYMBOL("Number"), IoNumber_proto(self)); IoState_setupCachedNumbers(self); { IoObject *systemProto = IoSystem_proto(self); IoObject_setSlot_to_(core, SIOSYMBOL("System"), systemProto); } IoState_setupSingletons(self); IoState_setupCachedMessages(self); { self->debugger = IoState_retain_(self, IoDebugger_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Debugger"), self->debugger); self->vmWillSendMessage = IoMessage_newWithName_(self, SIOSYMBOL("vmWillSendMessage")); IoMessage_cachedResult_(self->nilMessage, self->ioNil); IoState_retain_(self, self->vmWillSendMessage); } IoObject_setSlot_to_(core, SIOSYMBOL("Block"), IoBlock_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("List"), IoList_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Map"), IoMap_proto(self)); //IoObject_setSlot_to_(core, SIOSYMBOL("Range"), IoRange_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Coroutine"), self->mainCoroutine); IoObject_setSlot_to_(core, SIOSYMBOL("Error"), IoError_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("File"), IoFile_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Directory"), IoDirectory_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Date"), IoDate_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Duration"), IoDuration_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("WeakLink"), IoWeakLink_proto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Sandbox"), IoSandbox_proto(self)); //IoObject_setSlot_to_(core, SIOSYMBOL("EditLine"), IoEditLine_proto(self)); #if !defined(__SYMBIAN32__) IoObject_setSlot_to_(core, SIOSYMBOL("DynLib"), IoDynLib_proto(self)); #endif //self->store = //IoObject_setSlot_to_(core, SIOSYMBOL("Store"), self->store); IoObject_setSlot_to_(core, SIOSYMBOL("CFunction"), cFunctionProto); self->localsProto = IoState_retain_(self, IoObject_localsProto(self)); IoObject_setSlot_to_(core, SIOSYMBOL("Locals"), self->localsProto); self->stopStatus = MESSAGE_STOP_STATUS_NORMAL; self->returnValue = self->ioNil; IoState_clearRetainStack(self); IoState_popCollectorPause(self); //Collector_collect(self->collector); //io_show_mem("before IoVMCodeInit"); IoVMCodeInit(core); //io_show_mem("after IoVMCodeInit"); //Collector_collect(self->collector); //io_show_mem("after Collector_collect"); // IoState_popCollectorPause(self); IoState_clearRetainStack(self); Collector_collect(self->collector); //io_show_mem("after IoState_clearRetainStack and Collector_collect"); IoState_setupUserInterruptHandler(self); } }
void IoState_setupCachedMessages(IoState *self) { self->asStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("asString")); IoState_retain_(self, self->asStringMessage); self->collectedLinkMessage = IoMessage_newWithName_(self, SIOSYMBOL("collectedLink")); IoState_retain_(self, self->collectedLinkMessage); self->compareMessage = IoMessage_newWithName_(self, SIOSYMBOL("compare")); IoState_retain_(self, self->compareMessage); //self->doStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("doString")); //IoState_retain_(self, self->doStringMessage); self->initMessage = IoMessage_newWithName_(self, SIOSYMBOL("init")); IoState_retain_(self, self->initMessage); self->mainMessage = IoMessage_newWithName_(self, SIOSYMBOL("main")); IoState_retain_(self, self->mainMessage); self->opShuffleMessage = IoMessage_newWithName_(self, self->opShuffleSymbol); IoState_retain_(self, self->opShuffleMessage); self->printMessage = IoMessage_newWithName_(self, SIOSYMBOL("print")); IoState_retain_(self, self->printMessage); self->referenceIdForObjectMessage = IoMessage_newWithName_(self, SIOSYMBOL("referenceIdForObject")); IoState_retain_(self, self->referenceIdForObjectMessage); self->objectForReferenceIdMessage = IoMessage_newWithName_(self, SIOSYMBOL("objectForReferenceId")); IoState_retain_(self, self->objectForReferenceIdMessage); self->runMessage = IoMessage_newWithName_(self, SIOSYMBOL("run")); IoState_retain_(self, self->runMessage); self->willFreeMessage = IoMessage_newWithName_(self, SIOSYMBOL("willFree")); IoState_retain_(self, self->willFreeMessage); self->yieldMessage = IoMessage_newWithName_(self, SIOSYMBOL("yield")); IoState_retain_(self, self->yieldMessage); }
void Levels_attach(Levels *self, IoMessage *msg, List *expressions) { // TODO clean up this method. IoState *state = IoObject_state(msg); IoSymbol *messageSymbol = IoMessage_name(msg); char *messageName = CSTRING(messageSymbol); int precedence = Levels_levelForOp(self, messageName, messageSymbol, msg); int msgArgCount = IoMessage_argCount(msg); /* // o a := b c ; d becomes o setSlot("a", b c) ; d // // a attaching // := msg // b c msg->next */ if (Levels_isAssignOperator(self, messageSymbol)) { Level *currentLevel = Levels_currentLevel(self); IoMessage *attaching = currentLevel->message; IoSymbol *setSlotName; if (attaching == NULL) // := b ; { // Could be handled as, message(:= 42) -> setSlot(nil, 42) IoState_error_(state, msg, "compile error: %s requires a symbol to its left.", messageName); return; } if (IoMessage_argCount(attaching) > 0) // a(1,2,3) := b ; { IoState_error_(state, msg, "compile error: The symbol to the left of %s cannot have arguments.", messageName); return; } if (msgArgCount > 1) // setSlot("a") :=(b, c, d) e ; { IoState_error_(state, msg, "compile error: Assign operator passed multiple arguments, e.g., a := (b, c).", messageName); return; } { // a := b ; IoSymbol *slotName = DATA(attaching)->name; IoSymbol *quotedSlotName = IoSeq_newSymbolWithFormat_(state, "\"%s\"", CSTRING(slotName)); IoMessage *slotNameMessage = IoMessage_newWithName_returnsValue_(state, quotedSlotName, slotName); IoMessage_rawCopySourceLocation(slotNameMessage, attaching); // a := b ; -> a("a") := b ; IoMessage_addArg_(attaching, slotNameMessage); setSlotName = Levels_nameForAssignOperator(self, state, messageSymbol, slotName, msg); } // a("a") := b ; -> setSlot("a") := b ; DATA(attaching)->name = IoObject_addingRef_(attaching, setSlotName); currentLevel->type = ATTACH; if (msgArgCount > 0) // setSlot("a") :=(b c) d e ; { // b c IoMessage *arg = IoMessage_rawArgAt_(msg, 0); if (DATA(msg)->next == NULL || IoMessage_rawIsEOL(DATA(msg)->next)) { IoMessage_addArg_(attaching, arg); } else { // () IoMessage *foo = IoMessage_newWithName_(state, IoState_symbolWithCString_(state, "")); IoMessage_rawCopySourceLocation(foo, attaching); // () -> (b c) IoMessage_addArg_(foo, arg); // (b c) -> (b c) d e ; IoMessage_rawSetNext_(foo, DATA(msg)->next); // setSlot("a") :=(b c) d e ; -> setSlot("a", (b c) d e ;) :=(b c) d e ; IoMessage_addArg_(attaching, foo); } } else // setSlot("a") := b ; { // setSlot("a") := or setSlot("a") := ; IoMessage *mn = DATA(msg)->next; IoSymbol *name = mn ? DATA(mn)->name : NULL; IoSymbol *semi = IoObject_state(msg)->semicolonSymbol; //if (mn == NULL || IoMessage_rawIsEOL(mn)) if (mn == NULL || name == semi) { IoState_error_(state, msg, "compile error: %s must be followed by a value.", messageName); } // setSlot("a") := b c ; -> setSlot("a", b c ;) := b c ; IoMessage_addArg_(attaching, DATA(msg)->next); } // process the value (b c d) later (setSlot("a", b c d) := b c d ;) if (DATA(msg)->next != NULL && !IoMessage_rawIsEOL(DATA(msg)->next)) { List_push_(expressions, DATA(msg)->next); } { IoMessage *last = msg; while (DATA(last)->next != NULL && !IoMessage_rawIsEOL(DATA(last)->next)) { last = DATA(last)->next; } IoMessage_rawSetNext_(attaching, DATA(last)->next); // Continue processing in IoMessage_opShuffle loop IoMessage_rawSetNext_(msg, DATA(last)->next); if (last != msg) { IoMessage_rawSetNext_(last, NULL); } } // make sure b in 1 := b gets executed IoMessage_rawSetCachedResult_(attaching, NULL); } else if (IoMessage_rawIsEOL(msg)) { Levels_popDownTo(self, IO_OP_MAX_LEVEL-1); Level_attachAndReplace(Levels_currentLevel(self), msg); } else if (precedence != -1) // is an operator { if (msgArgCount > 0) { // move arguments off to their own message to make () after operators behave like Cs grouping () IoMessage *brackets = IoMessage_newWithName_(state, IoState_symbolWithCString_(state, "")); IoMessage_rawCopySourceLocation(brackets, msg); List_copy_(IoMessage_rawArgList(brackets), IoMessage_rawArgList(msg)); List_removeAll(IoMessage_rawArgList(msg)); // Insert the brackets message between msg and its next message IoMessage_rawSetNext_(brackets, DATA(msg)->next); IoMessage_rawSetNext_(msg, brackets); } Levels_popDownTo(self, precedence); Levels_attachToTopAndPush(self, msg, precedence); } else { Level_attachAndReplace(Levels_currentLevel(self), msg); } }