OP_INVOKE_VIRTUAL.S revision c4080f6bdeda19901a508cc75f96ac7e07903918
189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project 289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project%default { "isrange":"0", "routine":"NoRange" } 389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project%verify "executed" 489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project%verify "unknown method" 589c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project%verify "null object" 689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project /* 789c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project * Handle a virtual method call. 889c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project * 989c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project * for: invoke-virtual, invoke-virtual/range 1089c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project */ 1189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 1389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project GET_GLUE(%eax) 1489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movzwl 2(rPC),%ecx # ecx<- BBBB 1589c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 1689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project EXPORT_PC() 1789c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 1889c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 1989c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project testl %eax,%eax # already resolved? 2089c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project jne .L${opcode}_continue # yes, continue 2189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project GET_GLUE(%eax) 2289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl %ecx,OUT_ARG1(%esp) # arg1<- ref 2389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offGlue_method(%eax),%eax # eax<- glue->method 2489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project SPILL(rPC) 2589c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project jmp .L${opcode}_more 2689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project%break 2789c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project 2889c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project 2989c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project.L${opcode}_more: 3089c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 3189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl %eax,OUT_ARG0(%esp) # arg0<- clazz 3289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl $$METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 3389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project call dvmResolveMethod # eax<- call(clazz, ref, flags) 3489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project UNSPILL(rPC) 3589c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project testl %eax,%eax # got null? 3689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project jne .L${opcode}_continue # no, continue 3789c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project jmp common_exceptionThrown # yes, handle exception 3889c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project 3989c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project /* At this point: 4089c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project * eax = resolved base method 4189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project * ecx = scratch 4289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project */ 4389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project.L${opcode}_continue: 4489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 4589c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project .if (!$isrange) 4689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project andl $$0xf,%ecx # ecx<- D (or stays CCCC) 4789c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project .endif 4889c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project GET_VREG(%ecx,%ecx) # ecx<- "this" 4989c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 5089c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project testl %ecx,%ecx # null this? 5189c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project je common_errNullObject # go if so 5289c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 5389c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 5489c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 55c4080f6bdeda19901a508cc75f96ac7e07903918Johnnie Birch jmp common_invokeMethod${routine} 5689c1feb0a69a7707b271086e749975b3f7acacf7The Android Open Source Project 57