/** * Loads an infusion into the virtual machine. * @param vm the virtual machine object to load the infusion into * @param di a di pointer to the infusion file in program space * @return a newly loaded infusion, or NULL in case of fail */ dj_infusion *dj_vm_loadInfusion(dj_vm *vm, dj_di_pointer di, dj_named_native_handler native_handlers[], unsigned char numHandlers) { int i; dj_infusion *infusion; dj_di_pointer element; dj_di_pointer staticFieldInfo = DJ_DI_NOT_SET; dj_di_pointer infusionList = DJ_DI_NOT_SET; dj_thread * thread; dj_global_id entryPoint; // iterate over the child elements, and find the static // field size info block. We need this info to allocate // the memory to hold the static fields for this // infusion for (i=0; i<dj_di_getListSize(di); i++) { element = dj_di_getListElement(di, i); switch (dj_di_element_getId(element)) { case STATICFIELDINFO: staticFieldInfo = element; break; case INFUSIONLIST: infusionList = element; break; } } // Check if each of the required elements were found if (staticFieldInfo==DJ_DI_NOT_SET||infusionList==DJ_DI_NOT_SET) dj_panic(DJ_PANIC_MALFORMED_INFUSION); // allocate the Infusion struct infusion = dj_infusion_create(staticFieldInfo, dj_di_infusionList_getSize(infusionList)); // if we're out of memory, let the caller handle it if (infusion==NULL) return NULL; // iterate over the child elements and get references // to the class list and method implementation list, // and get the header for (i=0; i<dj_di_getListSize(di); i++) { element = dj_di_getListElement(di, i); switch (dj_di_element_getId(element)) { case HEADER: infusion->header = element; break; case CLASSLIST: infusion->classList = element; break; case METHODIMPLLIST: infusion->methodImplementationList = element; break; case STRINGTABLE: infusion->stringTable = element; break; } } // Check if each of the required elements was found if (infusion->stringTable==DJ_DI_NOT_SET||infusion->classList==DJ_DI_NOT_SET||infusion->methodImplementationList==DJ_DI_NOT_SET||infusion->header==DJ_DI_NOT_SET) dj_panic(DJ_PANIC_MALFORMED_INFUSION); // iterate over the referenced infusion list and set the appropriate pointers for (i=0; i<dj_di_infusionList_getSize(infusionList); i++) { dj_di_pointer name = dj_di_infusionList_getChild(infusionList, i); dj_infusion *referenced_infusion = dj_vm_lookupInfusion(vm, name); if (infusion==NULL) dj_panic(DJ_PANIC_UNSATISFIED_LINK); infusion->referencedInfusions[i] = referenced_infusion; } // add the new infusion to the VM dj_vm_addInfusion(vm, infusion); // We're assuming here that base.di is the first file in the archive if (vm->systemInfusion == NULL) vm->systemInfusion = infusion; // This code was originally in load dj_vm_loadInfusionArchive. // Moved here because the application is not in an archive, but needs // some of the same code (not native_handlers, but class initialisers // and creating a thread) #ifdef DARJEELING_DEBUG char name[64]; dj_infusion_getName(infusion, name, 64); DEBUG_LOG(DBG_DARJEELING, "Loaded infusion %s.", name); #endif for (i=0; i<numHandlers; i++) { if (dj_di_strEqualsDirectStr(dj_di_header_getInfusionName(infusion->header), native_handlers[i].name)) { infusion->native_handler = native_handlers[i].handler; #ifdef DARJEELING_DEBUG DEBUG_LOG(DBG_DARJEELING, "Attached native handler to infusion %s.", name); #endif } } // run class initialisers for this infusion infusion = dj_vm_runClassInitialisers(vm, infusion); // find the entry point for the infusion if ((entryPoint.entity_id=dj_di_header_getEntryPoint(infusion->header))!=255) { // create a new thread and add it to the VM entryPoint.infusion = infusion; thread = dj_thread_create_and_run(entryPoint); if (thread==NULL) dj_panic(DJ_PANIC_OUT_OF_MEMORY); dj_vm_addThread(vm, thread); } return infusion; }
/** * Loads an infusion into the virtual machine. * @param vm the virtual machine object to load the infusion into * @param di a di pointer to the infusion file in program space * @return a newly loaded infusion, or NULL in case of fail */ dj_infusion *dj_vm_loadInfusion(dj_vm *vm, dj_di_pointer di) { int i; dj_infusion *ret; dj_di_pointer element; dj_di_pointer staticFieldInfo = DJ_DI_NOT_SET; dj_di_pointer infusionList = DJ_DI_NOT_SET; // iterate over the child elements, and find the static // field size info block. We need this info to allocate // the memory to hold the static fields for this // infusion for (i=0; i<dj_di_getListSize(di); i++) { element = dj_di_getListElement(di, i); switch (dj_di_element_getId(element)) { case STATICFIELDINFO: staticFieldInfo = element; break; case INFUSIONLIST: infusionList = element; break; } } // Check if each of the required elements were found if (staticFieldInfo==DJ_DI_NOT_SET||infusionList==DJ_DI_NOT_SET) dj_panic(DJ_PANIC_MALFORMED_INFUSION); // allocate the Infusion struct ret = dj_infusion_create(staticFieldInfo, dj_di_infusionList_getSize(infusionList)); // if we're out of memory, let the caller handle it if (ret==NULL) return NULL; // iterate over the child elements and get references // to the class list and method implementation list, // and get the header for (i=0; i<dj_di_getListSize(di); i++) { element = dj_di_getListElement(di, i); switch (dj_di_element_getId(element)) { case HEADER: ret->header = element; break; case CLASSLIST: ret->classList = element; break; case METHODIMPLLIST: ret->methodImplementationList = element; break; case STRINGTABLE: ret->stringTable = element; break; } } // Check if each of the required elements was found if (ret->stringTable==DJ_DI_NOT_SET||ret->classList==DJ_DI_NOT_SET||ret->methodImplementationList==DJ_DI_NOT_SET||ret->header==DJ_DI_NOT_SET) dj_panic(DJ_PANIC_MALFORMED_INFUSION); // iterate over the referenced infusion list and set the appropriate pointers for (i=0; i<dj_di_infusionList_getSize(infusionList); i++) { dj_di_pointer name = dj_di_infusionList_getChild(infusionList, i); dj_infusion *infusion = dj_vm_lookupInfusion(vm, name); if (infusion==NULL) dj_panic(DJ_PANIC_UNSATISFIED_LINK); ret->referencedInfusions[i] = infusion; } // add the new infusion to the VM dj_vm_addInfusion(vm, ret); return ret; }