IoMessage *IoMessage_newFromText_labelSymbol_(void *state, const char *text, IoSymbol *label) { IoLexer *lexer; IoMessage *msg; IoState_pushCollectorPause((IoState *)state); // needed? lexer = IoLexer_new(); IoLexer_string_(lexer, text); IoLexer_lex(lexer); // This also applies line numbers. msg = IoMessage_newParse(state, lexer); IoMessage_opShuffle_(msg); IoMessage_label_(msg, label); // DLF: Check for pending breakpoint on this message. iovm_set_pending_breakpoints(msg); IoLexer_free(lexer); IoState_popCollectorPause((IoState *)state); return msg; }
IoObject *IoCFFIFunction_call(IoCFFIFunction *self, IoObject *locals, IoMessage *m) { IoCFFILibrary *library; const char *funName; void *funPointer, **funArgVals, *funRetVal; ffi_type **funArgTypes, *funRetType; ffi_cif *funInterface; int funArgCount, i; ffi_status status; IoObject *returnValAsObj, *funRetTypeObject, *o; List *funArgTypeObjects; library = IoObject_getSlot_(self, IOSYMBOL("library")); funInterface = &(DATA(self)->interface); funName = CSTRING(IoObject_getSlot_(self, IOSYMBOL("name"))); funPointer = IoCFFILibrary_rawGetFuctionPointer_(library, funName); funArgTypeObjects = IoList_rawList(IoObject_getSlot_(self, IOSYMBOL("argumentTypes"))); funRetTypeObject = IoObject_getSlot_(self, IOSYMBOL("returnType")); funArgCount = (int)List_size(funArgTypeObjects); funArgTypes = calloc(funArgCount, sizeof(ffi_type *)); for (i = 0; i < funArgCount; i++) { o = List_at_(funArgTypeObjects, i); funArgTypes[i] = IoCFFIDataType_ffiType(o); } funRetType = IoCFFIDataType_ffiType(funRetTypeObject); status = ffi_prep_cif(funInterface, FFI_DEFAULT_ABI, funArgCount, funRetType, funArgTypes); if (status != FFI_OK) { printf("\n\nUh oh. Something went wrong in IoCFFIFunction_call.\n\n"); free(funArgTypes); return IONIL(self); } funArgVals = calloc(funArgCount, sizeof(void *)); funRetVal = calloc(1, funRetType->size); IoState_pushCollectorPause(IOSTATE); { for (i = 0; i < funArgCount; i++) { o = IoMessage_locals_valueArgAt_(m, locals, i); funArgVals[i] = IoCFFIDataType_ValuePointerFromObject_(o); } ffi_call(funInterface, funPointer, funRetVal, funArgVals); returnValAsObj = IoCFFIDataType_objectFromData_(funRetTypeObject, funRetVal); } IoState_popCollectorPause(IOSTATE); free(funArgTypes); free(funArgVals); free(funRetVal); return returnValAsObj; }
void IoState_init(IoState *self) { if (self->bindingsInitCallback) { IoState_pushCollectorPause(self); self->bindingsInitCallback(self, self->core); IoState_popCollectorPause(self); IoState_clearRetainStack(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); } }
IoDynLib *IoDynLib_justCall(IoDynLib *self, IoObject *locals, IoMessage *m, int isVoid) { int n, rc = 0; intptr_t *params = NULL; IoSymbol *callName = IoMessage_locals_symbolArgAt_(m, locals, 0); void *f = DynLib_pointerForSymbolName_(DATA(self), CSTRING(callName)); //printf("DynLib calling '%s'\n", CSTRING(callName)); if (f == NULL) { IoState_error_(IOSTATE, m, "Error resolving call '%s'.", CSTRING(callName)); return IONIL(self); } if (IoMessage_argCount(m) > 9) { IoState_error_(IOSTATE, m, "Error, too many arguments (%i) to call '%s'.", IoMessage_argCount(m) - 1, CSTRING(callName)); return IONIL(self); } if (IoMessage_argCount(m) > 1) { params = io_calloc(1, IoMessage_argCount(m) * sizeof(unsigned int)); } for (n = 0; n < IoMessage_argCount(m) - 1; n++) { IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, n + 1); intptr_t p = marshal(self, arg); params[n] = p; /* if (p == 0) { IoState_error_(IOSTATE, m, "DynLib error marshalling argument (%i) to call '%s'.", n + 1, CSTRING(callName)); // FIXME this can leak memory. io_free(params); return IONIL(self); } */ } #if 0 printf("calling %s with %i arguments\n", CSTRING(IoMessage_locals_symbolArgAt_(m, locals, 0)), IoMessage_argCount(m) - 1); #endif IoState_pushCollectorPause(IOSTATE); if (isVoid) { IoDynLib_rawVoidCall(f, IoMessage_argCount(m), params); } else { rc = (int)IoDynLib_rawNonVoidCall(f, IoMessage_argCount(m), params); } IoState_popCollectorPause(IOSTATE); for (n = 0; n < IoMessage_argCount(m) - 1; n ++) { IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, n + 1); demarshal(self, arg, params[n]); } io_free(params); return isVoid ? IONIL(self) : IONUMBER(rc); }