Compile table traversals: next(), pairs(), BC_ISNEXT/BC_ITERN.
Sponsored by OpenResty Inc.
This commit is contained in:
@@ -2064,6 +2064,63 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|//-- Miscellaneous functions --------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
|
||||
|.define NEXT_TAB, TAB:CARG1
|
||||
|.define NEXT_RES, CARG1
|
||||
|.define NEXT_IDX, CARG2w
|
||||
|.define NEXT_LIM, CARG3w
|
||||
|.define NEXT_TMP0, TMP0
|
||||
|.define NEXT_TMP0w, TMP0w
|
||||
|.define NEXT_TMP1, TMP1
|
||||
|.define NEXT_TMP1w, TMP1w
|
||||
|.define NEXT_RES_PTR, sp
|
||||
|.define NEXT_RES_VAL, [sp]
|
||||
|.define NEXT_RES_KEY, [sp, #8]
|
||||
|
|
||||
|// TValue *lj_vm_next(GCtab *t, uint32_t idx)
|
||||
|// Next idx returned in CRET2w.
|
||||
|->vm_next:
|
||||
|.if JIT
|
||||
| ldr NEXT_LIM, NEXT_TAB->asize
|
||||
| ldr NEXT_TMP1, NEXT_TAB->array
|
||||
|1: // Traverse array part.
|
||||
| subs NEXT_TMP0w, NEXT_IDX, NEXT_LIM
|
||||
| bhs >5 // Index points after array part?
|
||||
| ldr NEXT_TMP0, [NEXT_TMP1, NEXT_IDX, uxtw #3]
|
||||
| cmn NEXT_TMP0, #-LJ_TNIL
|
||||
| cinc NEXT_IDX, NEXT_IDX, eq
|
||||
| beq <1 // Skip holes in array part.
|
||||
| str NEXT_TMP0, NEXT_RES_VAL
|
||||
| movz NEXT_TMP0w, #(LJ_TISNUM>>1)&0xffff, lsl #16
|
||||
| stp NEXT_IDX, NEXT_TMP0w, NEXT_RES_KEY
|
||||
| add NEXT_IDX, NEXT_IDX, #1
|
||||
| mov NEXT_RES, NEXT_RES_PTR
|
||||
|4:
|
||||
| ret
|
||||
|
|
||||
|5: // Traverse hash part.
|
||||
| ldr NEXT_TMP1w, NEXT_TAB->hmask
|
||||
| ldr NODE:NEXT_RES, NEXT_TAB->node
|
||||
| add NEXT_TMP0w, NEXT_TMP0w, NEXT_TMP0w, lsl #1
|
||||
| add NEXT_LIM, NEXT_LIM, NEXT_TMP1w
|
||||
| add NODE:NEXT_RES, NODE:NEXT_RES, NEXT_TMP0w, uxtw #3
|
||||
|6:
|
||||
| cmp NEXT_IDX, NEXT_LIM
|
||||
| bhi >9
|
||||
| ldr NEXT_TMP0, NODE:NEXT_RES->val
|
||||
| cmn NEXT_TMP0, #-LJ_TNIL
|
||||
| add NEXT_IDX, NEXT_IDX, #1
|
||||
| bne <4
|
||||
| // Skip holes in hash part.
|
||||
| add NODE:NEXT_RES, NODE:NEXT_RES, #sizeof(Node)
|
||||
| b <6
|
||||
|
|
||||
|9: // End of iteration. Set the key to nil (not the value).
|
||||
| movn NEXT_TMP0, #0
|
||||
| str NEXT_TMP0, NEXT_RES_KEY
|
||||
| mov NEXT_RES, NEXT_RES_PTR
|
||||
| ret
|
||||
|.endif
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- FFI helper functions -----------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
@@ -3320,10 +3377,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
break;
|
||||
|
||||
case BC_ITERN:
|
||||
| // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
|
||||
|.if JIT
|
||||
| // NYI: add hotloop, record BC_ITERN.
|
||||
| hotloop
|
||||
|.endif
|
||||
|->vm_IITERN:
|
||||
| // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
|
||||
| add RA, BASE, RA, lsl #3
|
||||
| ldr TAB:RB, [RA, #-16]
|
||||
| ldrh TMP3w, [PC, # OFS_RD]
|
||||
@@ -3390,11 +3448,28 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next
|
||||
|
|
||||
|5: // Despecialize bytecode if any of the checks fail.
|
||||
|.if JIT
|
||||
| ldrb TMP2w, [RC, # OFS_OP]
|
||||
|.endif
|
||||
| mov TMP0, #BC_JMP
|
||||
| mov TMP1, #BC_ITERC
|
||||
| strb TMP0w, [PC, #-4+OFS_OP]
|
||||
|.if JIT
|
||||
| cmp TMP2w, #BC_ITERN
|
||||
| bne >6
|
||||
|.endif
|
||||
| strb TMP1w, [RC, # OFS_OP]
|
||||
| b <1
|
||||
|.if JIT
|
||||
|6: // Unpatch JLOOP.
|
||||
| ldr RA, [GL, #GL_J(trace)]
|
||||
| ldrh TMP2w, [RC, # OFS_RD]
|
||||
| ldr TRACE:RA, [RA, TMP2, lsl #3]
|
||||
| ldr TMP2w, TRACE:RA->startins
|
||||
| bfxil TMP2w, TMP1w, #0, #8
|
||||
| str TMP2w, [RC]
|
||||
| b <1
|
||||
|.endif
|
||||
break;
|
||||
|
||||
case BC_VARG:
|
||||
|
||||
Reference in New Issue
Block a user