mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
String buffer refactoring, part 2.
Switch to pointers for start/pos/end of buffer. Abstract out some buffer writers.
This commit is contained in:
parent
28cfcf7744
commit
116cdd7e9a
@ -17,8 +17,8 @@ lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
|||||||
lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
|
lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
|
||||||
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
|
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
|
||||||
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||||
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_state.h lj_ff.h \
|
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_state.h \
|
||||||
lj_ffdef.h lj_lib.h lj_libdef.h
|
lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
|
||||||
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
|
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
|
||||||
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
|
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
|
||||||
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
|
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
|
||||||
@ -31,8 +31,8 @@ lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
|||||||
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||||
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
|
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
|
||||||
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
|
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
|
||||||
lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h lj_buf.h \
|
lj_tab.h lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h \
|
||||||
lj_char.h lj_lib.h lj_libdef.h
|
lj_char.h lj_lib.h lj_libdef.h
|
||||||
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
|
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
|
||||||
@ -56,7 +56,7 @@ lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||||||
lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
|
lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
|
||||||
lj_ir.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
|
lj_ir.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
|
||||||
lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||||
lj_err.h lj_errmsg.h lj_buf.h
|
lj_err.h lj_errmsg.h lj_buf.h lj_str.h
|
||||||
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
|
||||||
lj_cdata.h lj_carith.h
|
lj_cdata.h lj_carith.h
|
||||||
@ -91,8 +91,8 @@ lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||||||
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
|
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
|
||||||
lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
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_str.h lj_tab.h lj_state.h lj_frame.h \
|
lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
|
||||||
lj_bc.h lj_jit.h lj_ir.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_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_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_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \
|
||||||
@ -115,19 +115,19 @@ lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
|||||||
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
|
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
|
||||||
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
|
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
|
||||||
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
|
||||||
lj_ir.h lj_dispatch.h
|
lj_str.h lj_jit.h lj_ir.h lj_dispatch.h
|
||||||
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||||
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
|
lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
|
||||||
lj_vm.h lj_strscan.h lj_lib.h
|
lj_vm.h lj_strscan.h lj_lib.h
|
||||||
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
|
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
|
||||||
lj_state.h lj_lex.h lj_buf.h lj_parse.h lj_char.h lj_strscan.h
|
lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
|
||||||
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
|
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
|
||||||
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_buf.h \
|
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_bcdump.h \
|
||||||
lj_bcdump.h lj_lib.h
|
lj_lib.h
|
||||||
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
||||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \
|
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \
|
||||||
lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
||||||
@ -145,8 +145,9 @@ lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||||||
lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \
|
lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \
|
||||||
lj_strscan.h lj_folddef.h
|
lj_strscan.h lj_folddef.h
|
||||||
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h \
|
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h lj_jit.h \
|
||||||
lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h
|
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
|
||||||
|
lj_vm.h
|
||||||
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
|
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
|
||||||
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||||
@ -155,11 +156,11 @@ lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
|||||||
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
|
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
|
||||||
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
|
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||||
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ir.h lj_jit.h \
|
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \
|
||||||
lj_ircall.h lj_iropt.h lj_vm.h
|
lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h
|
||||||
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
|
||||||
lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_buf.h lj_parse.h lj_vm.h \
|
lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h \
|
||||||
lj_vmevent.h
|
lj_vmevent.h
|
||||||
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
|
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_gc.h"
|
#include "lj_gc.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_str.h"
|
#include "lj_str.h"
|
||||||
#include "lj_tab.h"
|
#include "lj_tab.h"
|
||||||
#include "lj_meta.h"
|
#include "lj_meta.h"
|
||||||
|
@ -53,27 +53,28 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
|
|||||||
const char *buf;
|
const char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
if (ls->n) { /* Copy remainder to buffer. */
|
if (ls->n) { /* Copy remainder to buffer. */
|
||||||
if (ls->sb.n) { /* Move down in buffer. */
|
if (sbuflen(&ls->sb)) { /* Move down in buffer. */
|
||||||
lua_assert(ls->p + ls->n == ls->sb.buf + ls->sb.n);
|
lua_assert(ls->p + ls->n == sbufP(&ls->sb));
|
||||||
if (ls->n != ls->sb.n)
|
if (ls->n != sbuflen(&ls->sb))
|
||||||
memmove(ls->sb.buf, ls->p, ls->n);
|
memmove(sbufB(&ls->sb), ls->p, ls->n);
|
||||||
} else { /* Copy from buffer provided by reader. */
|
} else { /* Copy from buffer provided by reader. */
|
||||||
memcpy(lj_buf_need(ls->L, &ls->sb, len), ls->p, ls->n);
|
memcpy(lj_buf_need(ls->L, &ls->sb, len), ls->p, ls->n);
|
||||||
}
|
}
|
||||||
ls->p = ls->sb.buf;
|
ls->p = sbufB(&ls->sb);
|
||||||
}
|
}
|
||||||
ls->sb.n = ls->n;
|
setsbufP(&ls->sb, sbufB(&ls->sb) + ls->n);
|
||||||
buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */
|
buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */
|
||||||
if (buf == NULL || size == 0) { /* EOF? */
|
if (buf == NULL || size == 0) { /* EOF? */
|
||||||
if (need) bcread_error(ls, LJ_ERR_BCBAD);
|
if (need) bcread_error(ls, LJ_ERR_BCBAD);
|
||||||
ls->current = -1; /* Only bad if we get called again. */
|
ls->current = -1; /* Only bad if we get called again. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ls->sb.n) { /* Append to buffer. */
|
if (sbuflen(&ls->sb)) { /* Append to buffer. */
|
||||||
MSize n = ls->sb.n + (MSize)size;
|
MSize n = sbuflen(&ls->sb) + (MSize)size;
|
||||||
char *p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n);
|
char *p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n);
|
||||||
memcpy(p + ls->sb.n, buf, size);
|
memcpy(sbufP(&ls->sb), buf, size);
|
||||||
ls->n = ls->sb.n = n;
|
setsbufP(&ls->sb, sbufB(&ls->sb) + n);
|
||||||
|
ls->n = n;
|
||||||
ls->p = p;
|
ls->p = p;
|
||||||
} else { /* Return buffer provided by reader. */
|
} else { /* Return buffer provided by reader. */
|
||||||
ls->n = (MSize)size;
|
ls->n = (MSize)size;
|
||||||
|
202
src/lj_bcwrite.c
202
src/lj_bcwrite.c
@ -32,76 +32,44 @@ typedef struct BCWriteCtx {
|
|||||||
int status; /* Status from writer callback. */
|
int status; /* Status from writer callback. */
|
||||||
} BCWriteCtx;
|
} BCWriteCtx;
|
||||||
|
|
||||||
/* -- Output buffer handling ---------------------------------------------- */
|
|
||||||
|
|
||||||
/* Ensure a certain amount of buffer space. */
|
|
||||||
static LJ_AINLINE void bcwrite_need(BCWriteCtx *ctx, MSize len)
|
|
||||||
{
|
|
||||||
lj_buf_need(ctx->L, &ctx->sb, ctx->sb.n + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add memory block to buffer. */
|
|
||||||
static void bcwrite_block(BCWriteCtx *ctx, const void *p, MSize len)
|
|
||||||
{
|
|
||||||
uint8_t *q = (uint8_t *)(ctx->sb.buf + ctx->sb.n);
|
|
||||||
MSize i;
|
|
||||||
ctx->sb.n += len;
|
|
||||||
for (i = 0; i < len; i++) q[i] = ((uint8_t *)p)[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add byte to buffer. */
|
|
||||||
static LJ_AINLINE void bcwrite_byte(BCWriteCtx *ctx, uint8_t b)
|
|
||||||
{
|
|
||||||
ctx->sb.buf[ctx->sb.n++] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add ULEB128 value to buffer. */
|
|
||||||
static void bcwrite_uleb128(BCWriteCtx *ctx, uint32_t v)
|
|
||||||
{
|
|
||||||
MSize n = ctx->sb.n;
|
|
||||||
uint8_t *p = (uint8_t *)ctx->sb.buf;
|
|
||||||
for (; v >= 0x80; v >>= 7)
|
|
||||||
p[n++] = (uint8_t)((v & 0x7f) | 0x80);
|
|
||||||
p[n++] = (uint8_t)v;
|
|
||||||
ctx->sb.n = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Bytecode writer ----------------------------------------------------- */
|
/* -- Bytecode writer ----------------------------------------------------- */
|
||||||
|
|
||||||
/* Write a single constant key/value of a template table. */
|
/* Write a single constant key/value of a template table. */
|
||||||
static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
|
static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
|
||||||
{
|
{
|
||||||
bcwrite_need(ctx, 1+10);
|
char *p = lj_buf_more(ctx->L, &ctx->sb, 1+10);
|
||||||
if (tvisstr(o)) {
|
if (tvisstr(o)) {
|
||||||
const GCstr *str = strV(o);
|
const GCstr *str = strV(o);
|
||||||
MSize len = str->len;
|
MSize len = str->len;
|
||||||
bcwrite_need(ctx, 5+len);
|
p = lj_buf_more(ctx->L, &ctx->sb, 5+len);
|
||||||
bcwrite_uleb128(ctx, BCDUMP_KTAB_STR+len);
|
p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len);
|
||||||
bcwrite_block(ctx, strdata(str), len);
|
p = lj_buf_wmem(p, strdata(str), len);
|
||||||
} else if (tvisint(o)) {
|
} else if (tvisint(o)) {
|
||||||
bcwrite_byte(ctx, BCDUMP_KTAB_INT);
|
*p++ = BCDUMP_KTAB_INT;
|
||||||
bcwrite_uleb128(ctx, intV(o));
|
p = lj_buf_wuleb128(p, intV(o));
|
||||||
} else if (tvisnum(o)) {
|
} else if (tvisnum(o)) {
|
||||||
if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */
|
if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */
|
||||||
lua_Number num = numV(o);
|
lua_Number num = numV(o);
|
||||||
int32_t k = lj_num2int(num);
|
int32_t k = lj_num2int(num);
|
||||||
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
||||||
bcwrite_byte(ctx, BCDUMP_KTAB_INT);
|
*p++ = BCDUMP_KTAB_INT;
|
||||||
bcwrite_uleb128(ctx, k);
|
p = lj_buf_wuleb128(p, k);
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcwrite_byte(ctx, BCDUMP_KTAB_NUM);
|
*p++ = BCDUMP_KTAB_NUM;
|
||||||
bcwrite_uleb128(ctx, o->u32.lo);
|
p = lj_buf_wuleb128(p, o->u32.lo);
|
||||||
bcwrite_uleb128(ctx, o->u32.hi);
|
p = lj_buf_wuleb128(p, o->u32.hi);
|
||||||
} else {
|
} else {
|
||||||
lua_assert(tvispri(o));
|
lua_assert(tvispri(o));
|
||||||
bcwrite_byte(ctx, BCDUMP_KTAB_NIL+~itype(o));
|
*p++ = BCDUMP_KTAB_NIL+~itype(o);
|
||||||
}
|
}
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a template table. */
|
/* Write a template table. */
|
||||||
static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t)
|
static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
|
||||||
{
|
{
|
||||||
MSize narray = 0, nhash = 0;
|
MSize narray = 0, nhash = 0;
|
||||||
if (t->asize > 0) { /* Determine max. length of array part. */
|
if (t->asize > 0) { /* Determine max. length of array part. */
|
||||||
@ -119,8 +87,9 @@ static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t)
|
|||||||
nhash += !tvisnil(&node[i].val);
|
nhash += !tvisnil(&node[i].val);
|
||||||
}
|
}
|
||||||
/* Write number of array slots and hash slots. */
|
/* Write number of array slots and hash slots. */
|
||||||
bcwrite_uleb128(ctx, narray);
|
p = lj_buf_wuleb128(p, narray);
|
||||||
bcwrite_uleb128(ctx, nhash);
|
p = lj_buf_wuleb128(p, nhash);
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
if (narray) { /* Write array entries (may contain nil). */
|
if (narray) { /* Write array entries (may contain nil). */
|
||||||
MSize i;
|
MSize i;
|
||||||
TValue *o = tvref(t->array);
|
TValue *o = tvref(t->array);
|
||||||
@ -147,6 +116,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
for (i = 0; i < sizekgc; i++, kr++) {
|
for (i = 0; i < sizekgc; i++, kr++) {
|
||||||
GCobj *o = gcref(*kr);
|
GCobj *o = gcref(*kr);
|
||||||
MSize tp, need = 1;
|
MSize tp, need = 1;
|
||||||
|
char *p;
|
||||||
/* Determine constant type and needed size. */
|
/* Determine constant type and needed size. */
|
||||||
if (o->gch.gct == ~LJ_TSTR) {
|
if (o->gch.gct == ~LJ_TSTR) {
|
||||||
tp = BCDUMP_KGC_STR + gco2str(o)->len;
|
tp = BCDUMP_KGC_STR + gco2str(o)->len;
|
||||||
@ -173,24 +143,26 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
need = 1+2*5;
|
need = 1+2*5;
|
||||||
}
|
}
|
||||||
/* Write constant type. */
|
/* Write constant type. */
|
||||||
bcwrite_need(ctx, need);
|
p = lj_buf_more(ctx->L, &ctx->sb, need);
|
||||||
bcwrite_uleb128(ctx, tp);
|
p = lj_buf_wuleb128(p, tp);
|
||||||
/* Write constant data (if any). */
|
/* Write constant data (if any). */
|
||||||
if (tp >= BCDUMP_KGC_STR) {
|
if (tp >= BCDUMP_KGC_STR) {
|
||||||
bcwrite_block(ctx, strdata(gco2str(o)), gco2str(o)->len);
|
p = lj_buf_wmem(p, strdata(gco2str(o)), gco2str(o)->len);
|
||||||
} else if (tp == BCDUMP_KGC_TAB) {
|
} else if (tp == BCDUMP_KGC_TAB) {
|
||||||
bcwrite_ktab(ctx, gco2tab(o));
|
bcwrite_ktab(ctx, p, gco2tab(o));
|
||||||
|
continue;
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
} else if (tp != BCDUMP_KGC_CHILD) {
|
} else if (tp != BCDUMP_KGC_CHILD) {
|
||||||
cTValue *p = (TValue *)cdataptr(gco2cd(o));
|
cTValue *q = (TValue *)cdataptr(gco2cd(o));
|
||||||
bcwrite_uleb128(ctx, p[0].u32.lo);
|
p = lj_buf_wuleb128(p, q[0].u32.lo);
|
||||||
bcwrite_uleb128(ctx, p[0].u32.hi);
|
p = lj_buf_wuleb128(p, q[0].u32.hi);
|
||||||
if (tp == BCDUMP_KGC_COMPLEX) {
|
if (tp == BCDUMP_KGC_COMPLEX) {
|
||||||
bcwrite_uleb128(ctx, p[1].u32.lo);
|
p = lj_buf_wuleb128(p, q[1].u32.lo);
|
||||||
bcwrite_uleb128(ctx, p[1].u32.hi);
|
p = lj_buf_wuleb128(p, q[1].u32.hi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +171,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
{
|
{
|
||||||
MSize i, sizekn = pt->sizekn;
|
MSize i, sizekn = pt->sizekn;
|
||||||
cTValue *o = mref(pt->k, TValue);
|
cTValue *o = mref(pt->k, TValue);
|
||||||
bcwrite_need(ctx, 10*sizekn);
|
char *p = lj_buf_more(ctx->L, &ctx->sb, 10*sizekn);
|
||||||
for (i = 0; i < sizekn; i++, o++) {
|
for (i = 0; i < sizekn; i++, o++) {
|
||||||
int32_t k;
|
int32_t k;
|
||||||
if (tvisint(o)) {
|
if (tvisint(o)) {
|
||||||
@ -212,58 +184,58 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
k = lj_num2int(num);
|
k = lj_num2int(num);
|
||||||
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
if (num == (lua_Number)k) { /* -0 is never a constant. */
|
||||||
save_int:
|
save_int:
|
||||||
bcwrite_uleb128(ctx, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u));
|
p = lj_buf_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u));
|
||||||
if (k < 0) {
|
if (k < 0)
|
||||||
char *p = &ctx->sb.buf[ctx->sb.n-1];
|
p[-1] = (p[-1] & 7) | ((k>>27) & 0x18);
|
||||||
*p = (*p & 7) | ((k>>27) & 0x18);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcwrite_uleb128(ctx, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
|
p = lj_buf_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
|
||||||
if (o->u32.lo >= 0x80000000u) {
|
if (o->u32.lo >= 0x80000000u)
|
||||||
char *p = &ctx->sb.buf[ctx->sb.n-1];
|
p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18);
|
||||||
*p = (*p & 7) | ((o->u32.lo>>27) & 0x18);
|
p = lj_buf_wuleb128(p, o->u32.hi);
|
||||||
}
|
|
||||||
bcwrite_uleb128(ctx, o->u32.hi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write bytecode instructions. */
|
/* Write bytecode instructions. */
|
||||||
static void bcwrite_bytecode(BCWriteCtx *ctx, GCproto *pt)
|
static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt)
|
||||||
{
|
{
|
||||||
MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */
|
MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
uint8_t *p = (uint8_t *)&ctx->sb.buf[ctx->sb.n];
|
uint8_t *q = (uint8_t *)p;
|
||||||
#endif
|
#endif
|
||||||
bcwrite_block(ctx, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns));
|
p = lj_buf_wmem(p, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns));
|
||||||
|
UNUSED(ctx);
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
/* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
|
/* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
|
||||||
if ((pt->flags & PROTO_ILOOP) || pt->trace) {
|
if ((pt->flags & PROTO_ILOOP) || pt->trace) {
|
||||||
jit_State *J = L2J(ctx->L);
|
jit_State *J = L2J(ctx->L);
|
||||||
MSize i;
|
MSize i;
|
||||||
for (i = 0; i < nbc; i++, p += sizeof(BCIns)) {
|
for (i = 0; i < nbc; i++, q += sizeof(BCIns)) {
|
||||||
BCOp op = (BCOp)p[LJ_ENDIAN_SELECT(0, 3)];
|
BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)];
|
||||||
if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP ||
|
if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP ||
|
||||||
op == BC_JFORI) {
|
op == BC_JFORI) {
|
||||||
p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL);
|
q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL);
|
||||||
} else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) {
|
} else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) {
|
||||||
BCReg rd = p[LJ_ENDIAN_SELECT(2, 1)] + (p[LJ_ENDIAN_SELECT(3, 0)] << 8);
|
BCReg rd = q[LJ_ENDIAN_SELECT(2, 1)] + (q[LJ_ENDIAN_SELECT(3, 0)] << 8);
|
||||||
BCIns ins = traceref(J, rd)->startins;
|
BCIns ins = traceref(J, rd)->startins;
|
||||||
p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL);
|
q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL);
|
||||||
p[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins);
|
q[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins);
|
||||||
p[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins);
|
q[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write prototype. */
|
/* Write prototype. */
|
||||||
static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
|
static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
|
||||||
{
|
{
|
||||||
MSize sizedbg = 0;
|
MSize sizedbg = 0;
|
||||||
|
char *p;
|
||||||
|
|
||||||
/* Recursively write children of prototype. */
|
/* Recursively write children of prototype. */
|
||||||
if ((pt->flags & PROTO_CHILD)) {
|
if ((pt->flags & PROTO_CHILD)) {
|
||||||
@ -277,31 +249,32 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Start writing the prototype info to a buffer. */
|
/* Start writing the prototype info to a buffer. */
|
||||||
lj_buf_reset(&ctx->sb);
|
p = lj_buf_need(ctx->L, &ctx->sb,
|
||||||
ctx->sb.n = 5; /* Leave room for final size. */
|
5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
|
||||||
bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
|
p += 5; /* Leave room for final size. */
|
||||||
|
|
||||||
/* Write prototype header. */
|
/* Write prototype header. */
|
||||||
bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)));
|
*p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI));
|
||||||
bcwrite_byte(ctx, pt->numparams);
|
*p++ = pt->numparams;
|
||||||
bcwrite_byte(ctx, pt->framesize);
|
*p++ = pt->framesize;
|
||||||
bcwrite_byte(ctx, pt->sizeuv);
|
*p++ = pt->sizeuv;
|
||||||
bcwrite_uleb128(ctx, pt->sizekgc);
|
p = lj_buf_wuleb128(p, pt->sizekgc);
|
||||||
bcwrite_uleb128(ctx, pt->sizekn);
|
p = lj_buf_wuleb128(p, pt->sizekn);
|
||||||
bcwrite_uleb128(ctx, pt->sizebc-1);
|
p = lj_buf_wuleb128(p, pt->sizebc-1);
|
||||||
if (!ctx->strip) {
|
if (!ctx->strip) {
|
||||||
if (proto_lineinfo(pt))
|
if (proto_lineinfo(pt))
|
||||||
sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
|
sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
|
||||||
bcwrite_uleb128(ctx, sizedbg);
|
p = lj_buf_wuleb128(p, sizedbg);
|
||||||
if (sizedbg) {
|
if (sizedbg) {
|
||||||
bcwrite_uleb128(ctx, pt->firstline);
|
p = lj_buf_wuleb128(p, pt->firstline);
|
||||||
bcwrite_uleb128(ctx, pt->numline);
|
p = lj_buf_wuleb128(p, pt->numline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write bytecode instructions and upvalue refs. */
|
/* Write bytecode instructions and upvalue refs. */
|
||||||
bcwrite_bytecode(ctx, pt);
|
p = bcwrite_bytecode(ctx, p, pt);
|
||||||
bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2);
|
p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2);
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
|
|
||||||
/* Write constants. */
|
/* Write constants. */
|
||||||
bcwrite_kgc(ctx, pt);
|
bcwrite_kgc(ctx, pt);
|
||||||
@ -309,18 +282,19 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
|
|||||||
|
|
||||||
/* Write debug info, if not stripped. */
|
/* Write debug info, if not stripped. */
|
||||||
if (sizedbg) {
|
if (sizedbg) {
|
||||||
bcwrite_need(ctx, sizedbg);
|
p = lj_buf_more(ctx->L, &ctx->sb, sizedbg);
|
||||||
bcwrite_block(ctx, proto_lineinfo(pt), sizedbg);
|
p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
|
||||||
|
setsbufP(&ctx->sb, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass buffer to writer function. */
|
/* Pass buffer to writer function. */
|
||||||
if (ctx->status == 0) {
|
if (ctx->status == 0) {
|
||||||
MSize n = ctx->sb.n - 5;
|
MSize n = sbuflen(&ctx->sb) - 5;
|
||||||
MSize nn = (lj_fls(n)+8)*9 >> 6;
|
MSize nn = (lj_fls(n)+8)*9 >> 6;
|
||||||
ctx->sb.n = 5 - nn;
|
char *q = sbufB(&ctx->sb) + (5 - nn);
|
||||||
bcwrite_uleb128(ctx, n); /* Fill in final size. */
|
p = lj_buf_wuleb128(q, n); /* Fill in final size. */
|
||||||
lua_assert(ctx->sb.n == 5);
|
lua_assert(p == sbufB(&ctx->sb) + 5);
|
||||||
ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata);
|
ctx->status = ctx->wfunc(ctx->L, q, nn+n, ctx->wdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,20 +304,20 @@ static void bcwrite_header(BCWriteCtx *ctx)
|
|||||||
GCstr *chunkname = proto_chunkname(ctx->pt);
|
GCstr *chunkname = proto_chunkname(ctx->pt);
|
||||||
const char *name = strdata(chunkname);
|
const char *name = strdata(chunkname);
|
||||||
MSize len = chunkname->len;
|
MSize len = chunkname->len;
|
||||||
lj_buf_reset(&ctx->sb);
|
char *p = lj_buf_need(ctx->L, &ctx->sb, 5+5+len);
|
||||||
bcwrite_need(ctx, 5+5+len);
|
*p++ = BCDUMP_HEAD1;
|
||||||
bcwrite_byte(ctx, BCDUMP_HEAD1);
|
*p++ = BCDUMP_HEAD2;
|
||||||
bcwrite_byte(ctx, BCDUMP_HEAD2);
|
*p++ = BCDUMP_HEAD3;
|
||||||
bcwrite_byte(ctx, BCDUMP_HEAD3);
|
*p++ = BCDUMP_VERSION;
|
||||||
bcwrite_byte(ctx, BCDUMP_VERSION);
|
*p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) +
|
||||||
bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) +
|
|
||||||
(LJ_BE ? BCDUMP_F_BE : 0) +
|
(LJ_BE ? BCDUMP_F_BE : 0) +
|
||||||
((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0));
|
((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0);
|
||||||
if (!ctx->strip) {
|
if (!ctx->strip) {
|
||||||
bcwrite_uleb128(ctx, len);
|
p = lj_buf_wuleb128(p, len);
|
||||||
bcwrite_block(ctx, name, len);
|
p = lj_buf_wmem(p, name, len);
|
||||||
}
|
}
|
||||||
ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata);
|
ctx->status = ctx->wfunc(ctx->L, sbufB(&ctx->sb),
|
||||||
|
(MSize)(p - sbufB(&ctx->sb)), ctx->wdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write footer of bytecode dump. */
|
/* Write footer of bytecode dump. */
|
||||||
@ -360,7 +334,7 @@ static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
|
|||||||
{
|
{
|
||||||
BCWriteCtx *ctx = (BCWriteCtx *)ud;
|
BCWriteCtx *ctx = (BCWriteCtx *)ud;
|
||||||
UNUSED(dummy);
|
UNUSED(dummy);
|
||||||
lj_buf_grow(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */
|
lj_buf_need(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */
|
||||||
bcwrite_header(ctx);
|
bcwrite_header(ctx);
|
||||||
bcwrite_proto(ctx, ctx->pt);
|
bcwrite_proto(ctx, ctx->pt);
|
||||||
bcwrite_footer(ctx);
|
bcwrite_footer(ctx);
|
||||||
|
64
src/lj_buf.c
64
src/lj_buf.c
@ -13,15 +13,20 @@
|
|||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_buf.h"
|
#include "lj_buf.h"
|
||||||
|
|
||||||
LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, MSize sz)
|
LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, char *en)
|
||||||
{
|
{
|
||||||
MSize bsz = sb->sz * 2;
|
char *b = sbufB(sb);
|
||||||
|
MSize sz = (MSize)(en - b);
|
||||||
|
MSize osz = (MSize)(sbufE(sb) - b), nsz = osz;
|
||||||
|
MSize n = (MSize)(sbufP(sb) - b);
|
||||||
if (LJ_UNLIKELY(sz > LJ_MAX_MEM))
|
if (LJ_UNLIKELY(sz > LJ_MAX_MEM))
|
||||||
lj_err_mem(L);
|
lj_err_mem(L);
|
||||||
if (bsz < LJ_MIN_SBUF) bsz = LJ_MIN_SBUF;
|
if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
|
||||||
while (bsz < sz) bsz += bsz;
|
while (nsz < sz) nsz += nsz;
|
||||||
sb->buf = lj_mem_realloc(L, sb->buf, sb->sz, bsz);
|
b = (char *)lj_mem_realloc(L, b, osz, nsz);
|
||||||
sb->sz = bsz;
|
setmref(sb->b, b);
|
||||||
|
setmref(sb->p, b + n);
|
||||||
|
setmref(sb->e, b + nsz);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *lj_buf_tmp(lua_State *L, MSize sz)
|
char *lj_buf_tmp(lua_State *L, MSize sz)
|
||||||
@ -31,10 +36,49 @@ char *lj_buf_tmp(lua_State *L, MSize sz)
|
|||||||
|
|
||||||
void lj_buf_shrink(lua_State *L, SBuf *sb)
|
void lj_buf_shrink(lua_State *L, SBuf *sb)
|
||||||
{
|
{
|
||||||
MSize sz = sb->sz;
|
char *b = sbufB(sb);
|
||||||
if (sz > 2*LJ_MIN_SBUF) {
|
MSize osz = (MSize)(sbufE(sb) - b);
|
||||||
sb->buf = lj_mem_realloc(L, sb->buf, sz, (sz >> 1));
|
if (osz > 2*LJ_MIN_SBUF) {
|
||||||
sb->sz = (sz >> 1);
|
MSize n = (MSize)(sbufP(sb) - b);
|
||||||
|
b = lj_mem_realloc(L, b, osz, (osz >> 1));
|
||||||
|
setmref(sb->b, b);
|
||||||
|
setmref(sb->p, b + n);
|
||||||
|
setmref(sb->e, b + (osz >> 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *lj_buf_wmem(char *p, const void *q, MSize len)
|
||||||
|
{
|
||||||
|
const char *s = (const char *)q, *e = s + len;
|
||||||
|
while (s < e) *p++ = *s++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len)
|
||||||
|
{
|
||||||
|
char *p = lj_buf_more(L, sb, len);
|
||||||
|
p = lj_buf_wmem(p, q, len);
|
||||||
|
setsbufP(sb, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lj_buf_ruleb128(const char **pp)
|
||||||
|
{
|
||||||
|
const uint8_t *p = (const uint8_t *)*pp;
|
||||||
|
uint32_t v = *p++;
|
||||||
|
if (LJ_UNLIKELY(v >= 0x80)) {
|
||||||
|
int sh = 0;
|
||||||
|
v &= 0x7f;
|
||||||
|
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
|
||||||
|
}
|
||||||
|
*pp = (const char *)p;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *lj_buf_wuleb128(char *p, uint32_t v)
|
||||||
|
{
|
||||||
|
for (; v >= 0x80; v >>= 7)
|
||||||
|
*p++ = (char)((v & 0x7f) | 0x80);
|
||||||
|
*p++ = (char)v;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
60
src/lj_buf.h
60
src/lj_buf.h
@ -7,21 +7,67 @@
|
|||||||
#define _LJ_BUF_H
|
#define _LJ_BUF_H
|
||||||
|
|
||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
|
#include "lj_gc.h"
|
||||||
|
#include "lj_str.h"
|
||||||
|
|
||||||
/* Resizable string buffers. Struct definition in lj_obj.h. */
|
/* Resizable string buffers. Struct definition in lj_obj.h. */
|
||||||
|
#define sbufB(sb) (mref((sb)->b, char))
|
||||||
|
#define sbufP(sb) (mref((sb)->p, char))
|
||||||
|
#define sbufE(sb) (mref((sb)->e, char))
|
||||||
|
#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb))))
|
||||||
|
#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
|
||||||
|
#define setsbufP(sb, q) (setmref((sb)->p, (q)))
|
||||||
|
|
||||||
LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz);
|
LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz);
|
||||||
LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, MSize sz);
|
LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, char *en);
|
||||||
LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb);
|
LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb);
|
||||||
|
|
||||||
#define lj_buf_init(sb) ((sb)->buf = NULL, (sb)->sz = 0)
|
LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len);
|
||||||
#define lj_buf_reset(sb) ((sb)->n = 0)
|
LJ_FUNC void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len);
|
||||||
#define lj_buf_free(g, sb) lj_mem_free(g, (void *)(sb)->buf, (sb)->sz)
|
LJ_FUNC uint32_t lj_buf_ruleb128(const char **pp);
|
||||||
|
LJ_FUNC char *lj_buf_wuleb128(char *p, uint32_t v);
|
||||||
|
|
||||||
|
static LJ_AINLINE void lj_buf_init(SBuf *sb)
|
||||||
|
{
|
||||||
|
setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LJ_AINLINE void lj_buf_reset(SBuf *sb)
|
||||||
|
{
|
||||||
|
setmrefr(sb->p, sb->b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
|
||||||
|
{
|
||||||
|
lj_mem_free(g, sbufB(sb), sbufsz(sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
|
||||||
|
{
|
||||||
|
return lj_str_new(L, sbufB(sb), sbuflen(sb));
|
||||||
|
}
|
||||||
|
|
||||||
static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz)
|
static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz)
|
||||||
{
|
{
|
||||||
if (LJ_UNLIKELY(sz > sb->sz))
|
char *en = sbufB(sb) + sz;
|
||||||
lj_buf_grow(L, sb, sz);
|
if (LJ_UNLIKELY(en > sbufE(sb)))
|
||||||
return sb->buf;
|
lj_buf_grow(L, sb, en);
|
||||||
|
return sbufB(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LJ_AINLINE char *lj_buf_more(lua_State *L, SBuf *sb, MSize sz)
|
||||||
|
{
|
||||||
|
char *en = sbufP(sb) + sz;
|
||||||
|
if (LJ_UNLIKELY(en > sbufE(sb)))
|
||||||
|
lj_buf_grow(L, sb, en);
|
||||||
|
return sbufP(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LJ_AINLINE void lj_buf_putb(lua_State *L, SBuf *sb, int c)
|
||||||
|
{
|
||||||
|
char *p = lj_buf_more(L, sb, 1);
|
||||||
|
*p++ = (char)c;
|
||||||
|
setsbufP(sb, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,22 +86,10 @@ static LJ_AINLINE CPChar cp_get(CPState *cp)
|
|||||||
return cp_get_bs(cp);
|
return cp_get_bs(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grow save buffer. */
|
|
||||||
static LJ_NOINLINE void cp_save_grow(CPState *cp, CPChar c)
|
|
||||||
{
|
|
||||||
if (cp->sb.sz >= CPARSE_MAX_BUF/2)
|
|
||||||
cp_err(cp, LJ_ERR_XELEM);
|
|
||||||
lj_buf_grow(cp->L, &cp->sb, 0);
|
|
||||||
cp->sb.buf[cp->sb.n++] = (char)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save character in buffer. */
|
/* Save character in buffer. */
|
||||||
static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
|
static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
|
||||||
{
|
{
|
||||||
if (LJ_UNLIKELY(cp->sb.n + 1 > cp->sb.sz))
|
lj_buf_putb(cp->L, &cp->sb, c);
|
||||||
cp_save_grow(cp, c);
|
|
||||||
else
|
|
||||||
cp->sb.buf[cp->sb.n++] = (char)c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
|
/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
|
||||||
@ -121,9 +109,9 @@ LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
|
|||||||
tokstr = NULL;
|
tokstr = NULL;
|
||||||
} else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
|
} else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
|
||||||
tok >= CTOK_FIRSTDECL) {
|
tok >= CTOK_FIRSTDECL) {
|
||||||
if (cp->sb.n == 0) cp_save(cp, '$');
|
if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$');
|
||||||
cp_save(cp, '\0');
|
cp_save(cp, '\0');
|
||||||
tokstr = cp->sb.buf;
|
tokstr = sbufB(&cp->sb);
|
||||||
} else {
|
} else {
|
||||||
tokstr = cp_tok2str(cp, tok);
|
tokstr = cp_tok2str(cp, tok);
|
||||||
}
|
}
|
||||||
@ -163,7 +151,7 @@ static CPToken cp_number(CPState *cp)
|
|||||||
TValue o;
|
TValue o;
|
||||||
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
||||||
cp_save(cp, '\0');
|
cp_save(cp, '\0');
|
||||||
fmt = lj_strscan_scan((const uint8_t *)cp->sb.buf, &o, STRSCAN_OPT_C);
|
fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C);
|
||||||
if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
|
if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
|
||||||
else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
|
else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
|
||||||
else if (!(cp->mode & CPARSE_MODE_SKIP))
|
else if (!(cp->mode & CPARSE_MODE_SKIP))
|
||||||
@ -176,7 +164,7 @@ static CPToken cp_number(CPState *cp)
|
|||||||
static CPToken cp_ident(CPState *cp)
|
static CPToken cp_ident(CPState *cp)
|
||||||
{
|
{
|
||||||
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
||||||
cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n);
|
cp->str = lj_buf_str(cp->L, &cp->sb);
|
||||||
cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
|
cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
|
||||||
if (ctype_type(cp->ct->info) == CT_KW)
|
if (ctype_type(cp->ct->info) == CT_KW)
|
||||||
return ctype_cid(cp->ct->info);
|
return ctype_cid(cp->ct->info);
|
||||||
@ -262,11 +250,11 @@ static CPToken cp_string(CPState *cp)
|
|||||||
}
|
}
|
||||||
cp_get(cp);
|
cp_get(cp);
|
||||||
if (delim == '"') {
|
if (delim == '"') {
|
||||||
cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n);
|
cp->str = lj_buf_str(cp->L, &cp->sb);
|
||||||
return CTOK_STRING;
|
return CTOK_STRING;
|
||||||
} else {
|
} else {
|
||||||
if (cp->sb.n != 1) cp_err_token(cp, '\'');
|
if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
|
||||||
cp->val.i32 = (int32_t)(char)cp->sb.buf[0];
|
cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb);
|
||||||
cp->val.id = CTID_INT32;
|
cp->val.id = CTID_INT32;
|
||||||
return CTOK_INTEGER;
|
return CTOK_INTEGER;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_debug.h"
|
#include "lj_debug.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_str.h"
|
#include "lj_str.h"
|
||||||
#include "lj_tab.h"
|
#include "lj_tab.h"
|
||||||
#include "lj_state.h"
|
#include "lj_state.h"
|
||||||
@ -133,20 +134,6 @@ static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe)
|
|||||||
|
|
||||||
/* -- Variable names ------------------------------------------------------ */
|
/* -- Variable names ------------------------------------------------------ */
|
||||||
|
|
||||||
/* Read ULEB128 value. */
|
|
||||||
static uint32_t debug_read_uleb128(const uint8_t **pp)
|
|
||||||
{
|
|
||||||
const uint8_t *p = *pp;
|
|
||||||
uint32_t v = *p++;
|
|
||||||
if (LJ_UNLIKELY(v >= 0x80)) {
|
|
||||||
int sh = 0;
|
|
||||||
v &= 0x7f;
|
|
||||||
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
|
|
||||||
}
|
|
||||||
*pp = p;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get name of a local variable from slot number and PC. */
|
/* Get name of a local variable from slot number and PC. */
|
||||||
static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
|
static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
|
||||||
{
|
{
|
||||||
@ -162,9 +149,9 @@ static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
|
|||||||
} else {
|
} else {
|
||||||
while (*p++) ; /* Skip over variable name string. */
|
while (*p++) ; /* Skip over variable name string. */
|
||||||
}
|
}
|
||||||
lastpc = startpc = lastpc + debug_read_uleb128(&p);
|
lastpc = startpc = lastpc + lj_buf_ruleb128((const char **)&p);
|
||||||
if (startpc > pc) break;
|
if (startpc > pc) break;
|
||||||
endpc = startpc + debug_read_uleb128(&p);
|
endpc = startpc + lj_buf_ruleb128((const char **)&p);
|
||||||
if (pc < endpc && slot-- == 0) {
|
if (pc < endpc && slot-- == 0) {
|
||||||
if (vn < VARNAME__MAX) {
|
if (vn < VARNAME__MAX) {
|
||||||
#define VARNAMESTR(name, str) str "\0"
|
#define VARNAMESTR(name, str) str "\0"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_debug.h"
|
#include "lj_debug.h"
|
||||||
#include "lj_frame.h"
|
#include "lj_frame.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_jit.h"
|
#include "lj_jit.h"
|
||||||
#include "lj_dispatch.h"
|
#include "lj_dispatch.h"
|
||||||
|
|
||||||
@ -426,16 +427,6 @@ static void gdbjit_catnum(GDBJITctx *ctx, uint32_t n)
|
|||||||
*ctx->p++ = '0' + n;
|
*ctx->p++ = '0' + n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a ULEB128 value. */
|
|
||||||
static void gdbjit_uleb128(GDBJITctx *ctx, uint32_t v)
|
|
||||||
{
|
|
||||||
uint8_t *p = ctx->p;
|
|
||||||
for (; v >= 0x80; v >>= 7)
|
|
||||||
*p++ = (uint8_t)((v & 0x7f) | 0x80);
|
|
||||||
*p++ = (uint8_t)v;
|
|
||||||
ctx->p = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a SLEB128 value. */
|
/* Add a SLEB128 value. */
|
||||||
static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v)
|
static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v)
|
||||||
{
|
{
|
||||||
@ -452,7 +443,7 @@ static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v)
|
|||||||
#define DU16(x) (*(uint16_t *)p = (x), p += 2)
|
#define DU16(x) (*(uint16_t *)p = (x), p += 2)
|
||||||
#define DU32(x) (*(uint32_t *)p = (x), p += 4)
|
#define DU32(x) (*(uint32_t *)p = (x), p += 4)
|
||||||
#define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t))
|
#define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t))
|
||||||
#define DUV(x) (ctx->p = p, gdbjit_uleb128(ctx, (x)), p = ctx->p)
|
#define DUV(x) (p = (uint8_t *)lj_buf_wuleb128((char *)p, (x)))
|
||||||
#define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p)
|
#define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p)
|
||||||
#define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p)
|
#define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p)
|
||||||
#define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop
|
#define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop
|
||||||
|
27
src/lj_lex.c
27
src/lj_lex.c
@ -12,6 +12,7 @@
|
|||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_gc.h"
|
#include "lj_gc.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_str.h"
|
#include "lj_str.h"
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
#include "lj_tab.h"
|
#include "lj_tab.h"
|
||||||
@ -54,20 +55,9 @@ static int fillbuf(LexState *ls)
|
|||||||
return char2int(*(ls->p++));
|
return char2int(*(ls->p++));
|
||||||
}
|
}
|
||||||
|
|
||||||
static LJ_NOINLINE void save_grow(LexState *ls, int c)
|
|
||||||
{
|
|
||||||
if (ls->sb.sz >= LJ_MAX_STR/2)
|
|
||||||
lj_lex_error(ls, 0, LJ_ERR_XELEM);
|
|
||||||
lj_buf_grow(ls->L, &ls->sb, 0);
|
|
||||||
ls->sb.buf[ls->sb.n++] = (char)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LJ_AINLINE void save(LexState *ls, int c)
|
static LJ_AINLINE void save(LexState *ls, int c)
|
||||||
{
|
{
|
||||||
if (LJ_UNLIKELY(ls->sb.n + 1 > ls->sb.sz))
|
lj_buf_putb(ls->L, &ls->sb, c);
|
||||||
save_grow(ls, c);
|
|
||||||
else
|
|
||||||
ls->sb.buf[ls->sb.n++] = (char)c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inclinenumber(LexState *ls)
|
static void inclinenumber(LexState *ls)
|
||||||
@ -99,7 +89,7 @@ static void lex_number(LexState *ls, TValue *tv)
|
|||||||
save_and_next(ls);
|
save_and_next(ls);
|
||||||
}
|
}
|
||||||
save(ls, '\0');
|
save(ls, '\0');
|
||||||
fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv,
|
fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv,
|
||||||
(LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
|
(LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
|
||||||
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
|
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
|
||||||
if (LJ_DUALNUM && fmt == STRSCAN_INT) {
|
if (LJ_DUALNUM && fmt == STRSCAN_INT) {
|
||||||
@ -174,8 +164,8 @@ static void read_long_string(LexState *ls, TValue *tv, int sep)
|
|||||||
}
|
}
|
||||||
} endloop:
|
} endloop:
|
||||||
if (tv) {
|
if (tv) {
|
||||||
GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep),
|
GCstr *str = lj_parse_keepstr(ls, sbufB(&ls->sb) + (2 + (MSize)sep),
|
||||||
ls->sb.n - 2*(2 + (MSize)sep));
|
sbuflen(&ls->sb) - 2*(2 + (MSize)sep));
|
||||||
setstrV(ls->L, tv, str);
|
setstrV(ls->L, tv, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +240,8 @@ static void read_string(LexState *ls, int delim, TValue *tv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_and_next(ls); /* skip delimiter */
|
save_and_next(ls); /* skip delimiter */
|
||||||
setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2));
|
setstrV(ls->L, tv,
|
||||||
|
lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Main lexical scanner ------------------------------------------------ */
|
/* -- Main lexical scanner ------------------------------------------------ */
|
||||||
@ -269,7 +260,7 @@ static int llex(LexState *ls, TValue *tv)
|
|||||||
do {
|
do {
|
||||||
save_and_next(ls);
|
save_and_next(ls);
|
||||||
} while (lj_char_isident(ls->current));
|
} while (lj_char_isident(ls->current));
|
||||||
s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n);
|
s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb));
|
||||||
setstrV(ls->L, tv, s);
|
setstrV(ls->L, tv, s);
|
||||||
if (s->reserved > 0) /* Reserved word? */
|
if (s->reserved > 0) /* Reserved word? */
|
||||||
return TK_OFS + s->reserved;
|
return TK_OFS + s->reserved;
|
||||||
@ -457,7 +448,7 @@ void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...)
|
|||||||
tok = NULL;
|
tok = NULL;
|
||||||
} else if (token == TK_name || token == TK_string || token == TK_number) {
|
} else if (token == TK_name || token == TK_string || token == TK_number) {
|
||||||
save(ls, '\0');
|
save(ls, '\0');
|
||||||
tok = ls->sb.buf;
|
tok = sbufB(&ls->sb);
|
||||||
} else {
|
} else {
|
||||||
tok = lj_lex_token2str(ls, token);
|
tok = lj_lex_token2str(ls, token);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_buf.h"
|
|
||||||
|
|
||||||
/* Lua lexer tokens. */
|
/* Lua lexer tokens. */
|
||||||
#define TKDEF(_, __) \
|
#define TKDEF(_, __) \
|
||||||
|
@ -121,9 +121,9 @@ typedef void (*ASMFunction)(void);
|
|||||||
|
|
||||||
/* Resizable string buffer. Need this here, details in lj_buf.h. */
|
/* Resizable string buffer. Need this here, details in lj_buf.h. */
|
||||||
typedef struct SBuf {
|
typedef struct SBuf {
|
||||||
char *buf; /* String buffer base. */
|
MRef p; /* String buffer pointer. */
|
||||||
MSize n; /* String buffer length. */
|
MRef e; /* String buffer end pointer. */
|
||||||
MSize sz; /* String buffer size. */
|
MRef b; /* String buffer base. */
|
||||||
} SBuf;
|
} SBuf;
|
||||||
|
|
||||||
/* -- Tags and values ----------------------------------------------------- */
|
/* -- Tags and values ----------------------------------------------------- */
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "lj_gc.h"
|
#include "lj_gc.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_debug.h"
|
#include "lj_debug.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_str.h"
|
#include "lj_str.h"
|
||||||
#include "lj_tab.h"
|
#include "lj_tab.h"
|
||||||
#include "lj_func.h"
|
#include "lj_func.h"
|
||||||
@ -1429,31 +1430,6 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len)
|
|
||||||
{
|
|
||||||
lj_buf_need(ls->L, &ls->sb, ls->sb.n + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add string to buffer. */
|
|
||||||
static void fs_buf_str(LexState *ls, const char *str, MSize len)
|
|
||||||
{
|
|
||||||
char *p = ls->sb.buf + ls->sb.n;
|
|
||||||
MSize i;
|
|
||||||
ls->sb.n += len;
|
|
||||||
for (i = 0; i < len; i++) p[i] = str[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add ULEB128 value to buffer. */
|
|
||||||
static void fs_buf_uleb128(LexState *ls, uint32_t v)
|
|
||||||
{
|
|
||||||
MSize n = ls->sb.n;
|
|
||||||
uint8_t *p = (uint8_t *)ls->sb.buf;
|
|
||||||
for (; v >= 0x80; v >>= 7)
|
|
||||||
p[n++] = (uint8_t)((v & 0x7f) | 0x80);
|
|
||||||
p[n++] = (uint8_t)v;
|
|
||||||
ls->sb.n = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare variable info for prototype. */
|
/* Prepare variable info for prototype. */
|
||||||
static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
|
static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
|
||||||
{
|
{
|
||||||
@ -1465,33 +1441,35 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
|
|||||||
for (i = 0, n = fs->nuv; i < n; i++) {
|
for (i = 0, n = fs->nuv; i < n; i++) {
|
||||||
GCstr *s = strref(vs[fs->uvmap[i]].name);
|
GCstr *s = strref(vs[fs->uvmap[i]].name);
|
||||||
MSize len = s->len+1;
|
MSize len = s->len+1;
|
||||||
fs_buf_need(ls, len);
|
char *p = lj_buf_more(ls->L, &ls->sb, len);
|
||||||
fs_buf_str(ls, strdata(s), len);
|
p = lj_buf_wmem(p, strdata(s), len);
|
||||||
|
setsbufP(&ls->sb, p);
|
||||||
}
|
}
|
||||||
*ofsvar = ls->sb.n;
|
*ofsvar = sbuflen(&ls->sb);
|
||||||
lastpc = 0;
|
lastpc = 0;
|
||||||
/* Store local variable names and compressed ranges. */
|
/* Store local variable names and compressed ranges. */
|
||||||
for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) {
|
for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) {
|
||||||
if (!gola_isgotolabel(vs)) {
|
if (!gola_isgotolabel(vs)) {
|
||||||
GCstr *s = strref(vs->name);
|
GCstr *s = strref(vs->name);
|
||||||
BCPos startpc;
|
BCPos startpc;
|
||||||
|
char *p;
|
||||||
if ((uintptr_t)s < VARNAME__MAX) {
|
if ((uintptr_t)s < VARNAME__MAX) {
|
||||||
fs_buf_need(ls, 1 + 2*5);
|
p = lj_buf_more(ls->L, &ls->sb, 1 + 2*5);
|
||||||
ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s;
|
*p++ = (char)(uintptr_t)s;
|
||||||
} else {
|
} else {
|
||||||
MSize len = s->len+1;
|
MSize len = s->len+1;
|
||||||
fs_buf_need(ls, len + 2*5);
|
p = lj_buf_more(ls->L, &ls->sb, len + 2*5);
|
||||||
fs_buf_str(ls, strdata(s), len);
|
p = lj_buf_wmem(p, strdata(s), len);
|
||||||
}
|
}
|
||||||
startpc = vs->startpc;
|
startpc = vs->startpc;
|
||||||
fs_buf_uleb128(ls, startpc-lastpc);
|
p = lj_buf_wuleb128(p, startpc-lastpc);
|
||||||
fs_buf_uleb128(ls, vs->endpc-startpc);
|
p = lj_buf_wuleb128(p, vs->endpc-startpc);
|
||||||
|
setsbufP(&ls->sb, p);
|
||||||
lastpc = startpc;
|
lastpc = startpc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs_buf_need(ls, 1);
|
lj_buf_putb(ls->L, &ls->sb, '\0'); /* Terminator for varinfo. */
|
||||||
ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */
|
return sbuflen(&ls->sb);
|
||||||
return ls->sb.n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fixup variable info for prototype. */
|
/* Fixup variable info for prototype. */
|
||||||
@ -1499,7 +1477,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
|
|||||||
{
|
{
|
||||||
setmref(pt->uvinfo, p);
|
setmref(pt->uvinfo, p);
|
||||||
setmref(pt->varinfo, (char *)p + ofsvar);
|
setmref(pt->varinfo, (char *)p + ofsvar);
|
||||||
memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */
|
memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
38
src/lj_str.c
38
src/lj_str.c
@ -218,20 +218,6 @@ GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
|
|||||||
|
|
||||||
/* -- String formatting --------------------------------------------------- */
|
/* -- String formatting --------------------------------------------------- */
|
||||||
|
|
||||||
static void addstr(lua_State *L, SBuf *sb, const char *str, MSize len)
|
|
||||||
{
|
|
||||||
MSize i;
|
|
||||||
char *p = lj_buf_need(L, sb, sb->n+len) + sb->n;
|
|
||||||
sb->n += len;
|
|
||||||
for (i = 0; i < len; i++) p[i] = str[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addchar(lua_State *L, SBuf *sb, int c)
|
|
||||||
{
|
|
||||||
char *p = lj_buf_need(L, sb, sb->n+1);
|
|
||||||
p[sb->n++] = (char)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Push formatted message as a string object to Lua stack. va_list variant. */
|
/* Push formatted message as a string object to Lua stack. va_list variant. */
|
||||||
const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
||||||
{
|
{
|
||||||
@ -241,22 +227,22 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
const char *e = strchr(fmt, '%');
|
const char *e = strchr(fmt, '%');
|
||||||
if (e == NULL) break;
|
if (e == NULL) break;
|
||||||
addstr(L, sb, fmt, (MSize)(e-fmt));
|
lj_buf_putmem(L, sb, fmt, (MSize)(e-fmt));
|
||||||
/* This function only handles %s, %c, %d, %f and %p formats. */
|
/* This function only handles %s, %c, %d, %f and %p formats. */
|
||||||
switch (e[1]) {
|
switch (e[1]) {
|
||||||
case 's': {
|
case 's': {
|
||||||
const char *s = va_arg(argp, char *);
|
const char *s = va_arg(argp, char *);
|
||||||
if (s == NULL) s = "(null)";
|
if (s == NULL) s = "(null)";
|
||||||
addstr(L, sb, s, (MSize)strlen(s));
|
lj_buf_putmem(L, sb, s, (MSize)strlen(s));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'c':
|
case 'c':
|
||||||
addchar(L, sb, va_arg(argp, int));
|
lj_buf_putb(L, sb, va_arg(argp, int));
|
||||||
break;
|
break;
|
||||||
case 'd': {
|
case 'd': {
|
||||||
char buf[LJ_STR_INTBUF];
|
char buf[LJ_STR_INTBUF];
|
||||||
char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
|
char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
|
||||||
addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
|
lj_buf_putmem(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'f': {
|
case 'f': {
|
||||||
@ -265,7 +251,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
|||||||
MSize len;
|
MSize len;
|
||||||
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
|
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
|
||||||
len = (MSize)lj_str_bufnum(buf, &tv);
|
len = (MSize)lj_str_bufnum(buf, &tv);
|
||||||
addstr(L, sb, buf, len);
|
lj_buf_putmem(L, sb, buf, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': {
|
case 'p': {
|
||||||
@ -274,7 +260,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
|||||||
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
|
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
|
||||||
ptrdiff_t i, lasti = 2+FMTP_CHARS;
|
ptrdiff_t i, lasti = 2+FMTP_CHARS;
|
||||||
if (p == 0) {
|
if (p == 0) {
|
||||||
addstr(L, sb, "NULL", 4);
|
lj_buf_putmem(L, sb, "NULL", 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if LJ_64
|
#if LJ_64
|
||||||
@ -285,21 +271,21 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
|||||||
buf[1] = 'x';
|
buf[1] = 'x';
|
||||||
for (i = lasti-1; i >= 2; i--, p >>= 4)
|
for (i = lasti-1; i >= 2; i--, p >>= 4)
|
||||||
buf[i] = "0123456789abcdef"[(p & 15)];
|
buf[i] = "0123456789abcdef"[(p & 15)];
|
||||||
addstr(L, sb, buf, (MSize)lasti);
|
lj_buf_putmem(L, sb, buf, (MSize)lasti);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '%':
|
case '%':
|
||||||
addchar(L, sb, '%');
|
lj_buf_putb(L, sb, '%');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
addchar(L, sb, '%');
|
lj_buf_putb(L, sb, '%');
|
||||||
addchar(L, sb, e[1]);
|
lj_buf_putb(L, sb, e[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fmt = e+2;
|
fmt = e+2;
|
||||||
}
|
}
|
||||||
addstr(L, sb, fmt, (MSize)strlen(fmt));
|
lj_buf_putmem(L, sb, fmt, (MSize)strlen(fmt));
|
||||||
setstrV(L, L->top, lj_str_new(L, sb->buf, sb->n));
|
setstrV(L, L->top, lj_buf_str(L, sb));
|
||||||
incr_top(L);
|
incr_top(L);
|
||||||
return strVdata(L->top - 1);
|
return strVdata(L->top - 1);
|
||||||
}
|
}
|
||||||
|
@ -1801,10 +1801,11 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| cmp CARG2, #1
|
| cmp CARG2, #1
|
||||||
| blo ->fff_emptystr // Zero-length string?
|
| blo ->fff_emptystr // Zero-length string?
|
||||||
| bne ->fff_fallback // Fallback for > 1-char strings.
|
| bne ->fff_fallback // Fallback for > 1-char strings.
|
||||||
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
|
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
|
||||||
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
|
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
|
||||||
| ldr CARG1, STR:CARG1[1]
|
| ldr CARG1, STR:CARG1[1]
|
||||||
| cmp RB, CARG3
|
| add INS, CARG2, CARG3
|
||||||
|
| cmp RB, INS
|
||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
|1: // Fill buffer with char.
|
|1: // Fill buffer with char.
|
||||||
| strb CARG1, [CARG2, CARG4]
|
| strb CARG1, [CARG2, CARG4]
|
||||||
@ -1819,11 +1820,12 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
| checkstr CARG2, ->fff_fallback
|
| checkstr CARG2, ->fff_fallback
|
||||||
| ldr CARG3, STR:CARG1->len
|
| ldr CARG3, STR:CARG1->len
|
||||||
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
|
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
|
||||||
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
|
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
|
||||||
| mov CARG4, CARG3
|
| mov CARG4, CARG3
|
||||||
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
||||||
| cmp RB, CARG3
|
| add INS, CARG2, CARG3
|
||||||
|
| cmp RB, INS
|
||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
|1: // Reverse string copy.
|
|1: // Reverse string copy.
|
||||||
| ldrb RB, [CARG1], #1
|
| ldrb RB, [CARG1], #1
|
||||||
@ -1840,11 +1842,12 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
| checkstr CARG2, ->fff_fallback
|
| checkstr CARG2, ->fff_fallback
|
||||||
| ldr CARG3, STR:CARG1->len
|
| ldr CARG3, STR:CARG1->len
|
||||||
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
|
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
|
||||||
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
|
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
|
||||||
| mov CARG4, #0
|
| mov CARG4, #0
|
||||||
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
||||||
| cmp RB, CARG3
|
| add INS, CARG2, CARG3
|
||||||
|
| cmp RB, INS
|
||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
|1: // ASCII case conversion.
|
|1: // ASCII case conversion.
|
||||||
| ldrb RB, [CARG1, CARG4]
|
| ldrb RB, [CARG1, CARG4]
|
||||||
|
@ -1736,14 +1736,15 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| beqz AT, ->fff_fallback
|
| beqz AT, ->fff_fallback
|
||||||
|. lw TMP0, STR:CARG1->len
|
|. lw TMP0, STR:CARG1->len
|
||||||
| mfc1 CARG3, f0
|
| mfc1 CARG3, f0
|
||||||
| lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
| lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
|
| lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
| li AT, 1
|
| li AT, 1
|
||||||
| blez CARG3, ->fff_emptystr // Count <= 0?
|
| blez CARG3, ->fff_emptystr // Count <= 0?
|
||||||
|. sltu AT, AT, TMP0
|
|. sltu AT, AT, TMP0
|
||||||
| beqz TMP0, ->fff_emptystr // Zero length string?
|
| beqz TMP0, ->fff_emptystr // Zero length string?
|
||||||
|. sltu TMP0, TMP1, CARG3
|
|. addu TMP3, CARG2, CARG3
|
||||||
|
| sltu TMP0, TMP1, TMP3
|
||||||
| or AT, AT, TMP0
|
| or AT, AT, TMP0
|
||||||
| lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
|
||||||
| bnez AT, ->fff_fallback // Fallback for > 1-char strings.
|
| bnez AT, ->fff_fallback // Fallback for > 1-char strings.
|
||||||
|. lbu TMP0, STR:CARG1[1]
|
|. lbu TMP0, STR:CARG1[1]
|
||||||
| addu TMP2, CARG2, CARG3
|
| addu TMP2, CARG2, CARG3
|
||||||
@ -1762,14 +1763,14 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| beqz NARGS8:RC, ->fff_fallback
|
| beqz NARGS8:RC, ->fff_fallback
|
||||||
|. li AT, LJ_TSTR
|
|. li AT, LJ_TSTR
|
||||||
| bne CARG3, AT, ->fff_fallback
|
| bne CARG3, AT, ->fff_fallback
|
||||||
|. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
|. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
| lw CARG3, STR:CARG1->len
|
| lw CARG3, STR:CARG1->len
|
||||||
|
| lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
| addiu CARG1, STR:CARG1, #STR
|
| addiu CARG1, STR:CARG1, #STR
|
||||||
| lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
| addu CARG4, CARG2, CARG3
|
||||||
| sltu AT, TMP1, CARG3
|
| sltu AT, TMP1, CARG4
|
||||||
| bnez AT, ->fff_fallback
|
| bnez AT, ->fff_fallback
|
||||||
|. addu TMP3, CARG1, CARG3
|
|. addu TMP3, CARG1, CARG3
|
||||||
| addu CARG4, CARG2, CARG3
|
|
||||||
|1: // Reverse string copy.
|
|1: // Reverse string copy.
|
||||||
| lbu TMP1, 0(CARG1)
|
| lbu TMP1, 0(CARG1)
|
||||||
| sltu AT, CARG1, TMP3
|
| sltu AT, CARG1, TMP3
|
||||||
@ -1787,11 +1788,12 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| beqz NARGS8:RC, ->fff_fallback
|
| beqz NARGS8:RC, ->fff_fallback
|
||||||
|. li AT, LJ_TSTR
|
|. li AT, LJ_TSTR
|
||||||
| bne CARG3, AT, ->fff_fallback
|
| bne CARG3, AT, ->fff_fallback
|
||||||
|. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
|. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
| lw CARG3, STR:CARG1->len
|
| lw CARG3, STR:CARG1->len
|
||||||
|
| lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
| addiu CARG1, STR:CARG1, #STR
|
| addiu CARG1, STR:CARG1, #STR
|
||||||
| lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
| addu TMP3, CARG2, CARG3
|
||||||
| sltu AT, TMP1, CARG3
|
| sltu AT, TMP1, TMP3
|
||||||
| bnez AT, ->fff_fallback
|
| bnez AT, ->fff_fallback
|
||||||
|. addu TMP3, CARG1, CARG3
|
|. addu TMP3, CARG1, CARG3
|
||||||
| move CARG4, CARG2
|
| move CARG4, CARG2
|
||||||
|
@ -2201,15 +2201,16 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.endif
|
|.endif
|
||||||
| lwz TMP0, STR:CARG1->len
|
| lwz TMP0, STR:CARG1->len
|
||||||
| cmpwi CARG3, 0
|
| cmpwi CARG3, 0
|
||||||
| lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
| lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
|
| lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
| ble >2 // Count <= 0? (or non-int)
|
| ble >2 // Count <= 0? (or non-int)
|
||||||
| cmplwi TMP0, 1
|
| cmplwi TMP0, 1
|
||||||
|
| add TMP3, CARG2, CARG3
|
||||||
| subi TMP2, CARG3, 1
|
| subi TMP2, CARG3, 1
|
||||||
| blt >2 // Zero length string?
|
| blt >2 // Zero length string?
|
||||||
| cmplw cr1, TMP1, CARG3
|
| cmplw cr1, TMP1, TMP3
|
||||||
| bne ->fff_fallback // Fallback for > 1-char strings.
|
| bne ->fff_fallback // Fallback for > 1-char strings.
|
||||||
| lbz TMP0, STR:CARG1[1]
|
| lbz TMP0, STR:CARG1[1]
|
||||||
| lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
|
||||||
| blt cr1, ->fff_fallback
|
| blt cr1, ->fff_fallback
|
||||||
|1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
|
|1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
|
||||||
| cmplwi TMP2, 0
|
| cmplwi TMP2, 0
|
||||||
@ -2229,13 +2230,14 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| lwz STR:CARG1, 4(BASE)
|
| lwz STR:CARG1, 4(BASE)
|
||||||
| blt ->fff_fallback
|
| blt ->fff_fallback
|
||||||
| checkstr CARG3
|
| checkstr CARG3
|
||||||
| lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
| lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
|
| lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
| bne ->fff_fallback
|
| bne ->fff_fallback
|
||||||
| lwz CARG3, STR:CARG1->len
|
| lwz CARG3, STR:CARG1->len
|
||||||
| la CARG1, #STR(STR:CARG1)
|
| la CARG1, #STR(STR:CARG1)
|
||||||
| lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
|
||||||
| li TMP2, 0
|
| li TMP2, 0
|
||||||
| cmplw TMP1, CARG3
|
| add TMP3, CARG2, CARG3
|
||||||
|
| cmplw TMP1, TMP3
|
||||||
| subi TMP3, CARG3, 1
|
| subi TMP3, CARG3, 1
|
||||||
| blt ->fff_fallback
|
| blt ->fff_fallback
|
||||||
|1: // Reverse string copy.
|
|1: // Reverse string copy.
|
||||||
@ -2255,13 +2257,14 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| lwz STR:CARG1, 4(BASE)
|
| lwz STR:CARG1, 4(BASE)
|
||||||
| blt ->fff_fallback
|
| blt ->fff_fallback
|
||||||
| checkstr CARG3
|
| checkstr CARG3
|
||||||
| lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
|
| lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
||||||
|
| lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
||||||
| bne ->fff_fallback
|
| bne ->fff_fallback
|
||||||
| lwz CARG3, STR:CARG1->len
|
| lwz CARG3, STR:CARG1->len
|
||||||
| la CARG1, #STR(STR:CARG1)
|
| la CARG1, #STR(STR:CARG1)
|
||||||
| lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
|
|
||||||
| cmplw TMP1, CARG3
|
|
||||||
| li TMP2, 0
|
| li TMP2, 0
|
||||||
|
| add TMP3, CARG2, CARG3
|
||||||
|
| cmplw TMP1, TMP3
|
||||||
| blt ->fff_fallback
|
| blt ->fff_fallback
|
||||||
|1: // ASCII case conversion.
|
|1: // ASCII case conversion.
|
||||||
| cmplw TMP2, CARG3
|
| cmplw TMP2, CARG3
|
||||||
|
@ -2356,20 +2356,21 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| cmp dword STR:RB->len, 1
|
| cmp dword STR:RB->len, 1
|
||||||
| jb ->fff_emptystr // Zero length string?
|
| jb ->fff_emptystr // Zero length string?
|
||||||
| jne ->fff_fallback_2 // Fallback for > 1-char strings.
|
| jne ->fff_fallback_2 // Fallback for > 1-char strings.
|
||||||
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_2
|
|
||||||
| movzx RA, byte STR:RB[1]
|
| movzx RA, byte STR:RB[1]
|
||||||
| mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
|
| mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
||||||
|
| add RB, RC
|
||||||
|
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RB; jb ->fff_fallback_2
|
||||||
|.if X64
|
|.if X64
|
||||||
| mov TMP3, RC
|
| mov TMP3, RC
|
||||||
|.else
|
|.else
|
||||||
| mov ARG3, RC
|
| mov ARG3, RC
|
||||||
|.endif
|
|.endif
|
||||||
|1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
|
|1: // Fill buffer with char.
|
||||||
| mov [RB], RAL
|
| sub RB, 1
|
||||||
| add RB, 1
|
|
||||||
| sub RC, 1
|
| sub RC, 1
|
||||||
|
| mov [RB], RAL
|
||||||
| jnz <1
|
| jnz <1
|
||||||
| mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
|
| mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
||||||
| jmp ->fff_newstr
|
| jmp ->fff_newstr
|
||||||
|
|
|
|
||||||
|.ffunc_1 string_reverse
|
|.ffunc_1 string_reverse
|
||||||
@ -2379,15 +2380,16 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov RC, STR:RB->len
|
| mov RC, STR:RB->len
|
||||||
| test RC, RC
|
| test RC, RC
|
||||||
| jz ->fff_emptystr // Zero length string?
|
| jz ->fff_emptystr // Zero length string?
|
||||||
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
|
|
||||||
| add RB, #STR
|
|
||||||
| mov TMP2, PC // Need another temp register.
|
| 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
|
|.if X64
|
||||||
| mov TMP3, RC
|
| mov TMP3, RC
|
||||||
|.else
|
|.else
|
||||||
| mov ARG3, RC
|
| mov ARG3, RC
|
||||||
|.endif
|
|.endif
|
||||||
| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
|
|
||||||
|1:
|
|1:
|
||||||
| movzx RA, byte [RB]
|
| movzx RA, byte [RB]
|
||||||
| add RB, 1
|
| add RB, 1
|
||||||
@ -2402,17 +2404,18 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| .ffunc_1 name
|
| .ffunc_1 name
|
||||||
| ffgccheck
|
| ffgccheck
|
||||||
| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
|
| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
|
||||||
|
| mov TMP2, PC // Need another temp register.
|
||||||
| mov STR:RB, [BASE]
|
| mov STR:RB, [BASE]
|
||||||
| mov RC, STR:RB->len
|
| mov RC, STR:RB->len
|
||||||
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
|
| 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
|
| add RB, #STR
|
||||||
| mov TMP2, PC // Need another temp register.
|
|
||||||
|.if X64
|
|.if X64
|
||||||
| mov TMP3, RC
|
| mov TMP3, RC
|
||||||
|.else
|
|.else
|
||||||
| mov ARG3, RC
|
| mov ARG3, RC
|
||||||
|.endif
|
|.endif
|
||||||
| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
|
|
||||||
| jmp >3
|
| jmp >3
|
||||||
|1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
|
|1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
|
||||||
| movzx RA, byte [RB+RC]
|
| movzx RA, byte [RB+RC]
|
||||||
|
Loading…
Reference in New Issue
Block a user