示例#1
0
/**
 * 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;
}
示例#2
0
文件: vm.c 项目: ekiwi/darjeeling-jvm
/**
 * 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;
}