|->vmeta_call: // Resolve and call __call metamethod.
| NYI
|
+ |->vmeta_callt: // Resolve __call for BC_CALLT.
+ | NYI
+ |
|//-- Argument coercion for 'for' statement ------------------------------
|
|->vmeta_for:
break;
case BC_CALLMT:
- | NYI
+ | // RA = base*8, (RB = 0,) RC = extra_nargs*8
+ | lwz TMP0, SAVE_MULTRES
+ | add NARGS8:RC, NARGS8:RC, TMP0
+ | // Fall through. Assumes BC_CALLT follows.
break;
case BC_CALLT:
- | NYI
+ | // RA = base*8, (RB = 0,) RC = (nargs+1)*8
+ | evlddx LFUNC:RB, BASE, RA
+ | add RA, BASE, RA
+ | lwz TMP1, FRAME_PC(BASE)
+ | subi NARGS8:RC, NARGS8:RC, 8
+ | checkfunc LFUNC:RB
+ | addi RA, RA, 8
+ | checkfail ->vmeta_callt
+ |->BC_CALLT_Z:
+ | andi. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand.
+ | lbz TMP3, LFUNC:RB->ffid
+ | xori TMP2, TMP1, FRAME_VARG
+ | cmpwi cr1, NARGS8:RC, 0
+ | bne >7
+ |1:
+ | stw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC.
+ | li TMP2, 0
+ | cmplwi cr7, TMP3, 1 // (> FF_C) Calling a fast function?
+ | beq cr1, >3
+ |2:
+ | addi TMP3, TMP2, 8
+ | evlddx TMP0, RA, TMP2
+ | cmpw cr1, TMP3, NARGS8:RC
+ | evstddx TMP0, BASE, TMP2
+ | mr TMP2, TMP3
+ | bne cr1, <2
+ |3:
+ | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt
+ | beq >5
+ |4:
+ | ins_callt
+ |
+ |5: // Tailcall to a fast function with a Lua frame below.
+ | lwz INS, -4(TMP1)
+ | decode_RA8 RA, INS
+ | sub TMP1, BASE, RA
+ | lwz LFUNC:TMP1, FRAME_FUNC(TMP1)
+ | lwz TMP1, LFUNC:TMP1->pc
+ | lwz KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE.
+ | b <4
+ |
+ |7: // Tailcall from a vararg function.
+ | andi. TMP0, TMP2, FRAME_TYPEP
+ | bne <1 // Vararg frame below?
+ | sub BASE, BASE, TMP2 // Relocate BASE down.
+ | lwz TMP1, FRAME_PC(BASE)
+ | andi. TMP0, TMP1, FRAME_TYPE
+ | b <1
break;
case BC_ITERC: