diff options
author | Mike Pall <mike> | 2013-02-27 21:17:27 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2013-02-27 21:28:28 +0100 |
commit | 116cdd7e9a578efffa5a9ca38167d059d12296d7 (patch) | |
tree | cc78e44c4b7a2175f2b16bc5f8898597a72bb228 | |
parent | 28cfcf77445e144335961a020e3e08d84cf0091f (diff) | |
download | luajit-116cdd7e9a578efffa5a9ca38167d059d12296d7.tar.gz luajit-116cdd7e9a578efffa5a9ca38167d059d12296d7.tar.bz2 luajit-116cdd7e9a578efffa5a9ca38167d059d12296d7.zip |
String buffer refactoring, part 2.
Switch to pointers for start/pos/end of buffer.
Abstract out some buffer writers.
-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] |