inline dj_global_id dj_vm_getRuntimeClass(dj_vm *vm, runtime_id_t id) { dj_global_id ret; dj_infusion *infusion = vm->infusions; runtime_id_t base = 0; // TODO: optimize this! (binary search?) // TODO: test for multiple loaded infusions while (infusion!=NULL) { base = infusion->class_base; if ((id>=base)&&(id<base + dj_di_parentElement_getListSize(infusion->classList))) { ret.infusion = infusion; ret.entity_id = id - base; return ret; } infusion = infusion->next; } // TODO raise error, class not found DEBUG_LOG(DBG_DARJEELING, "error: class not found: %d\n", id); DARJEELING_PRINTF("error: class not found: %d\n", id); #ifdef DARJEELING_DEBUG_FRAME dj_exec_debugCurrentFrame(); #endif dj_panic(DJ_PANIC_ILLEGAL_INTERNAL_STATE); // dead code to make compiler happy ret.entity_id=255; ret.infusion=NULL; return ret; }
// void javax.darjeeling.Darjeeling.assertTrue(int, boolean) void javax_darjeeling_Darjeeling_void_assertTrue_int_boolean() { // pop argument from the stack int16_t value = dj_exec_stackPopShort(); int32_t id = dj_exec_stackPopInt(); #warning FIX THIS :) if (value==0) DARJEELING_PRINTF("ASSERT[%3ld] FAILED\n", id); else DARJEELING_PRINTF("ASSERT[%3ld] passed\n", id); // if (nesc_printf(temp)==0) // blockThreadForPrintf(); }
void wuclass_light_actuator_update(wuobject_t *wuobject) { bool onOff; wkpf_internal_read_property_boolean(wuobject, WKPF_PROPERTY_LIGHT_ACTUATOR_ON_OFF, &onOff); DARJEELING_PRINTF("WKPFUPDATE(Light): Setting light to: %x\n", onOff); }
// void javax.darjeeling.Darjeeling.printBytesAsString(byte[]) void javax_darjeeling_Darjeeling_void_printBytesAsString_byte__() { dj_int_array* byteStr = REF_TO_VOIDP(dj_exec_stackPopRef()); char* str = byteStr->data.bytes; #ifdef IS_COOJA DARJEELING_PRINTF("\n(Node %d) ---> %s", node_id, str); ASSEMBLY_DEBUG("(Node %d) ---> %s", node_id, str); #else printf("%s", str); #endif }
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); } } } }
void dj_init() { //before anything starts, define global variables struct tossim_global_variables* global_variables = malloc(sizeof(struct tossim_global_variables)); struct tossim_UGLY_global_variables* UGLY_global_variables = malloc(sizeof(struct tossim_UGLY_global_variables)); setGlobalVariables(global_variables); setUglyGlobalVariables(UGLY_global_variables); dj_vm *vm; unsigned char *mem = malloc(HEAPSIZE); // initialise memory manager dj_mem_init(mem, HEAPSIZE); _global_ref_t_base_address = (char*)mem - 42; // initialise timer dj_timer_init(); // create a new VM vm = dj_vm_create(); if (vm == nullref) { //fail with a unknown type exception dj_panic(-1); } // tell the execution engine to use the newly created VM instance dj_exec_setVM(vm); // load the embedded infusions dj_named_native_handler handlers[] = { { "base", &base_native_handler }, { "darjeeling", &darjeeling_native_handler } #ifdef WITH_RADIO ,{ "radio", &radio_native_handler } #endif }; int length = sizeof(handlers)/ sizeof(handlers[0]); archive.start = (dj_di_pointer)di_archive_data; archive.end = (dj_di_pointer)(di_archive_data + di_archive_size); dj_vm_loadInfusionArchive(vm, &archive, handlers, length); // load the embedded infusions DARJEELING_PRINTF("%d infusions loaded\n", dj_vm_countInfusions(dj_exec_getVM())); // pre-allocate an OutOfMemoryError object dj_object *obj = dj_vm_createSysLibObject(dj_exec_getVM(), BASE_CDEF_java_lang_OutOfMemoryError); dj_mem_setPanicExceptionObject(obj); }
// TODO niels clean up this function dj_infusion* dj_vm_runClassInitialisers(dj_vm *vm, dj_infusion *infusion) { int i, threadId; dj_thread * thread; dj_frame * frame; dj_global_id methodImplId; uint8_t infusionId; // store infusion ID so that we can get an up-to-date infusion pointer later infusionId = dj_vm_getInfusionId(vm, infusion); // create a new thread object to run the <CLINIT> methods in thread = dj_thread_create(); infusion = dj_vm_getInfusion(vm, infusionId); if (thread == NULL) { DARJEELING_PRINTF("Not enough space for class initializer in infusion %s\n", (char *) dj_di_header_getInfusionName(infusion->header)); dj_panic(DJ_PANIC_OUT_OF_MEMORY); } dj_vm_addThread(dj_exec_getVM(), thread); threadId = thread->id; // iterate over the class list and execute any class initialisers that are encountered int size = dj_di_parentElement_getListSize(infusion->classList); for (i=0; i<size; i++) { infusion = dj_vm_getInfusion(dj_exec_getVM(), infusionId); dj_di_pointer classDef = dj_di_parentElement_getChild(infusion->classList, i); methodImplId.entity_id = dj_di_classDefinition_getCLInit(classDef); methodImplId.infusion = infusion; if (methodImplId.entity_id!=255) { // create a frame to run the initialiser in methodImplId.infusion = infusion; frame = dj_frame_create(methodImplId); // if we're out of memory, panic if (frame==NULL) { DEBUG_LOG(DBG_DARJEELING, "dj_vm_runClassInitialisers: could not create frame. Panicking\n"); DARJEELING_PRINTF("Not enough space to create a frame\n"); dj_panic(DJ_PANIC_OUT_OF_MEMORY); } // the thread we're running the class initialisers in. thread = dj_vm_getThreadById(dj_exec_getVM(), threadId); thread->frameStack = frame; thread->status = THREADSTATUS_RUNNING; dj_exec_activate_thread(thread); // execute the method while (dj_vm_getThreadById(dj_exec_getVM(), threadId)->status!=THREADSTATUS_FINISHED) { // running the CLINIT method may trigger garbage collection dj_exec_run(RUNSIZE); } } } // clean up the thread thread = dj_vm_getThreadById(dj_exec_getVM(), threadId); dj_vm_removeThread(vm, thread); dj_thread_destroy(thread); vm->currentThread = NULL; return infusion; }
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; } }