uint32_t dj_run() { // find thread to schedule dj_vm_schedule(dj_exec_getVM()); if (dj_exec_getCurrentThread()!=NULL) if (dj_exec_getCurrentThread()->status==THREADSTATUS_RUNNING) { dj_exec_run(RUNSIZE); } return dj_vm_getVMSleepTime(dj_exec_getVM()); }
// java.lang.Thread javax.darjeeling.Darjeeling.getThread(short) void javax_darjeeling_Darjeeling_java_lang_Thread_getThread_short() { dj_thread *thread; int index = dj_exec_stackPopShort(); // check for out of bounds if ( (index<0) || (index>=dj_vm_countThreads(dj_exec_getVM())) ) dj_exec_throwHere(dj_vm_createSysLibObject(dj_exec_getVM(), BASE_CDEF_java_lang_IndexOutOfBoundsException)); else { thread = dj_vm_getThread(dj_exec_getVM(), index); dj_exec_stackPushRef(VOIDP_TO_REF(thread)); } }
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); }
inline dj_global_id dj_vm_resolveRuntimeClass(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; PRINTF("Comparing with infusion %d having base id %d\n",dj_vm_getInfusionId(dj_exec_getVM(), infusion), 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 printf("error: class not found: %d\n", id); // dead code to make compiler happy ret.entity_id=255; ret.infusion=NULL; return ret; }
// void java.lang.Object.notifyAll() void java_lang_Object_void_notifyAll() { // Don't pop, just peek the object reference off the runtime stack, // because it's cleared by the VM's frame management. dj_object * object = (dj_object*)REF_TO_VOIDP(dj_exec_stackPeekRef()); dj_vm_notify(dj_exec_getVM(), object, false); }
void javax_virtualsense_network_Packet_javax_virtualsense_network_Packet_createPacket_byte__(){ uint8_t i = 0; dj_object* ret = NULL; dj_int_array * byteArray = REF_TO_VOIDP(dj_exec_stackPopRef()); // create an object or allocate the chunk as is ? //heap_chunk * chk = (heap_chunk *)byteArray; PRINTF("array size is %d\n", byteArray->array.length); // resolve runtime class dj_global_id refClass = dj_vm_resolveRuntimeClass(dj_exec_getVM(), byteArray->data.bytes[4]); if(refClass.infusion != NULL){ ret = (dj_object*)dj_mem_alloc((byteArray->array.length - sizeof(heap_chunk)), byteArray->data.bytes[4]); heap_chunk * chk = getChunk(ret); PRINTF("BEFORE W Created object id %d s %d\n", chk->id, chk->size); memcpy((char*)ret, (char*)(byteArray->data.bytes+sizeof(heap_chunk)), byteArray->array.length- sizeof(heap_chunk)); chk = getChunk(ret); PRINTF("Created object id %d s %d\n", chk->id, chk->size); for(i = 0; i < byteArray->array.length; i++) PRINTF("%x-", byteArray->data.bytes[i]); PRINTF("\n"); }else { PRINTF("Packet not created\n"); } dj_exec_stackPushRef(VOIDP_TO_REF(ret)); // crete a new object from array }
// void java.lang.Object.notify() void java_lang_Object_void_notify() { // Don't pop, just peek the object reference off the runtime stack, // because it's cleared by the VM's frame management. dj_object * object = (dj_object*)REF_TO_VOIDP(dj_exec_stackPeekRef()); // make sure the thread owns the lock // TODO implement this check dj_vm_notify(dj_exec_getVM(), object, false); }
void notify_serial_sendDone() { dj_thread * thread = NULL; if (printfTheadId!=-1) thread = dj_vm_getThreadById(dj_exec_getVM(), printfTheadId); if (thread!=NULL) { if (thread->status==THREADSTATUS_BLOCKED_FOR_IO) thread->status = THREADSTATUS_RUNNING; printfTheadId = -1; } }
void notify_radio_sendDone() { dj_thread * sendThread = NULL; if (_global_radio_sendThreadId!=-1) sendThread = dj_vm_getThreadById(dj_exec_getVM(), _global_radio_sendThreadId); // unblock the thread that was waiting for send if (sendThread!=NULL) { if (sendThread->status==THREADSTATUS_BLOCKED_FOR_IO){ DEBUG_LOG(DBG_DARJEELING, DARJEELING, "sendDone runs \t\tthread[%p]\n", sendThread); sendThread->status = THREADSTATUS_RUNNING; } _global_radio_sendThreadId = -1; } }
void java_lang_Object_java_lang_String_toString() { // Don't pop, just peek the object reference off the runtime stack, // because it's cleared by the VM's frame management. dj_object * obj = REF_TO_VOIDP(dj_exec_stackPeekRef()); // Get class definition runtime_id_t classRuntimeId = dj_mem_getChunkId(obj); dj_global_id classGlobalId = dj_vm_getRuntimeClass(dj_exec_getVM(), classRuntimeId); // Get class name dj_di_pointer classDefinition = dj_global_id_getClassDefinition(classGlobalId); dj_local_id classNameLocalId = dj_di_classDefinition_getClassName(classDefinition); dj_global_id classNameGlobalId = dj_global_id_resolve(classGlobalId.infusion, classNameLocalId); dj_object * string = dj_jstring_createFromGlobalId(dj_exec_getVM(), classNameGlobalId); if (string==NULL) dj_exec_createAndThrow(BASE_CDEF_java_lang_OutOfMemoryError); else dj_exec_stackPushRef(VOIDP_TO_REF(string)); }
// void javax.radio.Radio._waitForMessage() void javax_radio_Radio_void__waitForMessage() { // while (receiveThreadId != -1); dj_thread * currentThread = dj_exec_getCurrentThread(); if (tossim_getNrMessages()==0) { DEBUG_LOG(DBG_DARJEELING, DARJEELING, "vm[%p]\n", dj_exec_getVM()); DEBUG_LOG(DBG_DARJEELING, DARJEELING, "waitFor\t\tthread[%p]->status from %d to %d\n", currentThread, currentThread->status, THREADSTATUS_BLOCKED_FOR_IO); // block the current thread for IO currentThread->status = THREADSTATUS_BLOCKED_FOR_IO; currentThread->scheduleTime = 0; _global_radio_receiveThreadId = currentThread->id; dj_exec_breakExecution(); } }
// void javax.radio.Radio._broadcast(byte[]) void javax_radio_Radio_void__broadcast_byte__() { dj_thread * currentThread = dj_exec_getCurrentThread(); // get byte array to send dj_int_array * arr = REF_TO_VOIDP(dj_exec_stackPopRef()); if (tossim_send((char*)arr->data.bytes, 0xffff, arr->array.length)==0) { // block the current thread for IO dj_vm* vm = dj_exec_getVM(); DEBUG_LOG(DBG_DARJEELING, DARJEELING, "broadcast stops\t\tthread[%p]\n", currentThread); currentThread->status = THREADSTATUS_BLOCKED_FOR_IO; _global_radio_sendThreadId = currentThread->id; dj_exec_breakExecution(); } }
void notify_radio_receive() { // unblock the thread that was waiting for send dj_thread * receiveThread = NULL; if (_global_radio_receiveThreadId!=-1) receiveThread = dj_vm_getThreadById(dj_exec_getVM(), _global_radio_receiveThreadId); if (receiveThread!=NULL) { if (receiveThread->status==THREADSTATUS_BLOCKED_FOR_IO){ DEBUG_LOG(DBG_DARJEELING, DARJEELING, "notifyReceive runs \tthread[%p]\n", receiveThread); receiveThread->status = THREADSTATUS_RUNNING; } _global_radio_receiveThreadId = -1; } }
// short javax.darjeeling.Darjeeling.getNrThreads() void javax_darjeeling_Darjeeling_short_getNrThreads() { dj_exec_stackPushShort(dj_vm_countThreads(dj_exec_getVM())); }
// 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 javax_wukong_wkpf_WKPF_void_appInitCreateLocalObjectAndInitValues() { dj_vm *vm = dj_exec_getVM(); wkpf_initLocalObjectAndInitValues(vm->di_app_infusion_archive_data); }
void javax_wukong_wkpf_WKPF_void_appLoadInitLinkTableAndComponentMap() { dj_vm *vm = dj_exec_getVM(); wkpf_initLinkTableAndComponentMap(vm->di_app_infusion_archive_data); }