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 \
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)
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);
}
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)
{
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);
#include "lj_obj.h"
#include "lj_err.h"
+#include "lj_buf.h"
#include "lj_func.h"
#include "lj_str.h"
#include "lj_tab.h"
_(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,
|.type NODE, Node
|.type NARGS8, int
|.type TRACE, GCtrace
+|.type SBUF, SBuf
|
|//-----------------------------------------------------------------------
|
| 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
| bge <1
| b ->fff_newstr
|
- |.ffunc string_reverse
+ |.macro ffstring_op, name
+ | .ffunc string_ .. 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, 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]
+ | 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, #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 --------------------------------------------------------
|
|.type NODE, Node
|.type NARGS8, int
|.type TRACE, GCtrace
+|.type SBUF, SBuf
|
|//-----------------------------------------------------------------------
|
|. move CARG1, L
| // Returns GCstr *.
| lw BASE, L->base
+ |->fff_resstr:
| move CARG1, CRET1
| b ->fff_restv
|. li CARG3, LJ_TSTR
| 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 --------------------------------------------------------
|
|.type NODE, Node
|.type NARGS8, int
|.type TRACE, GCtrace
+|.type SBUF, SBuf
|
|//-----------------------------------------------------------------------
|
| 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
| 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 --------------------------------------------------------
|
|.type NODE, Node
|.type NARGS, int
|.type TRACE, GCtrace
+|.type SBUF, SBuf
|
|// Stack layout while in interpreter. Must match with lj_frame.h.
|//-----------------------------------------------------------------------
|.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]
| 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 --------------------------------------------------------
|