From 077ccc86580b5d075297f513ea44c130bfdaa31f Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 22 Dec 2016 14:59:37 -0500 Subject: [PATCH] Implement LEN. Enables length of tables and strings to be taken, for example: t = "hello" print(#t) -- prints 5 t = {1,2} print(#t) -- prints 2 --- src/vm_s390x.dasc | 60 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src/vm_s390x.dasc b/src/vm_s390x.dasc index 2bba69f3..dedccf20 100644 --- a/src/vm_s390x.dasc +++ b/src/vm_s390x.dasc @@ -845,8 +845,28 @@ static void build_subroutines(BuildCtx *ctx) | j ->vm_call_dispatch | |->vmeta_len: - | stg r0, 0(r0) - | stg r0, 0(r0) + | llgh RD, PC_RD + | sllg RD, RD, 3(r0) + | lg L:RB, SAVE_L + | stg BASE, L:RB->base + | la CARG2, 0(RD, BASE) + | lgr L:CARG1, L:RB + | stg PC, SAVE_PC + | brasl r14, extern lj_meta_len // (lua_State *L, TValue *o) + | // NULL (retry) or TValue * (metamethod) returned in r2 (CRET1). + | lgr RC, CRET1 + | lg BASE, L:RB->base +#if LJ_52 + | cghi RC, 0 + | jne ->vmeta_binop // Binop call for compatibility. + | llgh RD, PC_RD + | sllg RD, RD, 3(r0) + | lg TAB:CARG1, 0(RD, BASE) + | cleartp TAB:CARG1 + | j ->BC_LEN_Z +#else + | j ->vmeta_binop // Binop call for compatibility. +#endif | |//-- Call metamethod ---------------------------------------------------- | @@ -1698,8 +1718,40 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | j <1 break; case BC_LEN: - | stg r0, 0(r0) - | stg r0, 0(r0) + | ins_AD // RA = dst, RD = src + | sllg RD, RD, 3(r0) + | lg RD, 0(RD, BASE) + | checkstr RD, >2 + | llgf RD, STR:RD->len + |1: + | sllg RA, RA, 3(r0) + | setint RD + | stg RD, 0(RA, BASE) + | ins_next + |2: + | cghi ITYPE, LJ_TTAB; jne ->vmeta_len + | lgr TAB:CARG1, TAB:RD +#if LJ_52 + | lg TAB:RB, TAB:RD->metatable + | cghi TAB:RB, 0 + | jne >9 + |3: +#endif + |->BC_LEN_Z: + | lgr RB, BASE // Save BASE. + | brasl r14, extern lj_tab_len // (GCtab *t) + | // Length of table returned in r2 (CRET1). + | lgr RD, CRET1 + | lgr BASE, RB // Restore BASE. + | llgc RA, PC_RA + | j <1 +#if LJ_52 + |9: // Check for __len. + | llgc TMPR2, TAB:RB->nomm + | tmll TMPR2, 1<vmeta_len // 'no __len' flag NOT set: check. +#endif break; /* -- Binary ops -------------------------------------------------------- */