diff --git a/src/Makefile.dep b/src/Makefile.dep index c501db44..a29b396a 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -96,10 +96,10 @@ lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \ lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ - lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \ - lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \ - lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \ - lj_vm.h luajit.h + lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \ + lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \ + lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h lj_dispatch.h \ + lj_traceerr.h lj_vm.h luajit.h lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \ lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \ lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ diff --git a/src/lib_string.c b/src/lib_string.c index 27e0d594..c8243d6c 100644 --- a/src/lib_string.c +++ b/src/lib_string.c @@ -135,8 +135,7 @@ LJLIB_ASM(string_rep) LJLIB_ASM(string_reverse) { - GCstr *s = lj_lib_checkstr(L, 1); - lj_buf_tmp(L, s->len); + lj_lib_checkstr(L, 1); return FFH_RETRY; } LJLIB_ASM_(string_lower) diff --git a/src/lj_buf.c b/src/lj_buf.c index 67525694..32ed52b9 100644 --- a/src/lj_buf.c +++ b/src/lj_buf.c @@ -34,7 +34,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en) char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz) { SBuf *sb = &G(L)->tmpbuf; - setmref(sb->L, L); + setsbufL(sb, L); return lj_buf_need(sb, sz); } @@ -95,12 +95,59 @@ SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o) setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o)); return sb; } +#endif + +SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s) +{ + MSize len = s->len; + char *p = lj_buf_more(sb, len), *e = p+len; + const char *q = strdata(s)+len-1; + while (p < e) + *p++ = *q--; + setsbufP(sb, p); + return sb; +} + +SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s) +{ + MSize len = s->len; + char *p = lj_buf_more(sb, len), *e = p+len; + const char *q = strdata(s); + for (; p < e; p++, q++) { + uint32_t c = *(unsigned char *)q; +#if LJ_TARGET_PPC + *p = c + ((c >= 'A' && c <= 'Z') << 5); +#else + if (c >= 'A' && c <= 'Z') c += 0x20; + *p = c; +#endif + } + setsbufP(sb, p); + return sb; +} + +SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s) +{ + MSize len = s->len; + char *p = lj_buf_more(sb, len), *e = p+len; + const char *q = strdata(s); + for (; p < e; p++, q++) { + uint32_t c = *(unsigned char *)q; +#if LJ_TARGET_PPC + *p = c - ((c >= 'a' && c <= 'z') << 5); +#else + if (c >= 'a' && c <= 'z') c -= 0x20; + *p = c; +#endif + } + setsbufP(sb, p); + return sb; +} GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb) { return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb)); } -#endif uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp) { diff --git a/src/lj_buf.h b/src/lj_buf.h index 426ec720..98bcad20 100644 --- a/src/lj_buf.h +++ b/src/lj_buf.h @@ -31,8 +31,11 @@ LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s); LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c); LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k); LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o); -LJ_FUNC GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb); #endif +LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s); +LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s); +LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s); +LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb); LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp); LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v); diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index d57f1a6f..c144afce 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c @@ -8,6 +8,7 @@ #include "lj_obj.h" #include "lj_err.h" +#include "lj_buf.h" #include "lj_func.h" #include "lj_str.h" #include "lj_tab.h" diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h index a03804af..1368594a 100644 --- a/src/lj_dispatch.h +++ b/src/lj_dispatch.h @@ -37,7 +37,8 @@ _(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \ _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \ _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \ - _(lj_tab_setinth) JITGOTDEF(_) FFIGOTDEF(_) + _(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \ + _(lj_buf_putstr_upper) _(lj_buf_tostr) JITGOTDEF(_) FFIGOTDEF(_) enum { #define GOTENUM(name) LJ_GOT_##name, diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 4579b263..5a15c409 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc @@ -99,6 +99,7 @@ |.type NODE, Node |.type NARGS8, int |.type TRACE, GCtrace +|.type SBUF, SBuf | |//----------------------------------------------------------------------- | @@ -1743,6 +1744,7 @@ static void build_subroutines(BuildCtx *ctx) | mov CARG1, L | str PC, SAVE_PC | bl extern lj_str_new // (lua_State *L, char *str, size_t l) + |->fff_resstr: | // Returns GCstr *. | ldr BASE, L->base | mvn CARG2, #~LJ_TSTR @@ -1813,56 +1815,28 @@ static void build_subroutines(BuildCtx *ctx) | bge <1 | b ->fff_newstr | - |.ffunc string_reverse + |.macro ffstring_op, name + | .ffunc string_ .. name | ffgccheck - | ldrd CARG12, [BASE] + | ldr CARG3, [BASE, #4] | cmp NARGS8:RC, #8 + | ldr STR:CARG2, [BASE] | blo ->fff_fallback - | checkstr CARG2, ->fff_fallback - | ldr CARG3, STR:CARG1->len - | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] - | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] - | mov CARG4, CARG3 - | add CARG1, STR:CARG1, #sizeof(GCstr) - | add INS, CARG2, CARG3 - | cmp RB, INS - | blo ->fff_fallback - |1: // Reverse string copy. - | ldrb RB, [CARG1], #1 - | subs CARG4, CARG4, #1 - | blt ->fff_newstr - | strb RB, [CARG2, CARG4] - | b <1 - | - |.macro ffstring_case, name, lo - | .ffunc name - | ffgccheck - | ldrd CARG12, [BASE] - | cmp NARGS8:RC, #8 - | blo ->fff_fallback - | checkstr CARG2, ->fff_fallback - | ldr CARG3, STR:CARG1->len - | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] - | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] - | mov CARG4, #0 - | add CARG1, STR:CARG1, #sizeof(GCstr) - | add INS, CARG2, CARG3 - | cmp RB, INS - | blo ->fff_fallback - |1: // ASCII case conversion. - | ldrb RB, [CARG1, CARG4] - | cmp CARG4, CARG3 - | bhs ->fff_newstr - | sub RC, RB, #lo - | cmp RC, #26 - | eorlo RB, RB, #0x20 - | strb RB, [CARG2, CARG4] - | add CARG4, CARG4, #1 - | b <1 + | sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf) + | checkstr CARG3, ->fff_fallback + | ldr CARG4, SBUF:CARG1->b + | str BASE, L->base + | str PC, SAVE_PC + | str L, SBUF:CARG1->L + | str CARG4, SBUF:CARG1->p + | bl extern lj_buf_putstr_ .. name + | bl extern lj_buf_tostr + | b ->fff_resstr |.endmacro | - |ffstring_case string_lower, 65 - |ffstring_case string_upper, 97 + |ffstring_op reverse + |ffstring_op lower + |ffstring_op upper | |//-- Bit library -------------------------------------------------------- | diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc index c4f01e81..fa53a554 100644 --- a/src/vm_mips.dasc +++ b/src/vm_mips.dasc @@ -138,6 +138,7 @@ |.type NODE, Node |.type NARGS8, int |.type TRACE, GCtrace +|.type SBUF, SBuf | |//----------------------------------------------------------------------- | @@ -1668,6 +1669,7 @@ static void build_subroutines(BuildCtx *ctx) |. move CARG1, L | // Returns GCstr *. | lw BASE, L->base + |->fff_resstr: | move CARG1, CRET1 | b ->fff_restv |. li CARG3, LJ_TSTR @@ -1756,63 +1758,32 @@ static void build_subroutines(BuildCtx *ctx) | b ->fff_newstr |. nop | - |.ffunc string_reverse + |.macro ffstring_op, name + | .ffunc string_ .. name | ffgccheck | lw CARG3, HI(BASE) - | lw STR:CARG1, LO(BASE) + | lw STR:CARG2, LO(BASE) | beqz NARGS8:RC, ->fff_fallback |. li AT, LJ_TSTR | bne CARG3, AT, ->fff_fallback - |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) - | lw CARG3, STR:CARG1->len - | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) - | addiu CARG1, STR:CARG1, #STR - | addu CARG4, CARG2, CARG3 - | sltu AT, TMP1, CARG4 - | bnez AT, ->fff_fallback - |. addu TMP3, CARG1, CARG3 - |1: // Reverse string copy. - | lbu TMP1, 0(CARG1) - | sltu AT, CARG1, TMP3 - | beqz AT, ->fff_newstr - |. addiu CARG1, CARG1, 1 - | addiu CARG4, CARG4, -1 - | b <1 - | sb TMP1, 0(CARG4) - | - |.macro ffstring_case, name, lo - | .ffunc name - | ffgccheck - | lw CARG3, HI(BASE) - | lw STR:CARG1, LO(BASE) - | beqz NARGS8:RC, ->fff_fallback - |. li AT, LJ_TSTR - | bne CARG3, AT, ->fff_fallback - |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) - | lw CARG3, STR:CARG1->len - | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) - | addiu CARG1, STR:CARG1, #STR - | addu TMP3, CARG2, CARG3 - | sltu AT, TMP1, TMP3 - | bnez AT, ->fff_fallback - |. addu TMP3, CARG1, CARG3 - | move CARG4, CARG2 - |1: // ASCII case conversion. - | lbu TMP1, 0(CARG1) - | sltu AT, CARG1, TMP3 - | beqz AT, ->fff_newstr - |. addiu TMP0, TMP1, -lo - | xori TMP2, TMP1, 0x20 - | sltiu AT, TMP0, 26 - | movn TMP1, TMP2, AT - | addiu CARG1, CARG1, 1 - | sb TMP1, 0(CARG4) - | b <1 - |. addiu CARG4, CARG4, 1 + |. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf) + | load_got lj_buf_putstr_ .. name + | lw TMP0, SBUF:CARG1->b + | sw L, SBUF:CARG1->L + | sw BASE, L->base + | sw TMP0, SBUF:CARG1->p + | call_intern extern lj_buf_putstr_ .. name + |. sw PC, SAVE_PC + | load_got lj_buf_tostr + | call_intern lj_buf_tostr + |. move SBUF:CARG1, SBUF:CRET1 + | b ->fff_resstr + |. lw BASE, L->base |.endmacro | - |ffstring_case string_lower, 65 - |ffstring_case string_upper, 97 + |ffstring_op reverse + |ffstring_op lower + |ffstring_op upper | |//-- Bit library -------------------------------------------------------- | diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index c85f1f10..ac399900 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc @@ -293,6 +293,7 @@ |.type NODE, Node |.type NARGS8, int |.type TRACE, GCtrace +|.type SBUF, SBuf | |//----------------------------------------------------------------------- | @@ -2103,6 +2104,7 @@ static void build_subroutines(BuildCtx *ctx) | stp BASE, L->base | stw PC, SAVE_PC | bl extern lj_str_new // (lua_State *L, char *str, size_t l) + |->fff_resstr: | // Returns GCstr *. | lp BASE, L->base | li CARG3, LJ_TSTR @@ -2223,66 +2225,29 @@ static void build_subroutines(BuildCtx *ctx) | li CARG3, LJ_TSTR | b ->fff_restv | - |.ffunc string_reverse + |.macro ffstring_op, name + | .ffunc string_ .. name | ffgccheck | cmplwi NARGS8:RC, 8 | lwz CARG3, 0(BASE) - | lwz STR:CARG1, 4(BASE) + | lwz STR:CARG2, 4(BASE) | blt ->fff_fallback | checkstr CARG3 - | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) - | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) + | la SBUF:CARG1, DISPATCH_GL(tmpbuf)(DISPATCH) | bne ->fff_fallback - | lwz CARG3, STR:CARG1->len - | la CARG1, #STR(STR:CARG1) - | li TMP2, 0 - | add TMP3, CARG2, CARG3 - | cmplw TMP1, TMP3 - | subi TMP3, CARG3, 1 - | blt ->fff_fallback - |1: // Reverse string copy. - | cmpwi TMP3, 0 - | lbzx TMP1, CARG1, TMP2 - | blty ->fff_newstr - | stbx TMP1, CARG2, TMP3 - | subi TMP3, TMP3, 1 - | addi TMP2, TMP2, 1 - | b <1 - | - |.macro ffstring_case, name, lo - | .ffunc name - | ffgccheck - | cmplwi NARGS8:RC, 8 - | lwz CARG3, 0(BASE) - | lwz STR:CARG1, 4(BASE) - | blt ->fff_fallback - | checkstr CARG3 - | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) - | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) - | bne ->fff_fallback - | lwz CARG3, STR:CARG1->len - | la CARG1, #STR(STR:CARG1) - | li TMP2, 0 - | add TMP3, CARG2, CARG3 - | cmplw TMP1, TMP3 - | blt ->fff_fallback - |1: // ASCII case conversion. - | cmplw TMP2, CARG3 - | lbzx TMP1, CARG1, TMP2 - | bgey ->fff_newstr - | subi TMP0, TMP1, lo - | xori TMP3, TMP1, 0x20 - | addic TMP0, TMP0, -26 - | subfe TMP3, TMP3, TMP3 - | rlwinm TMP3, TMP3, 0, 26, 26 // x &= 0x20. - | xor TMP1, TMP1, TMP3 - | stbx TMP1, CARG2, TMP2 - | addi TMP2, TMP2, 1 - | b <1 + | lwz TMP0, SBUF:CARG1->b + | stw L, SBUF:CARG1->L + | stp BASE, L->base + | stw PC, SAVE_PC + | stw TMP0, SBUF:CARG1->p + | bl extern lj_buf_putstr_ .. name + | bl extern lj_buf_tostr + | b ->fff_resstr |.endmacro | - |ffstring_case string_lower, 65 - |ffstring_case string_upper, 97 + |ffstring_op reverse + |ffstring_op lower + |ffstring_op upper | |//-- Bit library -------------------------------------------------------- | diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index 8ed55fd2..8bbeaa2b 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc @@ -115,6 +115,7 @@ |.type NODE, Node |.type NARGS, int |.type TRACE, GCtrace +|.type SBUF, SBuf | |// Stack layout while in interpreter. Must match with lj_frame.h. |//----------------------------------------------------------------------- @@ -2258,6 +2259,7 @@ static void build_subroutines(BuildCtx *ctx) |.endif | mov SAVE_PC, PC | call extern lj_str_new // (lua_State *L, char *str, size_t l) + |->fff_resstr: | // GCstr * returned in eax (RD). | mov BASE, L:RB->base | mov PC, [BASE-4] @@ -2373,69 +2375,27 @@ static void build_subroutines(BuildCtx *ctx) | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)] | jmp ->fff_newstr | - |.ffunc_1 string_reverse + |.macro ffstring_op, name + | .ffunc_1 string_ .. name | ffgccheck | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback - | mov STR:RB, [BASE] - | mov RC, STR:RB->len - | test RC, RC - | jz ->fff_emptystr // Zero length string? - | mov TMP2, PC // Need another temp register. - | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)] - | lea RA, [PC+RC] - | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1 - | add RB, #STR - |.if X64 - | mov TMP3, RC - |.else - | mov ARG3, RC - |.endif - |1: - | movzx RA, byte [RB] - | add RB, 1 - | sub RC, 1 - | mov [PC+RC], RAL - | jnz <1 - | mov RD, PC - | mov PC, TMP2 - | jmp ->fff_newstr - | - |.macro ffstring_case, name, lo, hi - | .ffunc_1 name - | ffgccheck - | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback - | mov TMP2, PC // Need another temp register. - | mov STR:RB, [BASE] - | mov RC, STR:RB->len - | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)] - | lea RA, [PC+RC] - | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1 - | add RB, #STR - |.if X64 - | mov TMP3, RC - |.else - | mov ARG3, RC - |.endif - | jmp >3 - |1: // ASCII case conversion. Yes, this is suboptimal code (do you care?). - | movzx RA, byte [RB+RC] - | cmp RA, lo - | jb >2 - | cmp RA, hi - | ja >2 - | xor RA, 0x20 - |2: - | mov [PC+RC], RAL - |3: - | sub RC, 1 - | jns <1 - | mov RD, PC - | mov PC, TMP2 - | jmp ->fff_newstr + | mov L:RB, SAVE_L + | lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)] + | mov L:RB->base, BASE + | mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE + | mov RC, SBUF:FCARG1->b + | mov SBUF:FCARG1->L, L:RB + | mov SBUF:FCARG1->p, RC + | mov SAVE_PC, PC + | call extern lj_buf_putstr_ .. name + | mov FCARG1, eax + | call extern lj_buf_tostr + | jmp ->fff_resstr |.endmacro | - |ffstring_case string_lower, 0x41, 0x5a - |ffstring_case string_upper, 0x61, 0x7a + |ffstring_op reverse + |ffstring_op lower + |ffstring_op upper | |//-- Bit library -------------------------------------------------------- |