1 %default { "isrange":"0", "routine":"NoRange" } 2 %verify "executed" 3 %verify "unknown method" 4 /* 5 * Handle a "super" method call. 6 * 7 * for: invoke-super, invoke-super/range 8 */ 9 # op vB, {vD, vE, vF, vG, vA}, class /* CCCC */ 10 # op vAA, {vCCCC..v(CCCC+AA-1)}, meth /* BBBB */ 11 FETCH(t0, 2) # t0 <- GFED or CCCC 12 LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex 13 .if (!$isrange) 14 and t0, t0, 15 # t0 <- D (or stays CCCC) 15 .endif 16 FETCH(a1, 1) # a1 <- BBBB 17 LOAD_base_offDvmDex_pResMethods(a3, a3) # a3 <- pDvmDex->pResMethods 18 GET_VREG(rOBJ, t0) # rOBJ <- "this" ptr 19 LOAD_eas2(a0, a3, a1) # a0 <- resolved baseMethod 20 # null "this"? 21 LOAD_rSELF_method(t1) # t1 <- current method 22 beqz rOBJ, common_errNullObject # null "this", throw exception 23 # cmp a0, 0; already resolved? 24 LOAD_base_offMethod_clazz(rBIX, t1) # rBIX <- method->clazz 25 EXPORT_PC() # must export for invoke 26 bnez a0, .L${opcode}_continue # resolved, continue on 27 28 move a0, rBIX # a0 <- method->clazz 29 li a2, METHOD_VIRTUAL # resolver method type 30 JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags) 31 move a0, v0 32 # got null? 33 beqz v0, common_exceptionThrown # yes, handle exception 34 b .L${opcode}_continue 35 %break 36 37 /* 38 * At this point: 39 * a0 = resolved base method 40 * rBIX = method->clazz 41 */ 42 .L${opcode}_continue: 43 LOAD_base_offClassObject_super(a1, rBIX) # a1 <- method->clazz->super 44 LOADu2_offMethod_methodIndex(a2, a0) # a2 <- baseMethod->methodIndex 45 LOAD_base_offClassObject_vtableCount(a3, a1) # a3 <- super->vtableCount 46 EXPORT_PC() # must export for invoke 47 # compare (methodIndex, vtableCount) 48 bgeu a2, a3, .L${opcode}_nsm # method not present in superclass 49 LOAD_base_offClassObject_vtable(a1, a1) # a1 <- ...clazz->super->vtable 50 LOAD_eas2(a0, a1, a2) # a0 <- vtable[methodIndex] 51 b common_invokeMethod${routine} # continue on 52 53 /* 54 * Throw a NoSuchMethodError with the method name as the message. 55 * a0 = resolved base method 56 */ 57 .L${opcode}_nsm: 58 LOAD_base_offMethod_name(a1, a0) # a1 <- method name 59 b common_errNoSuchMethod 60 61