1 %default { "isrange":"0", "routine":"NoRange" }
3 %verify "unknown method"
5 * Handle a "super" method call.
7 * for: invoke-super, invoke-super/range
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
14 and t0, t0, 15 # t0 <- D (or stays CCCC)
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
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
28 move a0, rBIX # a0 <- method->clazz
29 li a2, METHOD_VIRTUAL # resolver method type
30 JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags)
33 beqz v0, common_exceptionThrown # yes, handle exception
34 b .L${opcode}_continue
39 * a0 = resolved base method
40 * rBIX = method->clazz
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
54 * Throw a NoSuchMethodError with the method name as the message.
55 * a0 = resolved base method
58 LOAD_base_offMethod_name(a1, a0) # a1 <- method name
59 b common_errNoSuchMethod