diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.dep | 39 | ||||
| -rw-r--r-- | src/lib_string.c | 1 | ||||
| -rw-r--r-- | src/lj_bcread.c | 21 | ||||
| -rw-r--r-- | src/lj_bcwrite.c | 204 | ||||
| -rw-r--r-- | src/lj_buf.c | 64 | ||||
| -rw-r--r-- | src/lj_buf.h | 60 | ||||
| -rw-r--r-- | src/lj_cparse.c | 28 | ||||
| -rw-r--r-- | src/lj_debug.c | 19 | ||||
| -rw-r--r-- | src/lj_gdbjit.c | 13 | ||||
| -rw-r--r-- | src/lj_lex.c | 27 | ||||
| -rw-r--r-- | src/lj_lex.h | 1 | ||||
| -rw-r--r-- | src/lj_obj.h | 6 | ||||
| -rw-r--r-- | src/lj_parse.c | 54 | ||||
| -rw-r--r-- | src/lj_str.c | 38 | ||||
| -rw-r--r-- | src/vm_arm.dasc | 21 | ||||
| -rw-r--r-- | src/vm_mips.dasc | 26 | ||||
| -rw-r--r-- | src/vm_ppc.dasc | 21 | ||||
| -rw-r--r-- | src/vm_x86.dasc | 27 |
18 files changed, 334 insertions, 336 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep index 56594704..f841767b 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -17,8 +17,8 @@ lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | |||
| 17 | lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h | 17 | lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h |
| 18 | lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h | 18 | lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h |
| 19 | lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | 19 | lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ |
| 20 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_state.h lj_ff.h \ | 20 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_state.h \ |
| 21 | lj_ffdef.h lj_lib.h lj_libdef.h | 21 | lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h |
| 22 | lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \ | 22 | lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \ |
| 23 | lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \ | 23 | lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \ |
| 24 | lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \ | 24 | 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 \ | |||
| 31 | lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 31 | lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ |
| 32 | lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h | 32 | lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h |
| 33 | lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 33 | lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ |
| 34 | lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \ | 34 | lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \ |
| 35 | lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h lj_buf.h \ | 35 | lj_tab.h lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h \ |
| 36 | lj_char.h lj_lib.h lj_libdef.h | 36 | lj_char.h lj_lib.h lj_libdef.h |
| 37 | lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 37 | lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ |
| 38 | lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \ | 38 | 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 \ | |||
| 56 | lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \ | 56 | lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \ |
| 57 | lj_ir.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h | 57 | lj_ir.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h |
| 58 | lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 58 | lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 59 | lj_err.h lj_errmsg.h lj_buf.h | 59 | lj_err.h lj_errmsg.h lj_buf.h lj_str.h |
| 60 | lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 60 | lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 61 | lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \ | 61 | lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \ |
| 62 | lj_cdata.h lj_carith.h | 62 | 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 \ | |||
| 91 | lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 91 | lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 92 | lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h | 92 | lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h |
| 93 | lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 93 | lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 94 | lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \ | 94 | lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \ |
| 95 | lj_bc.h lj_jit.h lj_ir.h | 95 | lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h |
| 96 | lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 96 | lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 97 | lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \ | 97 | lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \ |
| 98 | lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \ | 98 | 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 \ | |||
| 115 | lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \ | 115 | lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \ |
| 116 | lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h | 116 | lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h |
| 117 | lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 117 | lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 118 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \ | 118 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \ |
| 119 | lj_ir.h lj_dispatch.h | 119 | lj_str.h lj_jit.h lj_ir.h lj_dispatch.h |
| 120 | lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 120 | lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 121 | lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ | 121 | lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ |
| 122 | lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \ | 122 | lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \ |
| 123 | lj_vm.h lj_strscan.h lj_lib.h | 123 | lj_vm.h lj_strscan.h lj_lib.h |
| 124 | lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 124 | lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 125 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \ | 125 | lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \ |
| 126 | lj_state.h lj_lex.h lj_buf.h lj_parse.h lj_char.h lj_strscan.h | 126 | lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h |
| 127 | lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \ | 127 | lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \ |
| 128 | lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \ | 128 | lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \ |
| 129 | lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_buf.h \ | 129 | lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_bcdump.h \ |
| 130 | lj_bcdump.h lj_lib.h | 130 | lj_lib.h |
| 131 | lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ | 131 | lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ |
| 132 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \ | 132 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \ |
| 133 | lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h | 133 | 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 \ | |||
| 145 | lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \ | 145 | lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \ |
| 146 | lj_strscan.h lj_folddef.h | 146 | lj_strscan.h lj_folddef.h |
| 147 | lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 147 | lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 148 | lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h \ | 148 | lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h lj_jit.h \ |
| 149 | lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h | 149 | lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \ |
| 150 | lj_vm.h | ||
| 150 | lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 151 | lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 151 | lj_tab.h lj_ir.h lj_jit.h lj_iropt.h | 152 | lj_tab.h lj_ir.h lj_jit.h lj_iropt.h |
| 152 | lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \ | 153 | 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 \ | |||
| 155 | lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 156 | lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 156 | lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h | 157 | lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h |
| 157 | lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \ | 158 | lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \ |
| 158 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ir.h lj_jit.h \ | 159 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \ |
| 159 | lj_ircall.h lj_iropt.h lj_vm.h | 160 | lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h |
| 160 | lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 161 | lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 161 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \ | 162 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ |
| 162 | lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_buf.h lj_parse.h lj_vm.h \ | 163 | lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h \ |
| 163 | lj_vmevent.h | 164 | lj_vmevent.h |
| 164 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 165 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 165 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ | 166 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ |
diff --git a/src/lib_string.c b/src/lib_string.c index 5fdfcd91..36fd3f53 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "lj_obj.h" | 18 | #include "lj_obj.h" |
| 19 | #include "lj_gc.h" | 19 | #include "lj_gc.h" |
| 20 | #include "lj_err.h" | 20 | #include "lj_err.h" |
| 21 | #include "lj_buf.h" | ||
| 21 | #include "lj_str.h" | 22 | #include "lj_str.h" |
| 22 | #include "lj_tab.h" | 23 | #include "lj_tab.h" |
| 23 | #include "lj_meta.h" | 24 | #include "lj_meta.h" |
diff --git a/src/lj_bcread.c b/src/lj_bcread.c index fabe76da..eda121e0 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c | |||
| @@ -53,27 +53,28 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need) | |||
| 53 | const char *buf; | 53 | const char *buf; |
| 54 | size_t size; | 54 | size_t size; |
| 55 | if (ls->n) { /* Copy remainder to buffer. */ | 55 | if (ls->n) { /* Copy remainder to buffer. */ |
| 56 | if (ls->sb.n) { /* Move down in buffer. */ | 56 | if (sbuflen(&ls->sb)) { /* Move down in buffer. */ |
| 57 | lua_assert(ls->p + ls->n == ls->sb.buf + ls->sb.n); | 57 | lua_assert(ls->p + ls->n == sbufP(&ls->sb)); |
| 58 | if (ls->n != ls->sb.n) | 58 | if (ls->n != sbuflen(&ls->sb)) |
| 59 | memmove(ls->sb.buf, ls->p, ls->n); | 59 | memmove(sbufB(&ls->sb), ls->p, ls->n); |
| 60 | } else { /* Copy from buffer provided by reader. */ | 60 | } else { /* Copy from buffer provided by reader. */ |
| 61 | memcpy(lj_buf_need(ls->L, &ls->sb, len), ls->p, ls->n); | 61 | memcpy(lj_buf_need(ls->L, &ls->sb, len), ls->p, ls->n); |
| 62 | } | 62 | } |
| 63 | ls->p = ls->sb.buf; | 63 | ls->p = sbufB(&ls->sb); |
| 64 | } | 64 | } |
| 65 | ls->sb.n = ls->n; | 65 | setsbufP(&ls->sb, sbufB(&ls->sb) + ls->n); |
| 66 | buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */ | 66 | buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */ |
| 67 | if (buf == NULL || size == 0) { /* EOF? */ | 67 | if (buf == NULL || size == 0) { /* EOF? */ |
| 68 | if (need) bcread_error(ls, LJ_ERR_BCBAD); | 68 | if (need) bcread_error(ls, LJ_ERR_BCBAD); |
| 69 | ls->current = -1; /* Only bad if we get called again. */ | 69 | ls->current = -1; /* Only bad if we get called again. */ |
| 70 | break; | 70 | break; |
| 71 | } | 71 | } |
| 72 | if (ls->sb.n) { /* Append to buffer. */ | 72 | if (sbuflen(&ls->sb)) { /* Append to buffer. */ |
| 73 | MSize n = ls->sb.n + (MSize)size; | 73 | MSize n = sbuflen(&ls->sb) + (MSize)size; |
| 74 | char *p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); | 74 | char *p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); |
| 75 | memcpy(p + ls->sb.n, buf, size); | 75 | memcpy(sbufP(&ls->sb), buf, size); |
| 76 | ls->n = ls->sb.n = n; | 76 | setsbufP(&ls->sb, sbufB(&ls->sb) + n); |
| 77 | ls->n = n; | ||
| 77 | ls->p = p; | 78 | ls->p = p; |
| 78 | } else { /* Return buffer provided by reader. */ | 79 | } else { /* Return buffer provided by reader. */ |
| 79 | ls->n = (MSize)size; | 80 | ls->n = (MSize)size; |
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index 474234c5..71c86581 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c | |||
| @@ -32,76 +32,44 @@ typedef struct BCWriteCtx { | |||
| 32 | int status; /* Status from writer callback. */ | 32 | int status; /* Status from writer callback. */ |
| 33 | } BCWriteCtx; | 33 | } BCWriteCtx; |
| 34 | 34 | ||
| 35 | /* -- Output buffer handling ---------------------------------------------- */ | ||
| 36 | |||
| 37 | /* Ensure a certain amount of buffer space. */ | ||
| 38 | static LJ_AINLINE void bcwrite_need(BCWriteCtx *ctx, MSize len) | ||
| 39 | { | ||
| 40 | lj_buf_need(ctx->L, &ctx->sb, ctx->sb.n + len); | ||
| 41 | } | ||
| 42 | |||
| 43 | /* Add memory block to buffer. */ | ||
| 44 | static void bcwrite_block(BCWriteCtx *ctx, const void *p, MSize len) | ||
| 45 | { | ||
| 46 | uint8_t *q = (uint8_t *)(ctx->sb.buf + ctx->sb.n); | ||
| 47 | MSize i; | ||
| 48 | ctx->sb.n += len; | ||
| 49 | for (i = 0; i < len; i++) q[i] = ((uint8_t *)p)[i]; | ||
| 50 | } | ||
| 51 | |||
| 52 | /* Add byte to buffer. */ | ||
| 53 | static LJ_AINLINE void bcwrite_byte(BCWriteCtx *ctx, uint8_t b) | ||
| 54 | { | ||
| 55 | ctx->sb.buf[ctx->sb.n++] = b; | ||
| 56 | } | ||
| 57 | |||
| 58 | /* Add ULEB128 value to buffer. */ | ||
| 59 | static void bcwrite_uleb128(BCWriteCtx *ctx, uint32_t v) | ||
| 60 | { | ||
| 61 | MSize n = ctx->sb.n; | ||
| 62 | uint8_t *p = (uint8_t *)ctx->sb.buf; | ||
| 63 | for (; v >= 0x80; v >>= 7) | ||
| 64 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
| 65 | p[n++] = (uint8_t)v; | ||
| 66 | ctx->sb.n = n; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* -- Bytecode writer ----------------------------------------------------- */ | 35 | /* -- Bytecode writer ----------------------------------------------------- */ |
| 70 | 36 | ||
| 71 | /* Write a single constant key/value of a template table. */ | 37 | /* Write a single constant key/value of a template table. */ |
| 72 | static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) | 38 | static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) |
| 73 | { | 39 | { |
| 74 | bcwrite_need(ctx, 1+10); | 40 | char *p = lj_buf_more(ctx->L, &ctx->sb, 1+10); |
| 75 | if (tvisstr(o)) { | 41 | if (tvisstr(o)) { |
| 76 | const GCstr *str = strV(o); | 42 | const GCstr *str = strV(o); |
| 77 | MSize len = str->len; | 43 | MSize len = str->len; |
| 78 | bcwrite_need(ctx, 5+len); | 44 | p = lj_buf_more(ctx->L, &ctx->sb, 5+len); |
| 79 | bcwrite_uleb128(ctx, BCDUMP_KTAB_STR+len); | 45 | p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len); |
| 80 | bcwrite_block(ctx, strdata(str), len); | 46 | p = lj_buf_wmem(p, strdata(str), len); |
| 81 | } else if (tvisint(o)) { | 47 | } else if (tvisint(o)) { |
| 82 | bcwrite_byte(ctx, BCDUMP_KTAB_INT); | 48 | *p++ = BCDUMP_KTAB_INT; |
| 83 | bcwrite_uleb128(ctx, intV(o)); | 49 | p = lj_buf_wuleb128(p, intV(o)); |
| 84 | } else if (tvisnum(o)) { | 50 | } else if (tvisnum(o)) { |
| 85 | if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */ | 51 | if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */ |
| 86 | lua_Number num = numV(o); | 52 | lua_Number num = numV(o); |
| 87 | int32_t k = lj_num2int(num); | 53 | int32_t k = lj_num2int(num); |
| 88 | if (num == (lua_Number)k) { /* -0 is never a constant. */ | 54 | if (num == (lua_Number)k) { /* -0 is never a constant. */ |
| 89 | bcwrite_byte(ctx, BCDUMP_KTAB_INT); | 55 | *p++ = BCDUMP_KTAB_INT; |
| 90 | bcwrite_uleb128(ctx, k); | 56 | p = lj_buf_wuleb128(p, k); |
| 57 | setsbufP(&ctx->sb, p); | ||
| 91 | return; | 58 | return; |
| 92 | } | 59 | } |
| 93 | } | 60 | } |
| 94 | bcwrite_byte(ctx, BCDUMP_KTAB_NUM); | 61 | *p++ = BCDUMP_KTAB_NUM; |
| 95 | bcwrite_uleb128(ctx, o->u32.lo); | 62 | p = lj_buf_wuleb128(p, o->u32.lo); |
| 96 | bcwrite_uleb128(ctx, o->u32.hi); | 63 | p = lj_buf_wuleb128(p, o->u32.hi); |
| 97 | } else { | 64 | } else { |
| 98 | lua_assert(tvispri(o)); | 65 | lua_assert(tvispri(o)); |
| 99 | bcwrite_byte(ctx, BCDUMP_KTAB_NIL+~itype(o)); | 66 | *p++ = BCDUMP_KTAB_NIL+~itype(o); |
| 100 | } | 67 | } |
| 68 | setsbufP(&ctx->sb, p); | ||
| 101 | } | 69 | } |
| 102 | 70 | ||
| 103 | /* Write a template table. */ | 71 | /* Write a template table. */ |
| 104 | static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t) | 72 | static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t) |
| 105 | { | 73 | { |
| 106 | MSize narray = 0, nhash = 0; | 74 | MSize narray = 0, nhash = 0; |
| 107 | if (t->asize > 0) { /* Determine max. length of array part. */ | 75 | if (t->asize > 0) { /* Determine max. length of array part. */ |
| @@ -119,8 +87,9 @@ static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t) | |||
| 119 | nhash += !tvisnil(&node[i].val); | 87 | nhash += !tvisnil(&node[i].val); |
| 120 | } | 88 | } |
| 121 | /* Write number of array slots and hash slots. */ | 89 | /* Write number of array slots and hash slots. */ |
| 122 | bcwrite_uleb128(ctx, narray); | 90 | p = lj_buf_wuleb128(p, narray); |
| 123 | bcwrite_uleb128(ctx, nhash); | 91 | p = lj_buf_wuleb128(p, nhash); |
| 92 | setsbufP(&ctx->sb, p); | ||
| 124 | if (narray) { /* Write array entries (may contain nil). */ | 93 | if (narray) { /* Write array entries (may contain nil). */ |
| 125 | MSize i; | 94 | MSize i; |
| 126 | TValue *o = tvref(t->array); | 95 | TValue *o = tvref(t->array); |
| @@ -147,6 +116,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt) | |||
| 147 | for (i = 0; i < sizekgc; i++, kr++) { | 116 | for (i = 0; i < sizekgc; i++, kr++) { |
| 148 | GCobj *o = gcref(*kr); | 117 | GCobj *o = gcref(*kr); |
| 149 | MSize tp, need = 1; | 118 | MSize tp, need = 1; |
| 119 | char *p; | ||
| 150 | /* Determine constant type and needed size. */ | 120 | /* Determine constant type and needed size. */ |
| 151 | if (o->gch.gct == ~LJ_TSTR) { | 121 | if (o->gch.gct == ~LJ_TSTR) { |
| 152 | tp = BCDUMP_KGC_STR + gco2str(o)->len; | 122 | tp = BCDUMP_KGC_STR + gco2str(o)->len; |
| @@ -173,24 +143,26 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt) | |||
| 173 | need = 1+2*5; | 143 | need = 1+2*5; |
| 174 | } | 144 | } |
| 175 | /* Write constant type. */ | 145 | /* Write constant type. */ |
| 176 | bcwrite_need(ctx, need); | 146 | p = lj_buf_more(ctx->L, &ctx->sb, need); |
| 177 | bcwrite_uleb128(ctx, tp); | 147 | p = lj_buf_wuleb128(p, tp); |
| 178 | /* Write constant data (if any). */ | 148 | /* Write constant data (if any). */ |
| 179 | if (tp >= BCDUMP_KGC_STR) { | 149 | if (tp >= BCDUMP_KGC_STR) { |
| 180 | bcwrite_block(ctx, strdata(gco2str(o)), gco2str(o)->len); | 150 | p = lj_buf_wmem(p, strdata(gco2str(o)), gco2str(o)->len); |
| 181 | } else if (tp == BCDUMP_KGC_TAB) { | 151 | } else if (tp == BCDUMP_KGC_TAB) { |
| 182 | bcwrite_ktab(ctx, gco2tab(o)); | 152 | bcwrite_ktab(ctx, p, gco2tab(o)); |
| 153 | continue; | ||
| 183 | #if LJ_HASFFI | 154 | #if LJ_HASFFI |
| 184 | } else if (tp != BCDUMP_KGC_CHILD) { | 155 | } else if (tp != BCDUMP_KGC_CHILD) { |
| 185 | cTValue *p = (TValue *)cdataptr(gco2cd(o)); | 156 | cTValue *q = (TValue *)cdataptr(gco2cd(o)); |
| 186 | bcwrite_uleb128(ctx, p[0].u32.lo); | 157 | p = lj_buf_wuleb128(p, q[0].u32.lo); |
| 187 | bcwrite_uleb128(ctx, p[0].u32.hi); | 158 | p = lj_buf_wuleb128(p, q[0].u32.hi); |
| 188 | if (tp == BCDUMP_KGC_COMPLEX) { | 159 | if (tp == BCDUMP_KGC_COMPLEX) { |
| 189 | bcwrite_uleb128(ctx, p[1].u32.lo); | 160 | p = lj_buf_wuleb128(p, q[1].u32.lo); |
| 190 | bcwrite_uleb128(ctx, p[1].u32.hi); | 161 | p = lj_buf_wuleb128(p, q[1].u32.hi); |
| 191 | } | 162 | } |
| 192 | #endif | 163 | #endif |
| 193 | } | 164 | } |
| 165 | setsbufP(&ctx->sb, p); | ||
| 194 | } | 166 | } |
| 195 | } | 167 | } |
| 196 | 168 | ||
| @@ -199,7 +171,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt) | |||
| 199 | { | 171 | { |
| 200 | MSize i, sizekn = pt->sizekn; | 172 | MSize i, sizekn = pt->sizekn; |
| 201 | cTValue *o = mref(pt->k, TValue); | 173 | cTValue *o = mref(pt->k, TValue); |
| 202 | bcwrite_need(ctx, 10*sizekn); | 174 | char *p = lj_buf_more(ctx->L, &ctx->sb, 10*sizekn); |
| 203 | for (i = 0; i < sizekn; i++, o++) { | 175 | for (i = 0; i < sizekn; i++, o++) { |
| 204 | int32_t k; | 176 | int32_t k; |
| 205 | if (tvisint(o)) { | 177 | if (tvisint(o)) { |
| @@ -212,58 +184,58 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt) | |||
| 212 | k = lj_num2int(num); | 184 | k = lj_num2int(num); |
| 213 | if (num == (lua_Number)k) { /* -0 is never a constant. */ | 185 | if (num == (lua_Number)k) { /* -0 is never a constant. */ |
| 214 | save_int: | 186 | save_int: |
| 215 | bcwrite_uleb128(ctx, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u)); | 187 | p = lj_buf_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u)); |
| 216 | if (k < 0) { | 188 | if (k < 0) |
| 217 | char *p = &ctx->sb.buf[ctx->sb.n-1]; | 189 | p[-1] = (p[-1] & 7) | ((k>>27) & 0x18); |
| 218 | *p = (*p & 7) | ((k>>27) & 0x18); | ||
| 219 | } | ||
| 220 | continue; | 190 | continue; |
| 221 | } | 191 | } |
| 222 | } | 192 | } |
| 223 | bcwrite_uleb128(ctx, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u))); | 193 | p = lj_buf_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u))); |
| 224 | if (o->u32.lo >= 0x80000000u) { | 194 | if (o->u32.lo >= 0x80000000u) |
| 225 | char *p = &ctx->sb.buf[ctx->sb.n-1]; | 195 | p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18); |
| 226 | *p = (*p & 7) | ((o->u32.lo>>27) & 0x18); | 196 | p = lj_buf_wuleb128(p, o->u32.hi); |
| 227 | } | ||
| 228 | bcwrite_uleb128(ctx, o->u32.hi); | ||
| 229 | } | 197 | } |
| 230 | } | 198 | } |
| 199 | setsbufP(&ctx->sb, p); | ||
| 231 | } | 200 | } |
| 232 | 201 | ||
| 233 | /* Write bytecode instructions. */ | 202 | /* Write bytecode instructions. */ |
| 234 | static void bcwrite_bytecode(BCWriteCtx *ctx, GCproto *pt) | 203 | static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt) |
| 235 | { | 204 | { |
| 236 | MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */ | 205 | MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */ |
| 237 | #if LJ_HASJIT | 206 | #if LJ_HASJIT |
| 238 | uint8_t *p = (uint8_t *)&ctx->sb.buf[ctx->sb.n]; | 207 | uint8_t *q = (uint8_t *)p; |
| 239 | #endif | 208 | #endif |
| 240 | bcwrite_block(ctx, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns)); | 209 | p = lj_buf_wmem(p, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns)); |
| 210 | UNUSED(ctx); | ||
| 241 | #if LJ_HASJIT | 211 | #if LJ_HASJIT |
| 242 | /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ | 212 | /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ |
| 243 | if ((pt->flags & PROTO_ILOOP) || pt->trace) { | 213 | if ((pt->flags & PROTO_ILOOP) || pt->trace) { |
| 244 | jit_State *J = L2J(ctx->L); | 214 | jit_State *J = L2J(ctx->L); |
| 245 | MSize i; | 215 | MSize i; |
| 246 | for (i = 0; i < nbc; i++, p += sizeof(BCIns)) { | 216 | for (i = 0; i < nbc; i++, q += sizeof(BCIns)) { |
| 247 | BCOp op = (BCOp)p[LJ_ENDIAN_SELECT(0, 3)]; | 217 | BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)]; |
| 248 | if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP || | 218 | if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP || |
| 249 | op == BC_JFORI) { | 219 | op == BC_JFORI) { |
| 250 | p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL); | 220 | q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL); |
| 251 | } else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) { | 221 | } else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) { |
| 252 | BCReg rd = p[LJ_ENDIAN_SELECT(2, 1)] + (p[LJ_ENDIAN_SELECT(3, 0)] << 8); | 222 | BCReg rd = q[LJ_ENDIAN_SELECT(2, 1)] + (q[LJ_ENDIAN_SELECT(3, 0)] << 8); |
| 253 | BCIns ins = traceref(J, rd)->startins; | 223 | BCIns ins = traceref(J, rd)->startins; |
| 254 | p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL); | 224 | q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL); |
| 255 | p[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins); | 225 | q[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins); |
| 256 | p[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins); | 226 | q[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins); |
| 257 | } | 227 | } |
| 258 | } | 228 | } |
| 259 | } | 229 | } |
| 260 | #endif | 230 | #endif |
| 231 | return p; | ||
| 261 | } | 232 | } |
| 262 | 233 | ||
| 263 | /* Write prototype. */ | 234 | /* Write prototype. */ |
| 264 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | 235 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) |
| 265 | { | 236 | { |
| 266 | MSize sizedbg = 0; | 237 | MSize sizedbg = 0; |
| 238 | char *p; | ||
| 267 | 239 | ||
| 268 | /* Recursively write children of prototype. */ | 240 | /* Recursively write children of prototype. */ |
| 269 | if ((pt->flags & PROTO_CHILD)) { | 241 | if ((pt->flags & PROTO_CHILD)) { |
| @@ -277,31 +249,32 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
| 277 | } | 249 | } |
| 278 | 250 | ||
| 279 | /* Start writing the prototype info to a buffer. */ | 251 | /* Start writing the prototype info to a buffer. */ |
| 280 | lj_buf_reset(&ctx->sb); | 252 | p = lj_buf_need(ctx->L, &ctx->sb, |
| 281 | ctx->sb.n = 5; /* Leave room for final size. */ | 253 | 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); |
| 282 | bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); | 254 | p += 5; /* Leave room for final size. */ |
| 283 | 255 | ||
| 284 | /* Write prototype header. */ | 256 | /* Write prototype header. */ |
| 285 | bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI))); | 257 | *p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)); |
| 286 | bcwrite_byte(ctx, pt->numparams); | 258 | *p++ = pt->numparams; |
| 287 | bcwrite_byte(ctx, pt->framesize); | 259 | *p++ = pt->framesize; |
| 288 | bcwrite_byte(ctx, pt->sizeuv); | 260 | *p++ = pt->sizeuv; |
| 289 | bcwrite_uleb128(ctx, pt->sizekgc); | 261 | p = lj_buf_wuleb128(p, pt->sizekgc); |
| 290 | bcwrite_uleb128(ctx, pt->sizekn); | 262 | p = lj_buf_wuleb128(p, pt->sizekn); |
| 291 | bcwrite_uleb128(ctx, pt->sizebc-1); | 263 | p = lj_buf_wuleb128(p, pt->sizebc-1); |
| 292 | if (!ctx->strip) { | 264 | if (!ctx->strip) { |
| 293 | if (proto_lineinfo(pt)) | 265 | if (proto_lineinfo(pt)) |
| 294 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); | 266 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); |
| 295 | bcwrite_uleb128(ctx, sizedbg); | 267 | p = lj_buf_wuleb128(p, sizedbg); |
| 296 | if (sizedbg) { | 268 | if (sizedbg) { |
| 297 | bcwrite_uleb128(ctx, pt->firstline); | 269 | p = lj_buf_wuleb128(p, pt->firstline); |
| 298 | bcwrite_uleb128(ctx, pt->numline); | 270 | p = lj_buf_wuleb128(p, pt->numline); |
| 299 | } | 271 | } |
| 300 | } | 272 | } |
| 301 | 273 | ||
| 302 | /* Write bytecode instructions and upvalue refs. */ | 274 | /* Write bytecode instructions and upvalue refs. */ |
| 303 | bcwrite_bytecode(ctx, pt); | 275 | p = bcwrite_bytecode(ctx, p, pt); |
| 304 | bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2); | 276 | p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2); |
| 277 | setsbufP(&ctx->sb, p); | ||
| 305 | 278 | ||
| 306 | /* Write constants. */ | 279 | /* Write constants. */ |
| 307 | bcwrite_kgc(ctx, pt); | 280 | bcwrite_kgc(ctx, pt); |
| @@ -309,18 +282,19 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
| 309 | 282 | ||
| 310 | /* Write debug info, if not stripped. */ | 283 | /* Write debug info, if not stripped. */ |
| 311 | if (sizedbg) { | 284 | if (sizedbg) { |
| 312 | bcwrite_need(ctx, sizedbg); | 285 | p = lj_buf_more(ctx->L, &ctx->sb, sizedbg); |
| 313 | bcwrite_block(ctx, proto_lineinfo(pt), sizedbg); | 286 | p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); |
| 287 | setsbufP(&ctx->sb, p); | ||
| 314 | } | 288 | } |
| 315 | 289 | ||
| 316 | /* Pass buffer to writer function. */ | 290 | /* Pass buffer to writer function. */ |
| 317 | if (ctx->status == 0) { | 291 | if (ctx->status == 0) { |
| 318 | MSize n = ctx->sb.n - 5; | 292 | MSize n = sbuflen(&ctx->sb) - 5; |
| 319 | MSize nn = (lj_fls(n)+8)*9 >> 6; | 293 | MSize nn = (lj_fls(n)+8)*9 >> 6; |
| 320 | ctx->sb.n = 5 - nn; | 294 | char *q = sbufB(&ctx->sb) + (5 - nn); |
| 321 | bcwrite_uleb128(ctx, n); /* Fill in final size. */ | 295 | p = lj_buf_wuleb128(q, n); /* Fill in final size. */ |
| 322 | lua_assert(ctx->sb.n == 5); | 296 | lua_assert(p == sbufB(&ctx->sb) + 5); |
| 323 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata); | 297 | ctx->status = ctx->wfunc(ctx->L, q, nn+n, ctx->wdata); |
| 324 | } | 298 | } |
| 325 | } | 299 | } |
| 326 | 300 | ||
| @@ -330,20 +304,20 @@ static void bcwrite_header(BCWriteCtx *ctx) | |||
| 330 | GCstr *chunkname = proto_chunkname(ctx->pt); | 304 | GCstr *chunkname = proto_chunkname(ctx->pt); |
| 331 | const char *name = strdata(chunkname); | 305 | const char *name = strdata(chunkname); |
| 332 | MSize len = chunkname->len; | 306 | MSize len = chunkname->len; |
| 333 | lj_buf_reset(&ctx->sb); | 307 | char *p = lj_buf_need(ctx->L, &ctx->sb, 5+5+len); |
| 334 | bcwrite_need(ctx, 5+5+len); | 308 | *p++ = BCDUMP_HEAD1; |
| 335 | bcwrite_byte(ctx, BCDUMP_HEAD1); | 309 | *p++ = BCDUMP_HEAD2; |
| 336 | bcwrite_byte(ctx, BCDUMP_HEAD2); | 310 | *p++ = BCDUMP_HEAD3; |
| 337 | bcwrite_byte(ctx, BCDUMP_HEAD3); | 311 | *p++ = BCDUMP_VERSION; |
| 338 | bcwrite_byte(ctx, BCDUMP_VERSION); | 312 | *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) + |
| 339 | bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) + | 313 | (LJ_BE ? BCDUMP_F_BE : 0) + |
| 340 | (LJ_BE ? BCDUMP_F_BE : 0) + | 314 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0); |
| 341 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0)); | ||
| 342 | if (!ctx->strip) { | 315 | if (!ctx->strip) { |
| 343 | bcwrite_uleb128(ctx, len); | 316 | p = lj_buf_wuleb128(p, len); |
| 344 | bcwrite_block(ctx, name, len); | 317 | p = lj_buf_wmem(p, name, len); |
| 345 | } | 318 | } |
| 346 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata); | 319 | ctx->status = ctx->wfunc(ctx->L, sbufB(&ctx->sb), |
| 320 | (MSize)(p - sbufB(&ctx->sb)), ctx->wdata); | ||
| 347 | } | 321 | } |
| 348 | 322 | ||
| 349 | /* Write footer of bytecode dump. */ | 323 | /* Write footer of bytecode dump. */ |
| @@ -360,7 +334,7 @@ static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 360 | { | 334 | { |
| 361 | BCWriteCtx *ctx = (BCWriteCtx *)ud; | 335 | BCWriteCtx *ctx = (BCWriteCtx *)ud; |
| 362 | UNUSED(dummy); | 336 | UNUSED(dummy); |
| 363 | lj_buf_grow(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ | 337 | lj_buf_need(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ |
| 364 | bcwrite_header(ctx); | 338 | bcwrite_header(ctx); |
| 365 | bcwrite_proto(ctx, ctx->pt); | 339 | bcwrite_proto(ctx, ctx->pt); |
| 366 | bcwrite_footer(ctx); | 340 | bcwrite_footer(ctx); |
diff --git a/src/lj_buf.c b/src/lj_buf.c index 5d901d2a..a05dc22e 100644 --- a/src/lj_buf.c +++ b/src/lj_buf.c | |||
| @@ -13,15 +13,20 @@ | |||
| 13 | #include "lj_err.h" | 13 | #include "lj_err.h" |
| 14 | #include "lj_buf.h" | 14 | #include "lj_buf.h" |
| 15 | 15 | ||
| 16 | LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, MSize sz) | 16 | LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, char *en) |
| 17 | { | 17 | { |
| 18 | MSize bsz = sb->sz * 2; | 18 | char *b = sbufB(sb); |
| 19 | MSize sz = (MSize)(en - b); | ||
| 20 | MSize osz = (MSize)(sbufE(sb) - b), nsz = osz; | ||
| 21 | MSize n = (MSize)(sbufP(sb) - b); | ||
| 19 | if (LJ_UNLIKELY(sz > LJ_MAX_MEM)) | 22 | if (LJ_UNLIKELY(sz > LJ_MAX_MEM)) |
| 20 | lj_err_mem(L); | 23 | lj_err_mem(L); |
| 21 | if (bsz < LJ_MIN_SBUF) bsz = LJ_MIN_SBUF; | 24 | if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF; |
| 22 | while (bsz < sz) bsz += bsz; | 25 | while (nsz < sz) nsz += nsz; |
| 23 | sb->buf = lj_mem_realloc(L, sb->buf, sb->sz, bsz); | 26 | b = (char *)lj_mem_realloc(L, b, osz, nsz); |
| 24 | sb->sz = bsz; | 27 | setmref(sb->b, b); |
| 28 | setmref(sb->p, b + n); | ||
| 29 | setmref(sb->e, b + nsz); | ||
| 25 | } | 30 | } |
| 26 | 31 | ||
| 27 | char *lj_buf_tmp(lua_State *L, MSize sz) | 32 | char *lj_buf_tmp(lua_State *L, MSize sz) |
| @@ -31,10 +36,49 @@ char *lj_buf_tmp(lua_State *L, MSize sz) | |||
| 31 | 36 | ||
| 32 | void lj_buf_shrink(lua_State *L, SBuf *sb) | 37 | void lj_buf_shrink(lua_State *L, SBuf *sb) |
| 33 | { | 38 | { |
| 34 | MSize sz = sb->sz; | 39 | char *b = sbufB(sb); |
| 35 | if (sz > 2*LJ_MIN_SBUF) { | 40 | MSize osz = (MSize)(sbufE(sb) - b); |
| 36 | sb->buf = lj_mem_realloc(L, sb->buf, sz, (sz >> 1)); | 41 | if (osz > 2*LJ_MIN_SBUF) { |
| 37 | sb->sz = (sz >> 1); | 42 | MSize n = (MSize)(sbufP(sb) - b); |
| 43 | b = lj_mem_realloc(L, b, osz, (osz >> 1)); | ||
| 44 | setmref(sb->b, b); | ||
| 45 | setmref(sb->p, b + n); | ||
| 46 | setmref(sb->e, b + (osz >> 1)); | ||
| 38 | } | 47 | } |
| 39 | } | 48 | } |
| 40 | 49 | ||
| 50 | char *lj_buf_wmem(char *p, const void *q, MSize len) | ||
| 51 | { | ||
| 52 | const char *s = (const char *)q, *e = s + len; | ||
| 53 | while (s < e) *p++ = *s++; | ||
| 54 | return p; | ||
| 55 | } | ||
| 56 | |||
| 57 | void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len) | ||
| 58 | { | ||
| 59 | char *p = lj_buf_more(L, sb, len); | ||
| 60 | p = lj_buf_wmem(p, q, len); | ||
| 61 | setsbufP(sb, p); | ||
| 62 | } | ||
| 63 | |||
| 64 | uint32_t lj_buf_ruleb128(const char **pp) | ||
| 65 | { | ||
| 66 | const uint8_t *p = (const uint8_t *)*pp; | ||
| 67 | uint32_t v = *p++; | ||
| 68 | if (LJ_UNLIKELY(v >= 0x80)) { | ||
| 69 | int sh = 0; | ||
| 70 | v &= 0x7f; | ||
| 71 | do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80); | ||
| 72 | } | ||
| 73 | *pp = (const char *)p; | ||
| 74 | return v; | ||
| 75 | } | ||
| 76 | |||
| 77 | char *lj_buf_wuleb128(char *p, uint32_t v) | ||
| 78 | { | ||
| 79 | for (; v >= 0x80; v >>= 7) | ||
| 80 | *p++ = (char)((v & 0x7f) | 0x80); | ||
| 81 | *p++ = (char)v; | ||
| 82 | return p; | ||
| 83 | } | ||
| 84 | |||
diff --git a/src/lj_buf.h b/src/lj_buf.h index 19f2bb0d..5a7eae31 100644 --- a/src/lj_buf.h +++ b/src/lj_buf.h | |||
| @@ -7,21 +7,67 @@ | |||
| 7 | #define _LJ_BUF_H | 7 | #define _LJ_BUF_H |
| 8 | 8 | ||
| 9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
| 10 | #include "lj_gc.h" | ||
| 11 | #include "lj_str.h" | ||
| 10 | 12 | ||
| 11 | /* Resizable string buffers. Struct definition in lj_obj.h. */ | 13 | /* Resizable string buffers. Struct definition in lj_obj.h. */ |
| 14 | #define sbufB(sb) (mref((sb)->b, char)) | ||
| 15 | #define sbufP(sb) (mref((sb)->p, char)) | ||
| 16 | #define sbufE(sb) (mref((sb)->e, char)) | ||
| 17 | #define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb)))) | ||
| 18 | #define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb)))) | ||
| 19 | #define setsbufP(sb, q) (setmref((sb)->p, (q))) | ||
| 20 | |||
| 12 | LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz); | 21 | LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz); |
| 13 | LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, MSize sz); | 22 | LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, char *en); |
| 14 | LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb); | 23 | LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb); |
| 15 | 24 | ||
| 16 | #define lj_buf_init(sb) ((sb)->buf = NULL, (sb)->sz = 0) | 25 | LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len); |
| 17 | #define lj_buf_reset(sb) ((sb)->n = 0) | 26 | LJ_FUNC void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len); |
| 18 | #define lj_buf_free(g, sb) lj_mem_free(g, (void *)(sb)->buf, (sb)->sz) | 27 | LJ_FUNC uint32_t lj_buf_ruleb128(const char **pp); |
| 28 | LJ_FUNC char *lj_buf_wuleb128(char *p, uint32_t v); | ||
| 29 | |||
| 30 | static LJ_AINLINE void lj_buf_init(SBuf *sb) | ||
| 31 | { | ||
| 32 | setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL); | ||
| 33 | } | ||
| 34 | |||
| 35 | static LJ_AINLINE void lj_buf_reset(SBuf *sb) | ||
| 36 | { | ||
| 37 | setmrefr(sb->p, sb->b); | ||
| 38 | } | ||
| 39 | |||
| 40 | static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb) | ||
| 41 | { | ||
| 42 | lj_mem_free(g, sbufB(sb), sbufsz(sb)); | ||
| 43 | } | ||
| 44 | |||
| 45 | static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb) | ||
| 46 | { | ||
| 47 | return lj_str_new(L, sbufB(sb), sbuflen(sb)); | ||
| 48 | } | ||
| 19 | 49 | ||
| 20 | static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz) | 50 | static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz) |
| 21 | { | 51 | { |
| 22 | if (LJ_UNLIKELY(sz > sb->sz)) | 52 | char *en = sbufB(sb) + sz; |
| 23 | lj_buf_grow(L, sb, sz); | 53 | if (LJ_UNLIKELY(en > sbufE(sb))) |
| 24 | return sb->buf; | 54 | lj_buf_grow(L, sb, en); |
| 55 | return sbufB(sb); | ||
| 56 | } | ||
| 57 | |||
| 58 | static LJ_AINLINE char *lj_buf_more(lua_State *L, SBuf *sb, MSize sz) | ||
| 59 | { | ||
| 60 | char *en = sbufP(sb) + sz; | ||
| 61 | if (LJ_UNLIKELY(en > sbufE(sb))) | ||
| 62 | lj_buf_grow(L, sb, en); | ||
| 63 | return sbufP(sb); | ||
| 64 | } | ||
| 65 | |||
| 66 | static LJ_AINLINE void lj_buf_putb(lua_State *L, SBuf *sb, int c) | ||
| 67 | { | ||
| 68 | char *p = lj_buf_more(L, sb, 1); | ||
| 69 | *p++ = (char)c; | ||
| 70 | setsbufP(sb, p); | ||
| 25 | } | 71 | } |
| 26 | 72 | ||
| 27 | #endif | 73 | #endif |
diff --git a/src/lj_cparse.c b/src/lj_cparse.c index b88ce5d3..b8e31820 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c | |||
| @@ -86,22 +86,10 @@ static LJ_AINLINE CPChar cp_get(CPState *cp) | |||
| 86 | return cp_get_bs(cp); | 86 | return cp_get_bs(cp); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /* Grow save buffer. */ | ||
| 90 | static LJ_NOINLINE void cp_save_grow(CPState *cp, CPChar c) | ||
| 91 | { | ||
| 92 | if (cp->sb.sz >= CPARSE_MAX_BUF/2) | ||
| 93 | cp_err(cp, LJ_ERR_XELEM); | ||
| 94 | lj_buf_grow(cp->L, &cp->sb, 0); | ||
| 95 | cp->sb.buf[cp->sb.n++] = (char)c; | ||
| 96 | } | ||
| 97 | |||
| 98 | /* Save character in buffer. */ | 89 | /* Save character in buffer. */ |
| 99 | static LJ_AINLINE void cp_save(CPState *cp, CPChar c) | 90 | static LJ_AINLINE void cp_save(CPState *cp, CPChar c) |
| 100 | { | 91 | { |
| 101 | if (LJ_UNLIKELY(cp->sb.n + 1 > cp->sb.sz)) | 92 | lj_buf_putb(cp->L, &cp->sb, c); |
| 102 | cp_save_grow(cp, c); | ||
| 103 | else | ||
| 104 | cp->sb.buf[cp->sb.n++] = (char)c; | ||
| 105 | } | 93 | } |
| 106 | 94 | ||
| 107 | /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ | 95 | /* 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, ...) | |||
| 121 | tokstr = NULL; | 109 | tokstr = NULL; |
| 122 | } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || | 110 | } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || |
| 123 | tok >= CTOK_FIRSTDECL) { | 111 | tok >= CTOK_FIRSTDECL) { |
| 124 | if (cp->sb.n == 0) cp_save(cp, '$'); | 112 | if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$'); |
| 125 | cp_save(cp, '\0'); | 113 | cp_save(cp, '\0'); |
| 126 | tokstr = cp->sb.buf; | 114 | tokstr = sbufB(&cp->sb); |
| 127 | } else { | 115 | } else { |
| 128 | tokstr = cp_tok2str(cp, tok); | 116 | tokstr = cp_tok2str(cp, tok); |
| 129 | } | 117 | } |
| @@ -163,7 +151,7 @@ static CPToken cp_number(CPState *cp) | |||
| 163 | TValue o; | 151 | TValue o; |
| 164 | do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); | 152 | do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); |
| 165 | cp_save(cp, '\0'); | 153 | cp_save(cp, '\0'); |
| 166 | fmt = lj_strscan_scan((const uint8_t *)cp->sb.buf, &o, STRSCAN_OPT_C); | 154 | fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C); |
| 167 | if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; | 155 | if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; |
| 168 | else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; | 156 | else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; |
| 169 | else if (!(cp->mode & CPARSE_MODE_SKIP)) | 157 | else if (!(cp->mode & CPARSE_MODE_SKIP)) |
| @@ -176,7 +164,7 @@ static CPToken cp_number(CPState *cp) | |||
| 176 | static CPToken cp_ident(CPState *cp) | 164 | static CPToken cp_ident(CPState *cp) |
| 177 | { | 165 | { |
| 178 | do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); | 166 | do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); |
| 179 | cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n); | 167 | cp->str = lj_buf_str(cp->L, &cp->sb); |
| 180 | cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask); | 168 | cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask); |
| 181 | if (ctype_type(cp->ct->info) == CT_KW) | 169 | if (ctype_type(cp->ct->info) == CT_KW) |
| 182 | return ctype_cid(cp->ct->info); | 170 | return ctype_cid(cp->ct->info); |
| @@ -262,11 +250,11 @@ static CPToken cp_string(CPState *cp) | |||
| 262 | } | 250 | } |
| 263 | cp_get(cp); | 251 | cp_get(cp); |
| 264 | if (delim == '"') { | 252 | if (delim == '"') { |
| 265 | cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n); | 253 | cp->str = lj_buf_str(cp->L, &cp->sb); |
| 266 | return CTOK_STRING; | 254 | return CTOK_STRING; |
| 267 | } else { | 255 | } else { |
| 268 | if (cp->sb.n != 1) cp_err_token(cp, '\''); | 256 | if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\''); |
| 269 | cp->val.i32 = (int32_t)(char)cp->sb.buf[0]; | 257 | cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb); |
| 270 | cp->val.id = CTID_INT32; | 258 | cp->val.id = CTID_INT32; |
| 271 | return CTOK_INTEGER; | 259 | return CTOK_INTEGER; |
| 272 | } | 260 | } |
diff --git a/src/lj_debug.c b/src/lj_debug.c index ec56b7d2..3f502864 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
| 10 | #include "lj_err.h" | 10 | #include "lj_err.h" |
| 11 | #include "lj_debug.h" | 11 | #include "lj_debug.h" |
| 12 | #include "lj_buf.h" | ||
| 12 | #include "lj_str.h" | 13 | #include "lj_str.h" |
| 13 | #include "lj_tab.h" | 14 | #include "lj_tab.h" |
| 14 | #include "lj_state.h" | 15 | #include "lj_state.h" |
| @@ -133,20 +134,6 @@ static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe) | |||
| 133 | 134 | ||
| 134 | /* -- Variable names ------------------------------------------------------ */ | 135 | /* -- Variable names ------------------------------------------------------ */ |
| 135 | 136 | ||
| 136 | /* Read ULEB128 value. */ | ||
| 137 | static uint32_t debug_read_uleb128(const uint8_t **pp) | ||
| 138 | { | ||
| 139 | const uint8_t *p = *pp; | ||
| 140 | uint32_t v = *p++; | ||
| 141 | if (LJ_UNLIKELY(v >= 0x80)) { | ||
| 142 | int sh = 0; | ||
| 143 | v &= 0x7f; | ||
| 144 | do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80); | ||
| 145 | } | ||
| 146 | *pp = p; | ||
| 147 | return v; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* Get name of a local variable from slot number and PC. */ | 137 | /* Get name of a local variable from slot number and PC. */ |
| 151 | static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot) | 138 | static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot) |
| 152 | { | 139 | { |
| @@ -162,9 +149,9 @@ static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot) | |||
| 162 | } else { | 149 | } else { |
| 163 | while (*p++) ; /* Skip over variable name string. */ | 150 | while (*p++) ; /* Skip over variable name string. */ |
| 164 | } | 151 | } |
| 165 | lastpc = startpc = lastpc + debug_read_uleb128(&p); | 152 | lastpc = startpc = lastpc + lj_buf_ruleb128((const char **)&p); |
| 166 | if (startpc > pc) break; | 153 | if (startpc > pc) break; |
| 167 | endpc = startpc + debug_read_uleb128(&p); | 154 | endpc = startpc + lj_buf_ruleb128((const char **)&p); |
| 168 | if (pc < endpc && slot-- == 0) { | 155 | if (pc < endpc && slot-- == 0) { |
| 169 | if (vn < VARNAME__MAX) { | 156 | if (vn < VARNAME__MAX) { |
| 170 | #define VARNAMESTR(name, str) str "\0" | 157 | #define VARNAMESTR(name, str) str "\0" |
diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index 284195a1..334a906e 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
| 15 | #include "lj_debug.h" | 15 | #include "lj_debug.h" |
| 16 | #include "lj_frame.h" | 16 | #include "lj_frame.h" |
| 17 | #include "lj_buf.h" | ||
| 17 | #include "lj_jit.h" | 18 | #include "lj_jit.h" |
| 18 | #include "lj_dispatch.h" | 19 | #include "lj_dispatch.h" |
| 19 | 20 | ||
| @@ -426,16 +427,6 @@ static void gdbjit_catnum(GDBJITctx *ctx, uint32_t n) | |||
| 426 | *ctx->p++ = '0' + n; | 427 | *ctx->p++ = '0' + n; |
| 427 | } | 428 | } |
| 428 | 429 | ||
| 429 | /* Add a ULEB128 value. */ | ||
| 430 | static void gdbjit_uleb128(GDBJITctx *ctx, uint32_t v) | ||
| 431 | { | ||
| 432 | uint8_t *p = ctx->p; | ||
| 433 | for (; v >= 0x80; v >>= 7) | ||
| 434 | *p++ = (uint8_t)((v & 0x7f) | 0x80); | ||
| 435 | *p++ = (uint8_t)v; | ||
| 436 | ctx->p = p; | ||
| 437 | } | ||
| 438 | |||
| 439 | /* Add a SLEB128 value. */ | 430 | /* Add a SLEB128 value. */ |
| 440 | static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) | 431 | static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) |
| 441 | { | 432 | { |
| @@ -452,7 +443,7 @@ static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) | |||
| 452 | #define DU16(x) (*(uint16_t *)p = (x), p += 2) | 443 | #define DU16(x) (*(uint16_t *)p = (x), p += 2) |
| 453 | #define DU32(x) (*(uint32_t *)p = (x), p += 4) | 444 | #define DU32(x) (*(uint32_t *)p = (x), p += 4) |
| 454 | #define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t)) | 445 | #define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t)) |
| 455 | #define DUV(x) (ctx->p = p, gdbjit_uleb128(ctx, (x)), p = ctx->p) | 446 | #define DUV(x) (p = (uint8_t *)lj_buf_wuleb128((char *)p, (x))) |
| 456 | #define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p) | 447 | #define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p) |
| 457 | #define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p) | 448 | #define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p) |
| 458 | #define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop | 449 | #define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop |
diff --git a/src/lj_lex.c b/src/lj_lex.c index 3227cadd..c4d52da2 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "lj_obj.h" | 12 | #include "lj_obj.h" |
| 13 | #include "lj_gc.h" | 13 | #include "lj_gc.h" |
| 14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
| 15 | #include "lj_buf.h" | ||
| 15 | #include "lj_str.h" | 16 | #include "lj_str.h" |
| 16 | #if LJ_HASFFI | 17 | #if LJ_HASFFI |
| 17 | #include "lj_tab.h" | 18 | #include "lj_tab.h" |
| @@ -54,20 +55,9 @@ static int fillbuf(LexState *ls) | |||
| 54 | return char2int(*(ls->p++)); | 55 | return char2int(*(ls->p++)); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | static LJ_NOINLINE void save_grow(LexState *ls, int c) | ||
| 58 | { | ||
| 59 | if (ls->sb.sz >= LJ_MAX_STR/2) | ||
| 60 | lj_lex_error(ls, 0, LJ_ERR_XELEM); | ||
| 61 | lj_buf_grow(ls->L, &ls->sb, 0); | ||
| 62 | ls->sb.buf[ls->sb.n++] = (char)c; | ||
| 63 | } | ||
| 64 | |||
| 65 | static LJ_AINLINE void save(LexState *ls, int c) | 58 | static LJ_AINLINE void save(LexState *ls, int c) |
| 66 | { | 59 | { |
| 67 | if (LJ_UNLIKELY(ls->sb.n + 1 > ls->sb.sz)) | 60 | lj_buf_putb(ls->L, &ls->sb, c); |
| 68 | save_grow(ls, c); | ||
| 69 | else | ||
| 70 | ls->sb.buf[ls->sb.n++] = (char)c; | ||
| 71 | } | 61 | } |
| 72 | 62 | ||
| 73 | static void inclinenumber(LexState *ls) | 63 | static void inclinenumber(LexState *ls) |
| @@ -99,7 +89,7 @@ static void lex_number(LexState *ls, TValue *tv) | |||
| 99 | save_and_next(ls); | 89 | save_and_next(ls); |
| 100 | } | 90 | } |
| 101 | save(ls, '\0'); | 91 | save(ls, '\0'); |
| 102 | fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv, | 92 | fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv, |
| 103 | (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | | 93 | (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | |
| 104 | (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); | 94 | (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); |
| 105 | if (LJ_DUALNUM && fmt == STRSCAN_INT) { | 95 | if (LJ_DUALNUM && fmt == STRSCAN_INT) { |
| @@ -174,8 +164,8 @@ static void read_long_string(LexState *ls, TValue *tv, int sep) | |||
| 174 | } | 164 | } |
| 175 | } endloop: | 165 | } endloop: |
| 176 | if (tv) { | 166 | if (tv) { |
| 177 | GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep), | 167 | GCstr *str = lj_parse_keepstr(ls, sbufB(&ls->sb) + (2 + (MSize)sep), |
| 178 | ls->sb.n - 2*(2 + (MSize)sep)); | 168 | sbuflen(&ls->sb) - 2*(2 + (MSize)sep)); |
| 179 | setstrV(ls->L, tv, str); | 169 | setstrV(ls->L, tv, str); |
| 180 | } | 170 | } |
| 181 | } | 171 | } |
| @@ -250,7 +240,8 @@ static void read_string(LexState *ls, int delim, TValue *tv) | |||
| 250 | } | 240 | } |
| 251 | } | 241 | } |
| 252 | save_and_next(ls); /* skip delimiter */ | 242 | save_and_next(ls); /* skip delimiter */ |
| 253 | setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2)); | 243 | setstrV(ls->L, tv, |
| 244 | lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2)); | ||
| 254 | } | 245 | } |
| 255 | 246 | ||
| 256 | /* -- Main lexical scanner ------------------------------------------------ */ | 247 | /* -- Main lexical scanner ------------------------------------------------ */ |
| @@ -269,7 +260,7 @@ static int llex(LexState *ls, TValue *tv) | |||
| 269 | do { | 260 | do { |
| 270 | save_and_next(ls); | 261 | save_and_next(ls); |
| 271 | } while (lj_char_isident(ls->current)); | 262 | } while (lj_char_isident(ls->current)); |
| 272 | s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n); | 263 | s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb)); |
| 273 | setstrV(ls->L, tv, s); | 264 | setstrV(ls->L, tv, s); |
| 274 | if (s->reserved > 0) /* Reserved word? */ | 265 | if (s->reserved > 0) /* Reserved word? */ |
| 275 | return TK_OFS + s->reserved; | 266 | return TK_OFS + s->reserved; |
| @@ -457,7 +448,7 @@ void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...) | |||
| 457 | tok = NULL; | 448 | tok = NULL; |
| 458 | } else if (token == TK_name || token == TK_string || token == TK_number) { | 449 | } else if (token == TK_name || token == TK_string || token == TK_number) { |
| 459 | save(ls, '\0'); | 450 | save(ls, '\0'); |
| 460 | tok = ls->sb.buf; | 451 | tok = sbufB(&ls->sb); |
| 461 | } else { | 452 | } else { |
| 462 | tok = lj_lex_token2str(ls, token); | 453 | tok = lj_lex_token2str(ls, token); |
| 463 | } | 454 | } |
diff --git a/src/lj_lex.h b/src/lj_lex.h index 7013f6eb..6e18e4b0 100644 --- a/src/lj_lex.h +++ b/src/lj_lex.h | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | 10 | ||
| 11 | #include "lj_obj.h" | 11 | #include "lj_obj.h" |
| 12 | #include "lj_err.h" | 12 | #include "lj_err.h" |
| 13 | #include "lj_buf.h" | ||
| 14 | 13 | ||
| 15 | /* Lua lexer tokens. */ | 14 | /* Lua lexer tokens. */ |
| 16 | #define TKDEF(_, __) \ | 15 | #define TKDEF(_, __) \ |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 6faedd10..4d7b9262 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
| @@ -121,9 +121,9 @@ typedef void (*ASMFunction)(void); | |||
| 121 | 121 | ||
| 122 | /* Resizable string buffer. Need this here, details in lj_buf.h. */ | 122 | /* Resizable string buffer. Need this here, details in lj_buf.h. */ |
| 123 | typedef struct SBuf { | 123 | typedef struct SBuf { |
| 124 | char *buf; /* String buffer base. */ | 124 | MRef p; /* String buffer pointer. */ |
| 125 | MSize n; /* String buffer length. */ | 125 | MRef e; /* String buffer end pointer. */ |
| 126 | MSize sz; /* String buffer size. */ | 126 | MRef b; /* String buffer base. */ |
| 127 | } SBuf; | 127 | } SBuf; |
| 128 | 128 | ||
| 129 | /* -- Tags and values ----------------------------------------------------- */ | 129 | /* -- Tags and values ----------------------------------------------------- */ |
diff --git a/src/lj_parse.c b/src/lj_parse.c index 3f992bec..64652ed2 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "lj_gc.h" | 13 | #include "lj_gc.h" |
| 14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
| 15 | #include "lj_debug.h" | 15 | #include "lj_debug.h" |
| 16 | #include "lj_buf.h" | ||
| 16 | #include "lj_str.h" | 17 | #include "lj_str.h" |
| 17 | #include "lj_tab.h" | 18 | #include "lj_tab.h" |
| 18 | #include "lj_func.h" | 19 | #include "lj_func.h" |
| @@ -1429,31 +1430,6 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, | |||
| 1429 | } | 1430 | } |
| 1430 | } | 1431 | } |
| 1431 | 1432 | ||
| 1432 | static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len) | ||
| 1433 | { | ||
| 1434 | lj_buf_need(ls->L, &ls->sb, ls->sb.n + len); | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | /* Add string to buffer. */ | ||
| 1438 | static void fs_buf_str(LexState *ls, const char *str, MSize len) | ||
| 1439 | { | ||
| 1440 | char *p = ls->sb.buf + ls->sb.n; | ||
| 1441 | MSize i; | ||
| 1442 | ls->sb.n += len; | ||
| 1443 | for (i = 0; i < len; i++) p[i] = str[i]; | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | /* Add ULEB128 value to buffer. */ | ||
| 1447 | static void fs_buf_uleb128(LexState *ls, uint32_t v) | ||
| 1448 | { | ||
| 1449 | MSize n = ls->sb.n; | ||
| 1450 | uint8_t *p = (uint8_t *)ls->sb.buf; | ||
| 1451 | for (; v >= 0x80; v >>= 7) | ||
| 1452 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
| 1453 | p[n++] = (uint8_t)v; | ||
| 1454 | ls->sb.n = n; | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | /* Prepare variable info for prototype. */ | 1433 | /* Prepare variable info for prototype. */ |
| 1458 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | 1434 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
| 1459 | { | 1435 | { |
| @@ -1465,33 +1441,35 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | |||
| 1465 | for (i = 0, n = fs->nuv; i < n; i++) { | 1441 | for (i = 0, n = fs->nuv; i < n; i++) { |
| 1466 | GCstr *s = strref(vs[fs->uvmap[i]].name); | 1442 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
| 1467 | MSize len = s->len+1; | 1443 | MSize len = s->len+1; |
| 1468 | fs_buf_need(ls, len); | 1444 | char *p = lj_buf_more(ls->L, &ls->sb, len); |
| 1469 | fs_buf_str(ls, strdata(s), len); | 1445 | p = lj_buf_wmem(p, strdata(s), len); |
| 1446 | setsbufP(&ls->sb, p); | ||
| 1470 | } | 1447 | } |
| 1471 | *ofsvar = ls->sb.n; | 1448 | *ofsvar = sbuflen(&ls->sb); |
| 1472 | lastpc = 0; | 1449 | lastpc = 0; |
| 1473 | /* Store local variable names and compressed ranges. */ | 1450 | /* Store local variable names and compressed ranges. */ |
| 1474 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | 1451 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
| 1475 | if (!gola_isgotolabel(vs)) { | 1452 | if (!gola_isgotolabel(vs)) { |
| 1476 | GCstr *s = strref(vs->name); | 1453 | GCstr *s = strref(vs->name); |
| 1477 | BCPos startpc; | 1454 | BCPos startpc; |
| 1455 | char *p; | ||
| 1478 | if ((uintptr_t)s < VARNAME__MAX) { | 1456 | if ((uintptr_t)s < VARNAME__MAX) { |
| 1479 | fs_buf_need(ls, 1 + 2*5); | 1457 | p = lj_buf_more(ls->L, &ls->sb, 1 + 2*5); |
| 1480 | ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s; | 1458 | *p++ = (char)(uintptr_t)s; |
| 1481 | } else { | 1459 | } else { |
| 1482 | MSize len = s->len+1; | 1460 | MSize len = s->len+1; |
| 1483 | fs_buf_need(ls, len + 2*5); | 1461 | p = lj_buf_more(ls->L, &ls->sb, len + 2*5); |
| 1484 | fs_buf_str(ls, strdata(s), len); | 1462 | p = lj_buf_wmem(p, strdata(s), len); |
| 1485 | } | 1463 | } |
| 1486 | startpc = vs->startpc; | 1464 | startpc = vs->startpc; |
| 1487 | fs_buf_uleb128(ls, startpc-lastpc); | 1465 | p = lj_buf_wuleb128(p, startpc-lastpc); |
| 1488 | fs_buf_uleb128(ls, vs->endpc-startpc); | 1466 | p = lj_buf_wuleb128(p, vs->endpc-startpc); |
| 1467 | setsbufP(&ls->sb, p); | ||
| 1489 | lastpc = startpc; | 1468 | lastpc = startpc; |
| 1490 | } | 1469 | } |
| 1491 | } | 1470 | } |
| 1492 | fs_buf_need(ls, 1); | 1471 | lj_buf_putb(ls->L, &ls->sb, '\0'); /* Terminator for varinfo. */ |
| 1493 | ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */ | 1472 | return sbuflen(&ls->sb); |
| 1494 | return ls->sb.n; | ||
| 1495 | } | 1473 | } |
| 1496 | 1474 | ||
| 1497 | /* Fixup variable info for prototype. */ | 1475 | /* Fixup variable info for prototype. */ |
| @@ -1499,7 +1477,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
| 1499 | { | 1477 | { |
| 1500 | setmref(pt->uvinfo, p); | 1478 | setmref(pt->uvinfo, p); |
| 1501 | setmref(pt->varinfo, (char *)p + ofsvar); | 1479 | setmref(pt->varinfo, (char *)p + ofsvar); |
| 1502 | memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */ | 1480 | memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
| 1503 | } | 1481 | } |
| 1504 | #else | 1482 | #else |
| 1505 | 1483 | ||
diff --git a/src/lj_str.c b/src/lj_str.c index 623b362d..84bab864 100644 --- a/src/lj_str.c +++ b/src/lj_str.c | |||
| @@ -218,20 +218,6 @@ GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o) | |||
| 218 | 218 | ||
| 219 | /* -- String formatting --------------------------------------------------- */ | 219 | /* -- String formatting --------------------------------------------------- */ |
| 220 | 220 | ||
| 221 | static void addstr(lua_State *L, SBuf *sb, const char *str, MSize len) | ||
| 222 | { | ||
| 223 | MSize i; | ||
| 224 | char *p = lj_buf_need(L, sb, sb->n+len) + sb->n; | ||
| 225 | sb->n += len; | ||
| 226 | for (i = 0; i < len; i++) p[i] = str[i]; | ||
| 227 | } | ||
| 228 | |||
| 229 | static void addchar(lua_State *L, SBuf *sb, int c) | ||
| 230 | { | ||
| 231 | char *p = lj_buf_need(L, sb, sb->n+1); | ||
| 232 | p[sb->n++] = (char)c; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* Push formatted message as a string object to Lua stack. va_list variant. */ | 221 | /* Push formatted message as a string object to Lua stack. va_list variant. */ |
| 236 | const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | 222 | const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) |
| 237 | { | 223 | { |
| @@ -241,22 +227,22 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | |||
| 241 | for (;;) { | 227 | for (;;) { |
| 242 | const char *e = strchr(fmt, '%'); | 228 | const char *e = strchr(fmt, '%'); |
| 243 | if (e == NULL) break; | 229 | if (e == NULL) break; |
| 244 | addstr(L, sb, fmt, (MSize)(e-fmt)); | 230 | lj_buf_putmem(L, sb, fmt, (MSize)(e-fmt)); |
| 245 | /* This function only handles %s, %c, %d, %f and %p formats. */ | 231 | /* This function only handles %s, %c, %d, %f and %p formats. */ |
| 246 | switch (e[1]) { | 232 | switch (e[1]) { |
| 247 | case 's': { | 233 | case 's': { |
| 248 | const char *s = va_arg(argp, char *); | 234 | const char *s = va_arg(argp, char *); |
| 249 | if (s == NULL) s = "(null)"; | 235 | if (s == NULL) s = "(null)"; |
| 250 | addstr(L, sb, s, (MSize)strlen(s)); | 236 | lj_buf_putmem(L, sb, s, (MSize)strlen(s)); |
| 251 | break; | 237 | break; |
| 252 | } | 238 | } |
| 253 | case 'c': | 239 | case 'c': |
| 254 | addchar(L, sb, va_arg(argp, int)); | 240 | lj_buf_putb(L, sb, va_arg(argp, int)); |
| 255 | break; | 241 | break; |
| 256 | case 'd': { | 242 | case 'd': { |
| 257 | char buf[LJ_STR_INTBUF]; | 243 | char buf[LJ_STR_INTBUF]; |
| 258 | char *p = lj_str_bufint(buf, va_arg(argp, int32_t)); | 244 | char *p = lj_str_bufint(buf, va_arg(argp, int32_t)); |
| 259 | addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p)); | 245 | lj_buf_putmem(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p)); |
| 260 | break; | 246 | break; |
| 261 | } | 247 | } |
| 262 | case 'f': { | 248 | case 'f': { |
| @@ -265,7 +251,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | |||
| 265 | MSize len; | 251 | MSize len; |
| 266 | tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER)); | 252 | tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER)); |
| 267 | len = (MSize)lj_str_bufnum(buf, &tv); | 253 | len = (MSize)lj_str_bufnum(buf, &tv); |
| 268 | addstr(L, sb, buf, len); | 254 | lj_buf_putmem(L, sb, buf, len); |
| 269 | break; | 255 | break; |
| 270 | } | 256 | } |
| 271 | case 'p': { | 257 | case 'p': { |
| @@ -274,7 +260,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | |||
| 274 | ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); | 260 | ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); |
| 275 | ptrdiff_t i, lasti = 2+FMTP_CHARS; | 261 | ptrdiff_t i, lasti = 2+FMTP_CHARS; |
| 276 | if (p == 0) { | 262 | if (p == 0) { |
| 277 | addstr(L, sb, "NULL", 4); | 263 | lj_buf_putmem(L, sb, "NULL", 4); |
| 278 | break; | 264 | break; |
| 279 | } | 265 | } |
| 280 | #if LJ_64 | 266 | #if LJ_64 |
| @@ -285,21 +271,21 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | |||
| 285 | buf[1] = 'x'; | 271 | buf[1] = 'x'; |
| 286 | for (i = lasti-1; i >= 2; i--, p >>= 4) | 272 | for (i = lasti-1; i >= 2; i--, p >>= 4) |
| 287 | buf[i] = "0123456789abcdef"[(p & 15)]; | 273 | buf[i] = "0123456789abcdef"[(p & 15)]; |
| 288 | addstr(L, sb, buf, (MSize)lasti); | 274 | lj_buf_putmem(L, sb, buf, (MSize)lasti); |
| 289 | break; | 275 | break; |
| 290 | } | 276 | } |
| 291 | case '%': | 277 | case '%': |
| 292 | addchar(L, sb, '%'); | 278 | lj_buf_putb(L, sb, '%'); |
| 293 | break; | 279 | break; |
| 294 | default: | 280 | default: |
| 295 | addchar(L, sb, '%'); | 281 | lj_buf_putb(L, sb, '%'); |
| 296 | addchar(L, sb, e[1]); | 282 | lj_buf_putb(L, sb, e[1]); |
| 297 | break; | 283 | break; |
| 298 | } | 284 | } |
| 299 | fmt = e+2; | 285 | fmt = e+2; |
| 300 | } | 286 | } |
| 301 | addstr(L, sb, fmt, (MSize)strlen(fmt)); | 287 | lj_buf_putmem(L, sb, fmt, (MSize)strlen(fmt)); |
| 302 | setstrV(L, L->top, lj_str_new(L, sb->buf, sb->n)); | 288 | setstrV(L, L->top, lj_buf_str(L, sb)); |
| 303 | incr_top(L); | 289 | incr_top(L); |
| 304 | return strVdata(L->top - 1); | 290 | return strVdata(L->top - 1); |
| 305 | } | 291 | } |
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 6928e03b..1d4b60f4 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc | |||
| @@ -1801,10 +1801,11 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1801 | | cmp CARG2, #1 | 1801 | | cmp CARG2, #1 |
| 1802 | | blo ->fff_emptystr // Zero-length string? | 1802 | | blo ->fff_emptystr // Zero-length string? |
| 1803 | | bne ->fff_fallback // Fallback for > 1-char strings. | 1803 | | bne ->fff_fallback // Fallback for > 1-char strings. |
| 1804 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1804 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] |
| 1805 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1805 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] |
| 1806 | | ldr CARG1, STR:CARG1[1] | 1806 | | ldr CARG1, STR:CARG1[1] |
| 1807 | | cmp RB, CARG3 | 1807 | | add INS, CARG2, CARG3 |
| 1808 | | cmp RB, INS | ||
| 1808 | | blo ->fff_fallback | 1809 | | blo ->fff_fallback |
| 1809 | |1: // Fill buffer with char. | 1810 | |1: // Fill buffer with char. |
| 1810 | | strb CARG1, [CARG2, CARG4] | 1811 | | strb CARG1, [CARG2, CARG4] |
| @@ -1819,11 +1820,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1819 | | blo ->fff_fallback | 1820 | | blo ->fff_fallback |
| 1820 | | checkstr CARG2, ->fff_fallback | 1821 | | checkstr CARG2, ->fff_fallback |
| 1821 | | ldr CARG3, STR:CARG1->len | 1822 | | ldr CARG3, STR:CARG1->len |
| 1822 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1823 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] |
| 1823 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1824 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] |
| 1824 | | mov CARG4, CARG3 | 1825 | | mov CARG4, CARG3 |
| 1825 | | add CARG1, STR:CARG1, #sizeof(GCstr) | 1826 | | add CARG1, STR:CARG1, #sizeof(GCstr) |
| 1826 | | cmp RB, CARG3 | 1827 | | add INS, CARG2, CARG3 |
| 1828 | | cmp RB, INS | ||
| 1827 | | blo ->fff_fallback | 1829 | | blo ->fff_fallback |
| 1828 | |1: // Reverse string copy. | 1830 | |1: // Reverse string copy. |
| 1829 | | ldrb RB, [CARG1], #1 | 1831 | | ldrb RB, [CARG1], #1 |
| @@ -1840,11 +1842,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1840 | | blo ->fff_fallback | 1842 | | blo ->fff_fallback |
| 1841 | | checkstr CARG2, ->fff_fallback | 1843 | | checkstr CARG2, ->fff_fallback |
| 1842 | | ldr CARG3, STR:CARG1->len | 1844 | | ldr CARG3, STR:CARG1->len |
| 1843 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1845 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] |
| 1844 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1846 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] |
| 1845 | | mov CARG4, #0 | 1847 | | mov CARG4, #0 |
| 1846 | | add CARG1, STR:CARG1, #sizeof(GCstr) | 1848 | | add CARG1, STR:CARG1, #sizeof(GCstr) |
| 1847 | | cmp RB, CARG3 | 1849 | | add INS, CARG2, CARG3 |
| 1850 | | cmp RB, INS | ||
| 1848 | | blo ->fff_fallback | 1851 | | blo ->fff_fallback |
| 1849 | |1: // ASCII case conversion. | 1852 | |1: // ASCII case conversion. |
| 1850 | | ldrb RB, [CARG1, CARG4] | 1853 | | ldrb RB, [CARG1, CARG4] |
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc index 5808e182..53000411 100644 --- a/src/vm_mips.dasc +++ b/src/vm_mips.dasc | |||
| @@ -1736,14 +1736,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1736 | | beqz AT, ->fff_fallback | 1736 | | beqz AT, ->fff_fallback |
| 1737 | |. lw TMP0, STR:CARG1->len | 1737 | |. lw TMP0, STR:CARG1->len |
| 1738 | | mfc1 CARG3, f0 | 1738 | | mfc1 CARG3, f0 |
| 1739 | | lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 1739 | | lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) |
| 1740 | | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) | ||
| 1740 | | li AT, 1 | 1741 | | li AT, 1 |
| 1741 | | blez CARG3, ->fff_emptystr // Count <= 0? | 1742 | | blez CARG3, ->fff_emptystr // Count <= 0? |
| 1742 | |. sltu AT, AT, TMP0 | 1743 | |. sltu AT, AT, TMP0 |
| 1743 | | beqz TMP0, ->fff_emptystr // Zero length string? | 1744 | | beqz TMP0, ->fff_emptystr // Zero length string? |
| 1744 | |. sltu TMP0, TMP1, CARG3 | 1745 | |. addu TMP3, CARG2, CARG3 |
| 1746 | | sltu TMP0, TMP1, TMP3 | ||
| 1745 | | or AT, AT, TMP0 | 1747 | | or AT, AT, TMP0 |
| 1746 | | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | ||
| 1747 | | bnez AT, ->fff_fallback // Fallback for > 1-char strings. | 1748 | | bnez AT, ->fff_fallback // Fallback for > 1-char strings. |
| 1748 | |. lbu TMP0, STR:CARG1[1] | 1749 | |. lbu TMP0, STR:CARG1[1] |
| 1749 | | addu TMP2, CARG2, CARG3 | 1750 | | addu TMP2, CARG2, CARG3 |
| @@ -1762,14 +1763,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1762 | | beqz NARGS8:RC, ->fff_fallback | 1763 | | beqz NARGS8:RC, ->fff_fallback |
| 1763 | |. li AT, LJ_TSTR | 1764 | |. li AT, LJ_TSTR |
| 1764 | | bne CARG3, AT, ->fff_fallback | 1765 | | bne CARG3, AT, ->fff_fallback |
| 1765 | |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 1766 | |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) |
| 1766 | | lw CARG3, STR:CARG1->len | 1767 | | lw CARG3, STR:CARG1->len |
| 1768 | | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) | ||
| 1767 | | addiu CARG1, STR:CARG1, #STR | 1769 | | addiu CARG1, STR:CARG1, #STR |
| 1768 | | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | 1770 | | addu CARG4, CARG2, CARG3 |
| 1769 | | sltu AT, TMP1, CARG3 | 1771 | | sltu AT, TMP1, CARG4 |
| 1770 | | bnez AT, ->fff_fallback | 1772 | | bnez AT, ->fff_fallback |
| 1771 | |. addu TMP3, CARG1, CARG3 | 1773 | |. addu TMP3, CARG1, CARG3 |
| 1772 | | addu CARG4, CARG2, CARG3 | ||
| 1773 | |1: // Reverse string copy. | 1774 | |1: // Reverse string copy. |
| 1774 | | lbu TMP1, 0(CARG1) | 1775 | | lbu TMP1, 0(CARG1) |
| 1775 | | sltu AT, CARG1, TMP3 | 1776 | | sltu AT, CARG1, TMP3 |
| @@ -1787,11 +1788,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1787 | | beqz NARGS8:RC, ->fff_fallback | 1788 | | beqz NARGS8:RC, ->fff_fallback |
| 1788 | |. li AT, LJ_TSTR | 1789 | |. li AT, LJ_TSTR |
| 1789 | | bne CARG3, AT, ->fff_fallback | 1790 | | bne CARG3, AT, ->fff_fallback |
| 1790 | |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 1791 | |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) |
| 1791 | | lw CARG3, STR:CARG1->len | 1792 | | lw CARG3, STR:CARG1->len |
| 1793 | | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) | ||
| 1792 | | addiu CARG1, STR:CARG1, #STR | 1794 | | addiu CARG1, STR:CARG1, #STR |
| 1793 | | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | 1795 | | addu TMP3, CARG2, CARG3 |
| 1794 | | sltu AT, TMP1, CARG3 | 1796 | | sltu AT, TMP1, TMP3 |
| 1795 | | bnez AT, ->fff_fallback | 1797 | | bnez AT, ->fff_fallback |
| 1796 | |. addu TMP3, CARG1, CARG3 | 1798 | |. addu TMP3, CARG1, CARG3 |
| 1797 | | move CARG4, CARG2 | 1799 | | move CARG4, CARG2 |
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index bff50c59..514bd231 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc | |||
| @@ -2201,15 +2201,16 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2201 | |.endif | 2201 | |.endif |
| 2202 | | lwz TMP0, STR:CARG1->len | 2202 | | lwz TMP0, STR:CARG1->len |
| 2203 | | cmpwi CARG3, 0 | 2203 | | cmpwi CARG3, 0 |
| 2204 | | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 2204 | | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) |
| 2205 | | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) | ||
| 2205 | | ble >2 // Count <= 0? (or non-int) | 2206 | | ble >2 // Count <= 0? (or non-int) |
| 2206 | | cmplwi TMP0, 1 | 2207 | | cmplwi TMP0, 1 |
| 2208 | | add TMP3, CARG2, CARG3 | ||
| 2207 | | subi TMP2, CARG3, 1 | 2209 | | subi TMP2, CARG3, 1 |
| 2208 | | blt >2 // Zero length string? | 2210 | | blt >2 // Zero length string? |
| 2209 | | cmplw cr1, TMP1, CARG3 | 2211 | | cmplw cr1, TMP1, TMP3 |
| 2210 | | bne ->fff_fallback // Fallback for > 1-char strings. | 2212 | | bne ->fff_fallback // Fallback for > 1-char strings. |
| 2211 | | lbz TMP0, STR:CARG1[1] | 2213 | | lbz TMP0, STR:CARG1[1] |
| 2212 | | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | ||
| 2213 | | blt cr1, ->fff_fallback | 2214 | | blt cr1, ->fff_fallback |
| 2214 | |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?). | 2215 | |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?). |
| 2215 | | cmplwi TMP2, 0 | 2216 | | cmplwi TMP2, 0 |
| @@ -2229,13 +2230,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2229 | | lwz STR:CARG1, 4(BASE) | 2230 | | lwz STR:CARG1, 4(BASE) |
| 2230 | | blt ->fff_fallback | 2231 | | blt ->fff_fallback |
| 2231 | | checkstr CARG3 | 2232 | | checkstr CARG3 |
| 2232 | | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 2233 | | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) |
| 2234 | | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) | ||
| 2233 | | bne ->fff_fallback | 2235 | | bne ->fff_fallback |
| 2234 | | lwz CARG3, STR:CARG1->len | 2236 | | lwz CARG3, STR:CARG1->len |
| 2235 | | la CARG1, #STR(STR:CARG1) | 2237 | | la CARG1, #STR(STR:CARG1) |
| 2236 | | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | ||
| 2237 | | li TMP2, 0 | 2238 | | li TMP2, 0 |
| 2238 | | cmplw TMP1, CARG3 | 2239 | | add TMP3, CARG2, CARG3 |
| 2240 | | cmplw TMP1, TMP3 | ||
| 2239 | | subi TMP3, CARG3, 1 | 2241 | | subi TMP3, CARG3, 1 |
| 2240 | | blt ->fff_fallback | 2242 | | blt ->fff_fallback |
| 2241 | |1: // Reverse string copy. | 2243 | |1: // Reverse string copy. |
| @@ -2255,13 +2257,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2255 | | lwz STR:CARG1, 4(BASE) | 2257 | | lwz STR:CARG1, 4(BASE) |
| 2256 | | blt ->fff_fallback | 2258 | | blt ->fff_fallback |
| 2257 | | checkstr CARG3 | 2259 | | checkstr CARG3 |
| 2258 | | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) | 2260 | | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) |
| 2261 | | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) | ||
| 2259 | | bne ->fff_fallback | 2262 | | bne ->fff_fallback |
| 2260 | | lwz CARG3, STR:CARG1->len | 2263 | | lwz CARG3, STR:CARG1->len |
| 2261 | | la CARG1, #STR(STR:CARG1) | 2264 | | la CARG1, #STR(STR:CARG1) |
| 2262 | | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) | ||
| 2263 | | cmplw TMP1, CARG3 | ||
| 2264 | | li TMP2, 0 | 2265 | | li TMP2, 0 |
| 2266 | | add TMP3, CARG2, CARG3 | ||
| 2267 | | cmplw TMP1, TMP3 | ||
| 2265 | | blt ->fff_fallback | 2268 | | blt ->fff_fallback |
| 2266 | |1: // ASCII case conversion. | 2269 | |1: // ASCII case conversion. |
| 2267 | | cmplw TMP2, CARG3 | 2270 | | cmplw TMP2, CARG3 |
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index 0a53ffde..3fd897ec 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc | |||
| @@ -2356,20 +2356,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2356 | | cmp dword STR:RB->len, 1 | 2356 | | cmp dword STR:RB->len, 1 |
| 2357 | | jb ->fff_emptystr // Zero length string? | 2357 | | jb ->fff_emptystr // Zero length string? |
| 2358 | | jne ->fff_fallback_2 // Fallback for > 1-char strings. | 2358 | | jne ->fff_fallback_2 // Fallback for > 1-char strings. |
| 2359 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_2 | ||
| 2360 | | movzx RA, byte STR:RB[1] | 2359 | | movzx RA, byte STR:RB[1] |
| 2361 | | mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.buf)] | 2360 | | mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.b)] |
| 2361 | | add RB, RC | ||
| 2362 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RB; jb ->fff_fallback_2 | ||
| 2362 | |.if X64 | 2363 | |.if X64 |
| 2363 | | mov TMP3, RC | 2364 | | mov TMP3, RC |
| 2364 | |.else | 2365 | |.else |
| 2365 | | mov ARG3, RC | 2366 | | mov ARG3, RC |
| 2366 | |.endif | 2367 | |.endif |
| 2367 | |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?). | 2368 | |1: // Fill buffer with char. |
| 2368 | | mov [RB], RAL | 2369 | | sub RB, 1 |
| 2369 | | add RB, 1 | ||
| 2370 | | sub RC, 1 | 2370 | | sub RC, 1 |
| 2371 | | mov [RB], RAL | ||
| 2371 | | jnz <1 | 2372 | | jnz <1 |
| 2372 | | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.buf)] | 2373 | | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)] |
| 2373 | | jmp ->fff_newstr | 2374 | | jmp ->fff_newstr |
| 2374 | | | 2375 | | |
| 2375 | |.ffunc_1 string_reverse | 2376 | |.ffunc_1 string_reverse |
| @@ -2379,15 +2380,16 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2379 | | mov RC, STR:RB->len | 2380 | | mov RC, STR:RB->len |
| 2380 | | test RC, RC | 2381 | | test RC, RC |
| 2381 | | jz ->fff_emptystr // Zero length string? | 2382 | | jz ->fff_emptystr // Zero length string? |
| 2382 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1 | ||
| 2383 | | add RB, #STR | ||
| 2384 | | mov TMP2, PC // Need another temp register. | 2383 | | mov TMP2, PC // Need another temp register. |
| 2384 | | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)] | ||
| 2385 | | lea RA, [PC+RC] | ||
| 2386 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1 | ||
| 2387 | | add RB, #STR | ||
| 2385 | |.if X64 | 2388 | |.if X64 |
| 2386 | | mov TMP3, RC | 2389 | | mov TMP3, RC |
| 2387 | |.else | 2390 | |.else |
| 2388 | | mov ARG3, RC | 2391 | | mov ARG3, RC |
| 2389 | |.endif | 2392 | |.endif |
| 2390 | | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)] | ||
| 2391 | |1: | 2393 | |1: |
| 2392 | | movzx RA, byte [RB] | 2394 | | movzx RA, byte [RB] |
| 2393 | | add RB, 1 | 2395 | | add RB, 1 |
| @@ -2402,17 +2404,18 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2402 | | .ffunc_1 name | 2404 | | .ffunc_1 name |
| 2403 | | ffgccheck | 2405 | | ffgccheck |
| 2404 | | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback | 2406 | | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback |
| 2407 | | mov TMP2, PC // Need another temp register. | ||
| 2405 | | mov STR:RB, [BASE] | 2408 | | mov STR:RB, [BASE] |
| 2406 | | mov RC, STR:RB->len | 2409 | | mov RC, STR:RB->len |
| 2407 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1 | 2410 | | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)] |
| 2411 | | lea RA, [PC+RC] | ||
| 2412 | | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1 | ||
| 2408 | | add RB, #STR | 2413 | | add RB, #STR |
| 2409 | | mov TMP2, PC // Need another temp register. | ||
| 2410 | |.if X64 | 2414 | |.if X64 |
| 2411 | | mov TMP3, RC | 2415 | | mov TMP3, RC |
| 2412 | |.else | 2416 | |.else |
| 2413 | | mov ARG3, RC | 2417 | | mov ARG3, RC |
| 2414 | |.endif | 2418 | |.endif |
| 2415 | | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)] | ||
| 2416 | | jmp >3 | 2419 | | jmp >3 |
| 2417 | |1: // ASCII case conversion. Yes, this is suboptimal code (do you care?). | 2420 | |1: // ASCII case conversion. Yes, this is suboptimal code (do you care?). |
| 2418 | | movzx RA, byte [RB+RC] | 2421 | | movzx RA, byte [RB+RC] |
