Beispiel #1
0
/**
 * Loads an infusion into the virtual machine, and marks it as the system infusion. Always load the
 * system infusion before anything else.
 * @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_loadSystemInfusion(dj_vm *vm, dj_di_pointer di)
{
	dj_infusion *ret = dj_vm_loadInfusion(vm, di);

	// if we run out of memory, let the caller handle it
	if (ret==NULL) return NULL;

	dj_vm_setSystemInfusion(vm, ret);

	return ret;
}
Beispiel #2
0
void dj_vm_loadInfusionArchive(dj_vm * vm, dj_di_pointer archive, dj_named_native_handler native_handlers[], unsigned char numHandlers)
{
	for (uint8_t i=0; i<dj_archive_number_of_files(archive); i++) {
		dj_di_pointer file = dj_archive_get_file(archive, i);
		if (dj_archive_filetype(file) == FILETYPE_LIB_INFUSION) {
			dj_infusion * infusion = dj_vm_loadInfusion(vm, file, native_handlers, numHandlers);
			if (infusion == NULL) {
				DARJEELING_PRINTF("Not enough space to create the infusion nr %d in archive.\n", i);
		        dj_panic(DJ_PANIC_OUT_OF_MEMORY);
		    }
		}
	}
}
Beispiel #3
0
/**
 * Main function that creates the vm and runs until either all threads stop or runlevel is set to RUNLEVEL_REBOOT
 * This code was in the main() of each config before, but has been extracted to make rebooting easier.
 */
void dj_vm_main(void *mem,
 				uint32_t memsize,
 				dj_di_pointer di_lib_infusions_archive_data,
 				dj_di_pointer di_app_infusion_archive_data,
 				dj_named_native_handler handlers[],
 				uint8_t handlers_length) {
	dj_vm *vm;
	dj_object * obj;

	// initialise timer
	dj_timer_init();

	// initialise memory managerw
	dj_mem_init(mem, memsize);

	// create a new VM
	vm = dj_vm_create();

	// tell the execution engine to use the newly created VM instance
	dj_exec_setVM(vm);
	// set run level before loading libraries since they need to execute initialisation code
	dj_exec_setRunlevel(RUNLEVEL_RUNNING);

	dj_vm_loadInfusionArchive(vm, di_lib_infusions_archive_data, handlers, handlers_length);
	dj_di_pointer di_app_infusion_data = dj_archive_get_file(di_app_infusion_archive_data, 0);
	dj_vm_loadInfusion(vm, di_app_infusion_data, NULL, 0);

	// pre-allocate an OutOfMemoryError object
	obj = dj_vm_createSysLibObject(vm, BASE_CDEF_java_lang_OutOfMemoryError);
	dj_mem_setPanicExceptionObject(obj);

	DEBUG_LOG(true, "Darjeeling is go!\n\r");

	// start the main execution loop
	while (dj_vm_countLiveThreads(vm)>0)
	{
		dj_vm_schedule(vm);
		if (vm->currentThread!=NULL)
			if (vm->currentThread->status==THREADSTATUS_RUNNING)
				dj_exec_run(RUNSIZE);
	}
	DEBUG_LOG(true, "All threads terminated.\n\r");
}
Beispiel #4
0
void dj_vm_loadInfusionArchive(dj_vm * vm, dj_archive* archive, dj_named_native_handler native_handlers[], unsigned char numHandlers)
{

	dj_thread * thread;
	dj_infusion * infusion = NULL;

        dj_di_pointer archive_start = archive->start;
        dj_di_pointer archive_end = archive->end; 


	unsigned char digit, i;
	dj_global_id entryPoint;
	unsigned long size, pos;
	bool first = true;

	// skip header, we'll just assume you're not passing something silly into this method
	archive_start += 8;

	while (archive_start<archive_end-1)
	{
		// read size
		size = 0;
		pos = AR_EHEADER_SIZE_START;
		while (((digit=dj_di_getU8(archive_start+pos))!=' ')&&(pos<AR_EHEADER_SIZE_END))
		{
			size *= 10;
			size += digit - '0';
			pos++;
		}

		// if filename starts with '/' skip this entry, since it's part of a
		// GNU extension on the common AR format
		if (dj_di_getU8(archive_start)!='/')
		{

			// Read infusion file. We're assuming here that base.di is the first file in the archive
			if (first)
				infusion = dj_vm_loadSystemInfusion(vm, archive_start + AR_EHEADER_SIZE);
			else
				infusion = dj_vm_loadInfusion(vm, archive_start + AR_EHEADER_SIZE);

			// If infusion is not loaded a critical error has occured
			if (infusion == NULL){
				DARJEELING_PRINTF("Not enough space to create the infusion : %c%c%c%c%c%c%c%c\n",
						dj_di_getU8(archive_start+0),
						dj_di_getU8(archive_start+1),
						dj_di_getU8(archive_start+2),
						dj_di_getU8(archive_start+3),
						dj_di_getU8(archive_start+4),
						dj_di_getU8(archive_start+5),
						dj_di_getU8(archive_start+6),
						dj_di_getU8(archive_start+7)
				);
		        dj_panic(DJ_PANIC_OUT_OF_MEMORY);
			}
			/*
			else
				DARJEELING_PRINTF("[%s.di] %ld\n",
						(char *) dj_di_header_getInfusionName(infusion->header),
						size
						);
						*/

#ifdef DARJEELING_DEBUG
			char name[64];

			dj_infusion_getName(infusion, name, 64);

			DEBUG_LOG("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("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);
			}

			first = false;
		}

		// files are 2-byte aligned
		if (size&1) size++;
		archive_start += size + AR_EHEADER_SIZE;
	}

}