int Levels_levelForOp(Levels *self, char *messageName, IoSymbol *messageSymbol, IoMessage *msg) { IoObject *value = IoMap_rawAt(self->operatorTable, messageSymbol); if (!value) { return -1; } if (ISNUMBER(value)) { int precedence = IoNumber_asInt((IoNumber*)value); if (precedence < 0 || precedence >= IO_OP_MAX_LEVEL) { IoState_error_(IoObject_state(msg), msg, "compile error: Precedence for operators must be between 0 and %d. Precedence was %d.", IO_OP_MAX_LEVEL - 1, precedence); } return precedence; } else { IoState_error_(IoObject_state(msg), msg, "compile error: Value for '%s' in Message OperatorTable operators is not a number. Values in the OperatorTable operators are numbers which indicate the precedence of the operator.", messageName); return -1; // The C compiler does not know that IoState_error_() will never return. } }
IoObject *IoCertificate_attributes(IoCertificate *self, IoObject *locals, IoMessage *m) { IoObject *map = IoObject_new(IoObject_state(self)); const EVP_PKEY *pkey = X509_extract_key(X509(self)); int i; for(i = 0; i < EVP_PKEY_get_attr_count(pkey); i++) { IoList *list = IoList_new(IoObject_state(self)); X509_ATTRIBUTE *attr = EVP_PKEY_get_attr(pkey, i); const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr))); int j; for(j = 0; j < X509_ATTRIBUTE_count(attr); j++) { ASN1_TYPE *attrType = X509_ATTRIBUTE_get0_type(attr, j); ASN1_OBJECT *attrData = X509_ATTRIBUTE_get0_data(attr, j, attrType->type, NULL); //consider switching on attrType instead; //really, that would be wiser, so that dates, //numbers, etc can be happy /* switch(attrType->type) { case V_ASN1_OCTET_STRING: ... */ int len = i2t_ASN1_OBJECT(NULL, 0, attrData); char *value = calloc(len, sizeof(char)); i2t_ASN1_OBJECT(value, len, attrData); IoList_rawAppend_(list, IoSeq_newWithCString_(IoObject_state(self), value)); } IoObject_setSlot_to_(map, IOSYMBOL(key), list); } return map; }
void IoDrawStuffKeyboardFunc(int key) { //printf("IoDrawStuffKeyboardFunc\n"); IoState_pushRetainPool(IoObject_state(proto)); IoMessage_setCachedArg_toInt_(DATA(proto)->keyboardMessage, 0, key); IoDrawStuff_tryCallback(proto, DATA(proto)->keyboardMessage); IoState_popRetainPool(IoObject_state(proto)); }
void IoDrawStuffStopFunc(void) { //printf("IoDrawStuffStopFunc\n"); IoState_pushRetainPool(IoObject_state(proto)); IoDrawStuff_tryCallback(proto, DATA(proto)->stopMessage); IoState_popRetainPool(IoObject_state(proto)); }
void IoDrawStuffStepFunc(int pause) { //printf("IoDrawStuffStepFunc\n"); IoState_pushRetainPool(IoObject_state(proto)); IoMessage_setCachedArg_toInt_(DATA(proto)->stepMessage, 0, pause); IoDrawStuff_tryCallback(proto, DATA(proto)->stepMessage); IoState_popRetainPool(IoObject_state(proto)); }
IoObject *IoCertificate_nameToObject(IoObject *self, X509_NAME *xname) { IoObject *map = IoObject_new(IoObject_state(self)); int i; for(i = 0; i < X509_NAME_entry_count(xname); i++) { X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i); const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry))); const char *value = (const char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)); IoObject_setSlot_to_(map, IOSYMBOL(key), IoSeq_newWithCString_(IoObject_state(self), value)); } return map; }
IoCFFIArray *IoCFFIArray_with(IoCFFIArray *self, IoObject *locals, IoMessage *m) { IoCFFIDataType *type; int size, i; ffi_type *item_type; IoCFFIArray *o = IOCLONE(self); IoState_on_doCString_withLabel_(IoObject_state(o), o, "init", "IoCFFIArray_with"); type = IOCLONE(IoMessage_locals_valueArgAt_(m, locals, 0)); IoObject_setSlot_to_(o, IOSYMBOL("arrayType"), type); size = IoMessage_locals_intArgAt_(m, locals, 1); DATA(o)->arraySize = size; item_type = IoCFFIDataType_ffiType(type); DATA(o)->itemSize = item_type->size; // Fake libffi to think we are a Struct DATA(o)->ffiType.size = 0; DATA(o)->ffiType.alignment = 0; DATA(o)->ffiType.type = FFI_TYPE_STRUCT; DATA(o)->ffiType.elements = io_calloc(size + 1, sizeof(ffi_type *)); DATA(o)->needToFreeFFIType = 1; for ( i = 0 ; i < size ; i++ ) { DATA(o)->ffiType.elements[i] = item_type; } DATA(o)->ffiType.elements[size] = NULL; ffi_cif cif; ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &(DATA(o)->ffiType), NULL); return o; }
void IoUserInit(IoObject *context) { IoState *self = IoObject_state((IoObject *)context); IoObject_setSlot_to_(context, SIOSYMBOL("User"), IoUser_proto(self)); }
void IoSystemCallInit(IoObject *context) { IoState *self = IoObject_state((IoObject *)context); IoObject_setSlot_to_(context, SIOSYMBOL("SystemCall"), IoSystemCall_proto(self)); }
void IoVolcanoInit(IoObject *context) { IoState *self = IoObject_state((IoObject *)context); IoObject_setSlot_to_(context, SIOSYMBOL("HttpParser"), IoHttpParser_proto(self)); }
void IoThreadInit(IoObject *context) { IoState *self = IoObject_state((IoObject *)context); IoObject_setSlot_to_(context, SIOSYMBOL("Thread"), IoThread_proto(self)); }
Levels *Levels_new(IoMessage *msg) { Levels *self = io_calloc(1, sizeof(Levels)); IoState *state = IoObject_state(msg); IoSymbol *operatorTableSymbol = IoState_symbolWithCString_(state, "OperatorTable"); // Be ultra flexable, and try to use the first message's operator table. IoObject *opTable = IoObject_rawGetSlot_(msg, operatorTableSymbol); // Otherwise, use Core OperatorTable, and if that doesn't exist, create it. if (opTable == NULL) { // There is a chance the message didn't have it, but the core did---due // to the Core not being part of the message's protos. Use Core // Message's OperatorTable opTable = IoObject_rawGetSlot_(state->core, operatorTableSymbol); // If Core doesn't have an OperatorTable, then create it. if (opTable == NULL) { opTable = IoObject_new(state); IoObject_setSlot_to_(state->core, operatorTableSymbol, opTable); IoObject_setSlot_to_(opTable, IoState_symbolWithCString_(state, "precedenceLevelCount"), IoState_numberWithDouble_(state, IO_OP_MAX_LEVEL)); } } self->operatorTable = getOpTable(opTable, "operators", IoState_createOperatorTable); self->assignOperatorTable = getOpTable(opTable, "assignOperators", IoState_createAssignOperatorTable); self->stack = List_new(); Levels_reset(self); return self; }
IoObject *IoCertificate_asnTimeToDate(IoCertificate *self, ASN1_TIME *tm) { char *v; int gmt=0; int i; int y=0,M=0,d=0,h=0,m=0,s=0; i=tm->length; v=(char *)tm->data; if (i < 10) return IONIL(self); if (v[i-1] == 'Z') gmt=1; for (i=0; i<10; i++) if ((v[i] > '9') || (v[i] < '0')) return IONIL(self); y= (v[0]-'0')*10+(v[1]-'0'); if (y < 50) y+=100; M= (v[2]-'0')*10+(v[3]-'0'); if ((M > 12) || (M < 1)) return IONIL(self); d= (v[4]-'0')*10+(v[5]-'0'); h= (v[6]-'0')*10+(v[7]-'0'); m= (v[8]-'0')*10+(v[9]-'0'); if ( (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) s= (v[10]-'0')*10+(v[11]-'0'); struct tm ctm; ctm.tm_sec = s; ctm.tm_min = m; ctm.tm_hour = h; ctm.tm_mday = d; ctm.tm_mon = M-1; ctm.tm_year = y; ctm.tm_gmtoff = 0; return IoDate_newWithTime_(IoObject_state(self), timegm(&ctm)); }
IoObject *IoCertificate_extensions(IoCertificate *self, IoObject *locals, IoMessage *m) { IoObject *map = IoObject_new(IoObject_state(self)); int i; for(i = 0; i < X509_get_ext_count(X509(self)); i++) { IoObject *ioext = IoObject_new(IoObject_state(self)); X509_EXTENSION *ext = X509_get_ext(X509(self), i); const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); const char *value = (const char *)ASN1_STRING_data(X509_EXTENSION_get_data(ext)); int isCritical = X509_EXTENSION_get_critical(ext); IoObject_setSlot_to_(ioext, IOSYMBOL("value"), IoSeq_newWithCString_(IoObject_state(self), value)); IoObject_setSlot_to_(ioext, IOSYMBOL("isCritical"), IONUMBER(isCritical)); IoObject_setSlot_to_(map, IOSYMBOL(key), ioext); } return map; }
int IoSecureSockets_Password_Callback(char *buf, int size, int flag, void *selfPtr) { IoObject *self = (IoObject *)selfPtr; IoSeq *passSeq; if(flag == 0) //decryption { passSeq = IoState_on_doCString_withLabel_(IoObject_state(self), self, "fetchDecryptionPassword", "Decryption Password Callback"); } else //encryption { passSeq = IoState_on_doCString_withLabel_(IoObject_state(self), self, "fetchEncryptionPassword", "Encryption Password Callback"); } char *cpass = CSTRING(passSeq); strncpy(buf, cpass, size); buf[size-1] = '\0'; return strlen(buf); }
IoSecureSocket *IoSecureServer_tlsWrap(IoSecureServer *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); IoSocket *sock = IoMessage_locals_socketArgAt_(msg, locals, 0); IoNumber *port = IoObject_getSlot_(sock, IOSYMBOL("port")); SSL *ssl = SSL_new(ctx); SSL_set_fd(ssl, IoSocket_rawDescriptor(sock)); set_nonblocking(SSL_get_rbio(ssl)); set_nonblocking(SSL_get_wbio(ssl)); SSL_set_accept_state(ssl); SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); IoIPAddress *ioaddr = IoIPAddress_new(IoObject_state(self)); IPAddress *iaddr = IoIPAddress_rawIPAddress(ioaddr); IPAddress_setIp_(iaddr, "0.0.0.0"); IPAddress_setPort_(iaddr, IoNumber_asLong(port)); IoSecureSocket *ssock = IoSecureSocket_newWithSSL_IP_(IoObject_state(self), ssl, ioaddr); return ssock; }
void IoVector_glInit(IoObject *context) { IoState *state = IoObject_state(context); IoObject *self = IoState_protoWithName_(state, "Sequence"); { IoMethodTable methodTable[] = { {"glNormal", IoSeq_glNormal}, {"glTranslate", IoSeq_glTranslate}, {"glTranslatei", IoSeq_glTranslatei}, {"glRotate", IoSeq_glRotate}, {"glScale", IoSeq_glScale}, {"glUnproject", IoSeq_glUnproject}, {"glProject", IoSeq_glProject}, {"glVertex", IoSeq_glVertex}, {"glColor", IoSeq_glColor}, {"glClearColor", IoSeq_glClearColor}, {"drawQuadTo", IoSeq_drawQuadTo}, {"drawLineLoop", IoSeq_drawLineLoop}, {"drawLineLoopi", IoSeq_drawLineLoopi}, {"drawQuad", IoSeq_drawQuad}, {"red", IoSeq_x}, {"green", IoSeq_y}, {"blue", IoSeq_z}, {"alpha", IoSeq_w}, {"setRed", IoSeq_setX}, {"setGreen", IoSeq_setY}, {"setBlue", IoSeq_setZ}, {"setAlpha", IoSeq_setW}, {"drawAsLine", IoSeq_drawAsLine}, {"drawFilled", IoSeq_drawFilled}, /* {"drawLineTo", IoSeq_drawLineTo}, {"drawLineLoopTo", IoSeq_drawLineLoopTo}, */ {NULL, NULL}, }; IoObject_addMethodTable_(self, methodTable); } }
void Levels_attachToTopAndPush(Levels *self, IoMessage *msg, int precedence) { Level *level = NULL; { Level *top = List_top(self->stack); Level_attachAndReplace(top, msg); } { // TODO: Check for overflow of the pool. if (self->currentLevel >= IO_OP_MAX_LEVEL) { IoState_error_(IoObject_state(msg), NULL, "compile error: Overflowed operator stack. Only %d levels of operators currently supported.", IO_OP_MAX_LEVEL-1); } level = &self->pool[self->currentLevel++]; Level_setAwaitingFirstArg(level, msg, precedence); List_append_(self->stack, level); } }
IoObject *IoDrawStuff_tryCallback(IoDrawStuff *self, IoMessage *m) { IoState *state = IoObject_state(proto); IoObject *tryCoro = DATA(self)->coroutine; IoObject *t = DATA(self)->eventTarget; IoObject *result = state->ioNil; //printf("IoDrawStuff_tryCallback(self, %p)\n", (void*)m); //printf("IoDrawStuff_tryCallback target: %p)\n", (void*)t); if(t) { IoMessage_locals_performOn_(m, t, t); if (IoCoroutine_rawException(tryCoro) != state->ioNil) IoState_exception_(state, tryCoro); IoCoroutine_clearStack(tryCoro); return IoCoroutine_rawResult(tryCoro); } return result; }
IoSecureSocket *IoSecureClient_connectionToServer(IoSecureClient *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); char *serverIP = CSTRING(IoMessage_locals_seqArgAt_(msg, locals, 0)); char *port = CSTRING(IoMessage_locals_seqArgAt_(msg, locals, 1)); IoSecureSocket *sock = IoSecureSocket_newWithCTX_(IoObject_state(self), ctx); if(sock == IONIL(self)) { ERR_print_errors_fp(stderr); IoState_error_(IOSTATE, msg, "Error creating SecureSocket"); return sock; } if(!IoSecureSocket_createBIO(sock, serverIP, port)) { ERR_print_errors_fp(stderr); IoState_error_(IOSTATE, msg, "Error creating BIO for SecureSocket"); return IONIL(self); } return sock; }
void IoBox_glInit(IoObject *context) { IoState *state = IoObject_state(context); IoObject *self = IoState_protoWithInitFunction_(state, IoBox_proto); { IoMethodTable methodTable[] = { {"drawAsRect", IoBox_drawAsRect}, {"drawAsRectOutline", IoBox_drawAsRectOutline}, {"scissor", IoBox_scissor}, //{"scissorToUnion", IoBox_scissorToUnion}, //{"getScissor", IoBox_getScissor}, {"glProject", IoBox_glProject}, {"glUnproject", IoBox_glUnproject}, {NULL, NULL}, }; IoObject_addMethodTable_(self, methodTable); } }
IoSymbol *Levels_nameForAssignOperator(Levels *self, IoState *state, IoSymbol *operator, IoSymbol *slotName, IoMessage *msg) { IoObject *value = IoMap_rawAt(self->assignOperatorTable, operator); char *operatorString = CSTRING(operator); if (value != NULL && ISSYMBOL(value)) { if (strcmp(operatorString, ":=") == 0 && isupper(CSTRING(slotName)[0])) { return state->setSlotWithTypeSymbol; } else { return value; } } else { IoState_error_(IoObject_state(msg), msg, "compile error: Value for '%s' in Message OperatorTable assignOperators is not a symbol. Values in the OperatorTable assignOperators are symbols which are the name of the operator.", operatorString); return NULL; // To keep the compiler happy. } }
IoSecureSocket *IoSecureServer_dtlsWrap(IoSecureServer *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); IoSocket *sock = IoObject_getSlot_(self, IOSYMBOL("socket")); IoIPAddress *ioip = IoMessage_locals_addressArgAt_(msg, locals, 0); IPAddress *ip = IoIPAddress_rawIPAddress(ioip); struct sockaddr *addr = IPAddress_sockaddr(ip); IoNumber *port = IoObject_getSlot_(sock, IOSYMBOL("port")); int fd = IoSocket_rawDescriptor(sock); SSL *ssl = SSL_new(ctx); BIO *rbio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(rbio, -1); BIO *wbio = BIO_new_dgram(fd, BIO_NOCLOSE); BIO_dgram_set_peer(wbio, addr); SSL_set_bio(ssl, rbio, wbio); SSL_set_accept_state(ssl); set_nonblocking(wbio); SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); IoSecureSocket *ssock = IoSecureSocket_newWithSSL_IP_(IoObject_state(self), ssl, ioip); return ssock; }
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); } }