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    movl      rSELF,rINST
12    movzwl    2(rPC),%eax               # eax<- BBBB
13    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
14    EXPORT_PC
15    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
16    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
17    movl      offThread_method(rINST),%eax # eax<- method
18    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
19    .if       (!$isrange)
20    andl      $$0xf,rINST               # rINST<- D (or stays CCCC)
21    .endif
22    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
23    testl     %edx,%edx                # null "this"?
24    SPILL_TMP1(%edx)
25    je        common_errNullObject      # yes, throw
26    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
27    testl     %ecx,%ecx                 # already resolved?
28    je       .L${opcode}_resolve
29    /*
30     * At this point:
31     *  ecx = resolved base method [r0]
32     *  eax = method->clazz [r9]
33     */
34.L${opcode}_continue:
35    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
36    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
37    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
38    jae     .L${opcode}_nsm           # method not present in superclass
39    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
40    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
41    UNSPILL_TMP1(%edx)
42    movl    %edx, %ecx
43    jmp     common_invokeMethod${routine}
44
45
46    /* At this point:
47     * ecx = null (needs to be resolved base method)
48     * eax = method->clazz
49    */
50.L${opcode}_resolve:
51    SPILL_TMP2(%eax)                    # method->clazz
52    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
53    movzwl  2(rPC),%ecx                 # ecx<- BBBB
54    movl    $$METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
55    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
56    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
57    testl   %eax,%eax                   # got null?
58    movl    %eax,%ecx                   # ecx<- resolved base method
59    UNSPILL_TMP2(%eax)                  # restore method->clazz
60    jne     .L${opcode}_continue        # good to go - continue
61    jmp     common_exceptionThrown      # handle exception
62
63    /*
64     * Throw a NoSuchMethodError with the method name as the message.
65     *  ecx = resolved base method
66     */
67.L${opcode}_nsm:
68    movl    offMethod_name(%ecx),%eax
69    jmp     common_errNoSuchMethod
70