From 21f2fdfab241d046af9e7a9070be2c0fdb321b38 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 29 Dec 2016 17:37:11 -0500 Subject: [PATCH] Partially implement ipairs. Still need to handle ipairs_aux. --- src/vm_s390x.dasc | 109 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/src/vm_s390x.dasc b/src/vm_s390x.dasc index 35261391..9985f1a7 100644 --- a/src/vm_s390x.dasc +++ b/src/vm_s390x.dasc @@ -431,12 +431,23 @@ static void build_subroutines(BuildCtx *ctx) | stg r0, 0(r0) | |->vm_unwind_ff: // Unwind C stack, return from ff pcall. - | stg r0, 0(r0) - | stg r0, 0(r0) - | + | // (void *cframe) + | nill CARG1, CFRAME_RAWMASK // Assumes high 48-bits set in CFRAME_RAWMASK. + | lgr sp, CARG1 |->vm_unwind_ff_eh: // Landing pad for external unwinder. - | stg r0, 0(r0) - | stg r0, 0(r0) + | lg L:RB, SAVE_L + | lghi RD, 1+1 // Really 1+2 results, incr. later. + | lg BASE, L:RB->base + | lg DISPATCH, L:RB->glref // Setup pointer to dispatch table. + | lay DISPATCH, GG_G2DISP(DISPATCH) + | lg PC, -8(BASE) // Fetch PC of previous frame. + | load_false RA + | lg RB, 0(BASE) + | stg RA, -16(BASE) // Prepend false to error message. + | stg RB, -8(BASE) + | lghi RA, -16 // Results start at BASE+RA = BASE-16. + | set_vmstate INTERP + | j ->vm_returnc // Increments RD/MULTRES and returns. | |//----------------------------------------------------------------------- |//-- Grow stack for calls ----------------------------------------------- @@ -1086,19 +1097,60 @@ static void build_subroutines(BuildCtx *ctx) |//-- Base library: iterators ------------------------------------------- | |.ffunc_1 next + | stg r0, 0(r0) + | stg r0, 0(r0) | |.ffunc_1 pairs + | stg r0, 0(r0) + | stg r0, 0(r0) | |.ffunc_2 ipairs_aux + | stg r0, 0(r0) + | stg r0, 0(r0) |->fff_res0: + | stg r0, 0(r0) + | stg r0, 0(r0) | |.ffunc_1 ipairs + | lg TAB:RB, 0(BASE) + | lgr TMPR1, TAB:RB + | checktab TAB:RB, ->fff_fallback +#if LJ_52 + | lghi TMPR2, 0 + | cg TMPR2, TAB:RB->metatable; jne ->fff_fallback +#endif + | lg CFUNC:RD, -16(BASE) + | cleartp CFUNC:RD + | lg CFUNC:RD, CFUNC:RD->upvalue[0] + | settp CFUNC:RD, LJ_TFUNC + | lg PC, -8(BASE) + | stg CFUNC:RD, -16(BASE) + | stg TMPR1, -8(BASE) + | llihh RD, ((int)LJ_TISNUM)>>1 // mov64 RD, ((int64_t)LJ_TISNUM<<47) // TODO: write mov64-macro, use all of TISNUM (currently this is very fragile). + | stg RD, 0(BASE) + | lghi RD, 1+3 + | j ->fff_res | |//-- Base library: catch errors ---------------------------------------- | |.ffunc_1 pcall - | stg r0, 0(r0) - | stg r0, 0(r0) + | la RA, 16(BASE) + | aghi NARGS:RD, -1 + | lghi PC, 16+FRAME_PCALL + |1: + | llgc RB, (DISPATCH_GL(hookmask))(DISPATCH) + | srlg RB, RB, HOOK_ACTIVE_SHIFT(r0) + | nill RB, 1 // High bits already zero (from load). + | agr PC, RB // Remember active hook before pcall. + | // Note: this does a (harmless) copy of the function to the PC slot, too. + | lgr KBASE, RD + |2: + | sllg TMPR1, KBASE, 3(r0) + | lg RB, -24(TMPR1, RA) + | stg RB, -16(TMPR1, RA) + | aghi KBASE, -1 + | jh <2 + | j ->vm_call_dispatch | |.ffunc_2 xpcall | stg r0, 0(r0) @@ -2846,9 +2898,21 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_ITERC: - | stg r0, 0(r0) - | stg r0, 0(r0) + | ins_A // RA = base, (RB = nresults+1,) RC = nargs+1 (2+1) + | sllg RA, RA, 3(r0) + | la RA, 16(RA, BASE) // fb = base+2 + | lg RB, -32(RA) // Copy state. fb[0] = fb[-4]. + | lg RC, -24(RA) // Copy control var. fb[1] = fb[-3]. + | stg RB, 0(RA) + | stg RC, 8(RA) + | lg LFUNC:RB, -40(RA) // Copy callable. fb[-2] = fb[-5] + | stg LFUNC:RB, -16(RA) + | lghi NARGS:RD, 2+1 // Handle like a regular 2-arg call. + | checkfunc LFUNC:RB, ->vmeta_call + | lgr BASE, RA + | ins_call break; + case BC_ITERN: | stg r0, 0(r0) | stg r0, 0(r0) @@ -3156,16 +3220,31 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_ITERL: - | stg r0, 0(r0) - | stg r0, 0(r0) + |.if JIT + | hotloop RB + |.endif + | // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op. break; + case BC_JITERL: - | stg r0, 0(r0) - | stg r0, 0(r0) +#if !LJ_HASJIT break; +#endif case BC_IITERL: - | stg r0, 0(r0) - | stg r0, 0(r0) + | ins_AJ // RA = base, RD = target + | sllg RA, RA, 3(r0) + | la RA, 0(RA, BASE) + | lg RB, 0(RA) + | cghi RB, LJ_TNIL; je >1 // Stop if iterator returned nil. + if (op == BC_JITERL) { + | stg RB, -8(RA) + | j =>BC_JLOOP + } else { + | branchPC RD // Otherwise save control var + branch. + | stg RB, -8(RA) + } + |1: + | ins_next break; case BC_LOOP: