Since we have the object creation code in
JavaClass
it is very easy to create an object on the heap. We just call the CreateObject
method of the current class that is already pushed on the stack by previous instructions:int CreateNewObject(Context *pContext, u2 index) { if(!pContext->pClass->CreateObject(index, pContext->pVMEnv->pObjectHeap, pContext->stack[pContext->stackTop].object)) return -1; pContext->stackTop++; return 0; }
Now let us create the helper methods for the
new
instruction:void EmitExecuteNew(u1* code, int &ip, u4 index) { u1 c[] = { //((int (*)(Context *pContext, u2 index))pContext->pVMEnv->ppHelperMethods[EXECUTE_NEW_HELPER_INDEX])(pContext, index); 0x8B, 0xF4, // mov esi,esp 0x68, 0x00, 0x00, 0x00, 0x00, // push index 0x8B, 0x45, 0x08, // mov eax,dword ptr [pContext] 0x50, // push eax 0x8B, 0x4D, 0x08, // mov ecx,dword ptr [pContext] 0x8B, 0x51, 0x10, // mov edx,dword ptr [ecx+10h] 0x8B, 0x42, 0x08, // mov eax,dword ptr [edx+8] 0x8B, 0x48, 0x04, // mov ecx,dword ptr [eax+4] 0xFF, 0xD1, // call ecx 0x83, 0xC4, 0x08, // add esp,8 }; memcpy(c+3, &index, sizeof(index)); memcpy(&code[ip], c, sizeof(c)); ip+=sizeof(c); } void ExecuteNew(u1* code, int& ip, u2 index) { EmitExecuteNew(code, ip, index); }
With the call mechanism that wer built to call method is used to callback the object creation method here.
And from the
Compile
method we just add a call for the new
instruction:case _new:// 187(0xbb) -'new' is a keyword in C++ so we use '_new' :) ExecuteNew(codes, ip, getu2(&bc[pc+1])); pc+=3; break;
We actually have all the basic mechanism built. We just need to add things like native method support, garbase collector and helpers for remaining instruction. Those will be managed mostly in C++ since there is nothing to parse for them the optimizing C++ compiler does all the good thing for us.
No comments:
Post a Comment