We can not accept any native method for execution- Those should understand the stack. For native methods we fix the stack top to point to actual data- since there is nothing we need to generate- we dont need the clever stack pointer-
The signature of each native method must match the following type signature:
typedef Variable (*NativeMethod)(Context* pContext);
Lets define our helper for native method. And here also we do not deal with machine instruction since there is nothing to parse- (well except the return type of the method)-
u4 ExecuteNativeMethod(Context* pContext, CString strClassName, CString strMethod, CString strDesc) { JavaClass *pClass = pContext->pClass; LOG(_T("Execute NativeMethod %s.%s%s \n"),strClassName , strMethod, strDesc); CString strSignature= GetNativeMethodSignature(strClassName, strMethod, strDesc); NativeMethod nativeMethod=pContext->pVMEnv->pNativeMethodProvider->GetNativeMethod(strSignature); if(nativeMethod == NULL) { ASSERT(FALSE); return -1; } else { Variable retVal = nativeMethod(pContext); //if returns then get on stack if(strDesc.Find(_T(")V")) < 0) { if(strDesc.Find(_T(")J")) < 0 && (strDesc.Find(_T(")D")) < 0)) { //todo validate pContext->stack[0]=retVal; } else { pContext->stack[0].intValue=0; pContext->stack[1]=retVal; } } } return 0; }
OK, lets now define a simple native method that adds two numbers:
Variable Add(Context* pContext) { Variable returnVal; //The stack top is right in native methods- returnVal.intValue = pContext->stack[pContext->stackTop].intValue + pContext->stack[pContext->stackTop-1].intValue; return returnVal; }
Thats all for native methods for now. We'll add some native methods to dynamically load native method-
No comments:
Post a Comment