Просмотр исходного кода

Big renaming of string buffer/formatting/conversion functions.

Mike Pall 12 лет назад
Родитель
Сommit
8f90a1279e

+ 27 - 27
src/Makefile.dep

@@ -7,9 +7,9 @@ lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
  lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
  lj_strfmt.h lj_lib.h lj_libdef.h
 lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
- lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h \
- lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h lj_ffdef.h lj_lib.h \
- lj_libdef.h
+ lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \
+ lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \
+ lj_ffdef.h lj_lib.h lj_libdef.h
 lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
  lj_libdef.h
@@ -59,15 +59,15 @@ lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_strfmt.h
 lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
- lj_ir.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
+ lj_ir.h lj_strfmt.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
 lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
- lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h
+ lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_strfmt.h
 lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ir.h lj_ctype.h \
  lj_cconv.h lj_cdata.h lj_carith.h lj_strscan.h
 lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
- lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
+ lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h \
+ lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
  lj_traceerr.h
 lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
  lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
@@ -78,8 +78,7 @@ lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
  lj_ccallback.h
 lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
- lj_cdata.h
+ lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h
 lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
 lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
@@ -88,21 +87,22 @@ lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ctype.h lj_cparse.h \
  lj_frame.h lj_bc.h lj_vm.h lj_char.h lj_strscan.h lj_strfmt.h
 lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \
- lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \
+ lj_err.h lj_errmsg.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_gc.h \
+ lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \
  lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
  lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
  lj_crecord.h
 lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
+ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \
+ lj_ccallback.h
 lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
  lj_state.h lj_frame.h lj_bc.h lj_strfmt.h lj_jit.h lj_ir.h
 lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \
  lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \
- lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h lj_dispatch.h \
- lj_traceerr.h lj_vm.h luajit.h
+ lj_strfmt.h lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h \
+ lj_dispatch.h lj_traceerr.h lj_vm.h luajit.h
 lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
  lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
  lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
@@ -121,19 +121,19 @@ lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
 lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
- lj_str.h lj_jit.h lj_ir.h lj_dispatch.h
+ lj_str.h lj_strfmt.h lj_jit.h lj_ir.h lj_dispatch.h
 lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_buf.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
  lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h \
- lj_carith.h lj_vm.h lj_strscan.h lj_lib.h
+ lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
 lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
  lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h \
  lj_strfmt.h
 lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
- lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_bcdump.h \
- lj_lib.h
+ lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lex.h \
+ lj_bcdump.h lj_lib.h
 lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
  lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \
  lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
@@ -142,14 +142,14 @@ lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_traceerr.h lj_vm.h
 lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
- lj_bc.h lj_vm.h lj_strscan.h lj_lib.h
+ lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
 lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
 lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_ir.h lj_jit.h lj_iropt.h
 lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h \
  lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h \
- lj_carith.h lj_vm.h lj_strscan.h lj_folddef.h
+ lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_folddef.h
 lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h lj_jit.h \
  lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
@@ -166,13 +166,13 @@ lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
  lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h
 lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
- lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h \
- lj_vmevent.h
+ lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
+ lj_vm.h lj_vmevent.h
 lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_meta.h \
- lj_frame.h lj_bc.h lj_ctype.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h \
- lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
- lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h
+ lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
+ lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h \
+ lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h \
+ lj_ffrecord.h lj_snap.h lj_vm.h
 lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
  lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
@@ -182,7 +182,7 @@ lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h \
  lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h
 lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
- lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_char.h
+ lj_err.h lj_errmsg.h lj_str.h lj_char.h
 lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h
 lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \

+ 2 - 2
src/lib_base.c

@@ -492,11 +492,11 @@ LJLIB_CF(print)
   shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring);
   for (i = 0; i < nargs; i++) {
     cTValue *o = &L->base[i];
-    char buf[LJ_STR_NUMBERBUF];
+    char buf[STRFMT_MAXBUF_NUM];
     const char *str;
     size_t size;
     MSize len;
-    if (shortcut && (str = lj_str_buftv(buf, o, &len)) != NULL) {
+    if (shortcut && (str = lj_strfmt_wstrnum(buf, o, &len)) != NULL) {
       size = len;
     } else {
       copyTV(L, L->top+1, o);

+ 2 - 2
src/lib_bit.c

@@ -13,7 +13,7 @@
 #include "lj_obj.h"
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
+#include "lj_strscan.h"
 #include "lj_strfmt.h"
 #if LJ_HASFFI
 #include "lj_ctype.h"
@@ -157,7 +157,7 @@ LJLIB_CF(bit_tohex)
   SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
   if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
   sf |= ((SFormat)(n+1) << STRFMT_SH_PREC);
-  sb = lj_strfmt_putxint(sb, sf, b);
+  sb = lj_strfmt_putfxint(sb, sf, b);
   setstrV(L, L->top-1, lj_buf_str(L, sb));
   lj_gc_check(L);
   return 1;

+ 2 - 2
src/lib_io.c

@@ -232,9 +232,9 @@ static int io_file_write(lua_State *L, FILE *fp, int start)
   cTValue *tv;
   int status = 1;
   for (tv = L->base+start; tv < L->top; tv++) {
-    char buf[LJ_STR_NUMBERBUF];
+    char buf[STRFMT_MAXBUF_NUM];
     MSize len;
-    const char *p = lj_str_buftv(buf, tv, &len);
+    const char *p = lj_strfmt_wstrnum(buf, tv, &len);
     if (!p)
       lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
     status = status && (fwrite(p, 1, len, fp) == len);

+ 1 - 0
src/lib_os.c

@@ -21,6 +21,7 @@
 #include "lj_gc.h"
 #include "lj_err.h"
 #include "lj_buf.h"
+#include "lj_str.h"
 #include "lj_lib.h"
 
 #if LJ_TARGET_POSIX

+ 10 - 10
src/lib_string.c

@@ -684,21 +684,21 @@ again:
 	if (tvisint(L->base+arg-1)) {
 	  int32_t k = intV(L->base+arg-1);
 	  if (sf == STRFMT_INT)
-	    lj_buf_putint(sb, k);  /* Shortcut for plain %d. */
+	    lj_strfmt_putint(sb, k);  /* Shortcut for plain %d. */
 	  else
-	    lj_strfmt_putxint(sb, sf, k);
+	    lj_strfmt_putfxint(sb, sf, k);
 	} else {
-	  lj_strfmt_putnum_int(sb, sf, lj_lib_checknum(L, arg));
+	  lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
 	}
 	break;
       case STRFMT_UINT:
 	if (tvisint(L->base+arg-1))
-	  lj_strfmt_putxint(sb, sf, intV(L->base+arg-1));
+	  lj_strfmt_putfxint(sb, sf, intV(L->base+arg-1));
 	else
-	  lj_strfmt_putnum_uint(sb, sf, lj_lib_checknum(L, arg));
+	  lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
 	break;
       case STRFMT_NUM:
-	lj_strfmt_putnum(sb, sf, lj_lib_checknum(L, arg));
+	lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg));
 	break;
       case STRFMT_STR: {
 	GCstr *str = string_fmt_tostring(L, arg, retry);
@@ -707,15 +707,15 @@ again:
 	else if ((sf & STRFMT_T_QUOTED))
 	  lj_strfmt_putquoted(sb, str);
 	else
-	  lj_strfmt_putstr(sb, sf, str);
+	  lj_strfmt_putfstr(sb, sf, str);
 	break;
 	}
       case STRFMT_CHAR:
-	lj_strfmt_putchar(sb, sf, lj_lib_checkint(L, arg));
+	lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg));
 	break;
       case STRFMT_PTR:  /* No formatting. */
-	setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF),
-				   lj_obj_ptr(L->base+arg-1)));
+	setsbufP(sb, lj_strfmt_wptr(lj_buf_more(sb, STRFMT_MAXBUF_PTR),
+				    lj_obj_ptr(L->base+arg-1)));
 	break;
       default:
 	lua_assert(0);

+ 0 - 1
src/lib_table.c

@@ -17,7 +17,6 @@
 #include "lj_gc.h"
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_lib.h"
 

+ 4 - 4
src/lj_api.c

@@ -435,7 +435,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
   } else if (tvisnumber(o)) {
     lj_gc_check(L);
     o = index2adr(L, idx);  /* GC may move the stack. */
-    s = lj_str_fromnumber(L, o);
+    s = lj_strfmt_number(L, o);
     setstrV(L, o, s);
   } else {
     if (len != NULL) *len = 0;
@@ -454,7 +454,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
   } else if (tvisnumber(o)) {
     lj_gc_check(L);
     o = index2adr(L, idx);  /* GC may move the stack. */
-    s = lj_str_fromnumber(L, o);
+    s = lj_strfmt_number(L, o);
     setstrV(L, o, s);
   } else {
     lj_err_argt(L, idx, LUA_TSTRING);
@@ -476,7 +476,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
   } else if (tvisnumber(o)) {
     lj_gc_check(L);
     o = index2adr(L, idx);  /* GC may move the stack. */
-    s = lj_str_fromnumber(L, o);
+    s = lj_strfmt_number(L, o);
     setstrV(L, o, s);
   } else {
     lj_err_argt(L, idx, LUA_TSTRING);
@@ -508,7 +508,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
   } else if (tvisudata(o)) {
     return udataV(o)->len;
   } else if (tvisnumber(o)) {
-    GCstr *s = lj_str_fromnumber(L, o);
+    GCstr *s = lj_strfmt_number(L, o);
     setstrV(L, o, s);
     return s->len;
   } else {

+ 6 - 6
src/lj_asm.c

@@ -1086,12 +1086,12 @@ static void asm_bufput(ASMState *as, IRIns *ir)
     if (irs->o == IR_TOSTR) {  /* Fuse number to string conversions. */
       if (irs->op2 == IRTOSTR_NUM) {
 	args[1] = ASMREF_TMP1;  /* TValue * */
-	ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum];
+	ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum];
       } else {
 	lua_assert(irt_isinteger(IR(irs->op1)->t));
 	args[1] = irs->op1;  /* int */
 	if (irs->op2 == IRTOSTR_INT)
-	  ci = &lj_ir_callinfo[IRCALL_lj_buf_putint];
+	  ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint];
 	else
 	  ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
       }
@@ -1131,14 +1131,14 @@ static void asm_tostr(ASMState *as, IRIns *ir)
   args[0] = ASMREF_L;
   as->gcsteps++;
   if (ir->op2 == IRTOSTR_NUM) {
-    args[1] = ASMREF_TMP1;  /* const lua_Number * */
-    ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
+    args[1] = ASMREF_TMP1;  /* cTValue * */
+    ci = &lj_ir_callinfo[IRCALL_lj_strfmt_num];
   } else {
     args[1] = ir->op1;  /* int32_t k */
     if (ir->op2 == IRTOSTR_INT)
-      ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
+      ci = &lj_ir_callinfo[IRCALL_lj_strfmt_int];
     else
-      ci = &lj_ir_callinfo[IRCALL_lj_str_fromchar];
+      ci = &lj_ir_callinfo[IRCALL_lj_strfmt_char];
   }
   asm_setupresult(as, ir, ci);  /* GCstr * */
   asm_gencall(as, ci, args);

+ 24 - 24
src/lj_bcwrite.c

@@ -9,7 +9,6 @@
 #include "lj_obj.h"
 #include "lj_gc.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_bc.h"
 #if LJ_HASFFI
 #include "lj_ctype.h"
@@ -18,6 +17,7 @@
 #include "lj_dispatch.h"
 #include "lj_jit.h"
 #endif
+#include "lj_strfmt.h"
 #include "lj_bcdump.h"
 #include "lj_vm.h"
 
@@ -41,25 +41,25 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
     const GCstr *str = strV(o);
     MSize len = str->len;
     p = lj_buf_more(&ctx->sb, 5+len);
-    p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len);
+    p = lj_strfmt_wuleb128(p, BCDUMP_KTAB_STR+len);
     p = lj_buf_wmem(p, strdata(str), len);
   } else if (tvisint(o)) {
     *p++ = BCDUMP_KTAB_INT;
-    p = lj_buf_wuleb128(p, intV(o));
+    p = lj_strfmt_wuleb128(p, intV(o));
   } else if (tvisnum(o)) {
     if (!LJ_DUALNUM && narrow) {  /* Narrow number constants to integers. */
       lua_Number num = numV(o);
       int32_t k = lj_num2int(num);
       if (num == (lua_Number)k) {  /* -0 is never a constant. */
 	*p++ = BCDUMP_KTAB_INT;
-	p = lj_buf_wuleb128(p, k);
+	p = lj_strfmt_wuleb128(p, k);
 	setsbufP(&ctx->sb, p);
 	return;
       }
     }
     *p++ = BCDUMP_KTAB_NUM;
-    p = lj_buf_wuleb128(p, o->u32.lo);
-    p = lj_buf_wuleb128(p, o->u32.hi);
+    p = lj_strfmt_wuleb128(p, o->u32.lo);
+    p = lj_strfmt_wuleb128(p, o->u32.hi);
   } else {
     lua_assert(tvispri(o));
     *p++ = BCDUMP_KTAB_NIL+~itype(o);
@@ -86,8 +86,8 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
       nhash += !tvisnil(&node[i].val);
   }
   /* Write number of array slots and hash slots. */
-  p = lj_buf_wuleb128(p, narray);
-  p = lj_buf_wuleb128(p, nhash);
+  p = lj_strfmt_wuleb128(p, narray);
+  p = lj_strfmt_wuleb128(p, nhash);
   setsbufP(&ctx->sb, p);
   if (narray) {  /* Write array entries (may contain nil). */
     MSize i;
@@ -143,7 +143,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
     }
     /* Write constant type. */
     p = lj_buf_more(&ctx->sb, need);
-    p = lj_buf_wuleb128(p, tp);
+    p = lj_strfmt_wuleb128(p, tp);
     /* Write constant data (if any). */
     if (tp >= BCDUMP_KGC_STR) {
       p = lj_buf_wmem(p, strdata(gco2str(o)), gco2str(o)->len);
@@ -153,11 +153,11 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
 #if LJ_HASFFI
     } else if (tp != BCDUMP_KGC_CHILD) {
       cTValue *q = (TValue *)cdataptr(gco2cd(o));
-      p = lj_buf_wuleb128(p, q[0].u32.lo);
-      p = lj_buf_wuleb128(p, q[0].u32.hi);
+      p = lj_strfmt_wuleb128(p, q[0].u32.lo);
+      p = lj_strfmt_wuleb128(p, q[0].u32.hi);
       if (tp == BCDUMP_KGC_COMPLEX) {
-	p = lj_buf_wuleb128(p, q[1].u32.lo);
-	p = lj_buf_wuleb128(p, q[1].u32.hi);
+	p = lj_strfmt_wuleb128(p, q[1].u32.lo);
+	p = lj_strfmt_wuleb128(p, q[1].u32.hi);
       }
 #endif
     }
@@ -183,16 +183,16 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
 	k = lj_num2int(num);
 	if (num == (lua_Number)k) {  /* -0 is never a constant. */
 	save_int:
-	  p = lj_buf_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u));
+	  p = lj_strfmt_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k&0x80000000u));
 	  if (k < 0)
 	    p[-1] = (p[-1] & 7) | ((k>>27) & 0x18);
 	  continue;
 	}
       }
-      p = lj_buf_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
+      p = lj_strfmt_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
       if (o->u32.lo >= 0x80000000u)
 	p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18);
-      p = lj_buf_wuleb128(p, o->u32.hi);
+      p = lj_strfmt_wuleb128(p, o->u32.hi);
     }
   }
   setsbufP(&ctx->sb, p);
@@ -257,16 +257,16 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
   *p++ = pt->numparams;
   *p++ = pt->framesize;
   *p++ = pt->sizeuv;
-  p = lj_buf_wuleb128(p, pt->sizekgc);
-  p = lj_buf_wuleb128(p, pt->sizekn);
-  p = lj_buf_wuleb128(p, pt->sizebc-1);
+  p = lj_strfmt_wuleb128(p, pt->sizekgc);
+  p = lj_strfmt_wuleb128(p, pt->sizekn);
+  p = lj_strfmt_wuleb128(p, pt->sizebc-1);
   if (!ctx->strip) {
     if (proto_lineinfo(pt))
       sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
-    p = lj_buf_wuleb128(p, sizedbg);
+    p = lj_strfmt_wuleb128(p, sizedbg);
     if (sizedbg) {
-      p = lj_buf_wuleb128(p, pt->firstline);
-      p = lj_buf_wuleb128(p, pt->numline);
+      p = lj_strfmt_wuleb128(p, pt->firstline);
+      p = lj_strfmt_wuleb128(p, pt->numline);
     }
   }
 
@@ -291,7 +291,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
     MSize n = sbuflen(&ctx->sb) - 5;
     MSize nn = (lj_fls(n)+8)*9 >> 6;
     char *q = sbufB(&ctx->sb) + (5 - nn);
-    p = lj_buf_wuleb128(q, n);  /* Fill in final size. */
+    p = lj_strfmt_wuleb128(q, n);  /* Fill in final size. */
     lua_assert(p == sbufB(&ctx->sb) + 5);
     ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
   }
@@ -312,7 +312,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
 		       (LJ_BE ? BCDUMP_F_BE : 0) +
 		       ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0);
   if (!ctx->strip) {
-    p = lj_buf_wuleb128(p, len);
+    p = lj_strfmt_wuleb128(p, len);
     p = lj_buf_wmem(p, name, len);
   }
   ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb),

+ 26 - 34
src/lj_buf.c

@@ -14,6 +14,9 @@
 #include "lj_buf.h"
 #include "lj_str.h"
 #include "lj_tab.h"
+#include "lj_strfmt.h"
+
+/* -- Buffer management --------------------------------------------------- */
 
 LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
 {
@@ -32,13 +35,6 @@ LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
   setmref(sb->e, b + nsz);
 }
 
-char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
-{
-  SBuf *sb = &G(L)->tmpbuf;
-  setsbufL(sb, L);
-  return lj_buf_need(sb, sz);
-}
-
 void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
 {
   char *b = sbufB(sb);
@@ -52,6 +48,16 @@ void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
   }
 }
 
+char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
+{
+  SBuf *sb = &G(L)->tmpbuf;
+  setsbufL(sb, L);
+  return lj_buf_need(sb, sz);
+}
+
+/* -- Low-level buffer put operations ------------------------------------- */
+
+/* Write memory block to buffer. */
 char *lj_buf_wmem(char *p, const void *q, MSize len)
 {
   const char *s = (const char *)q, *e = s + len;
@@ -68,15 +74,6 @@ SBuf * lj_buf_putmem(SBuf *sb, const void *q, MSize len)
 }
 
 #if LJ_HASJIT
-SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
-{
-  MSize len = s->len;
-  char *p = lj_buf_more(sb, len);
-  p = lj_buf_wmem(p, strdata(s), len);
-  setsbufP(sb, p);
-  return sb;
-}
-
 SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c)
 {
   char *p = lj_buf_more(sb, 1);
@@ -84,19 +81,18 @@ SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c)
   setsbufP(sb, p);
   return sb;
 }
+#endif
 
-SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k)
+SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
 {
-  setsbufP(sb, lj_str_bufint(lj_buf_more(sb, LJ_STR_INTBUF), k));
+  MSize len = s->len;
+  char *p = lj_buf_more(sb, len);
+  p = lj_buf_wmem(p, strdata(s), len);
+  setsbufP(sb, p);
   return sb;
 }
 
-SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o)
-{
-  setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o));
-  return sb;
-}
-#endif
+/* -- High-level buffer put operations ------------------------------------ */
 
 SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
 {
@@ -184,9 +180,9 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
 	MSize len = strV(o)->len;
 	p = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len);
       } else if (tvisint(o)) {
-	p = lj_str_bufint(lj_buf_more(sb, LJ_STR_INTBUF + seplen), intV(o));
+	p = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o));
       } else if (tvisnum(o)) {
-	p = lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF + seplen), o);
+	p = lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM+seplen), o);
       } else {
 	goto badtype;
       }
@@ -201,11 +197,14 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
   return sb;
 }
 
+/* -- Miscellaneous buffer operations ------------------------------------- */
+
 GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
 {
   return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
 }
 
+/* Concatenate two strings. */
 GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2)
 {
   MSize len1 = s1->len, len2 = s2->len;
@@ -215,6 +214,7 @@ GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2)
   return lj_str_new(L, buf, len1 + len2);
 }
 
+/* Read ULEB128 from buffer. */
 uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
 {
   const uint8_t *p = (const uint8_t *)*pp;
@@ -228,11 +228,3 @@ uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
   return v;
 }
 
-char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v)
-{
-  for (; v >= 0x80; v >>= 7)
-    *p++ = (char)((v & 0x7f) | 0x80);
-  *p++ = (char)v;
-  return p;
-}
-

+ 28 - 25
src/lj_buf.h

@@ -20,28 +20,10 @@
 #define setsbufP(sb, q)	(setmref((sb)->p, (q)))
 #define setsbufL(sb, l)	(setmref((sb)->L, (l)))
 
-LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
+/* Buffer management */
 LJ_FUNC void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en);
 LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb);
-
-LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len);
-LJ_FUNC SBuf * lj_buf_putmem(SBuf *sb, const void *q, MSize len);
-#if LJ_HASJIT
-LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
-LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
-LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k);
-LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o);
-#endif
-LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
-LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
-LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
-LJ_FUNC SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep);
-LJ_FUNC SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep,
-			    int32_t i, int32_t e);
-LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
-LJ_FUNC GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2);
-LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
-LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
+LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
 
 static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
 {
@@ -67,11 +49,6 @@ static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
   lj_mem_free(g, sbufB(sb), sbufsz(sb));
 }
 
-static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
-{
-  return lj_str_new(L, sbufB(sb), sbuflen(sb));
-}
-
 static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
 {
   char *en = sbufB(sb) + sz;
@@ -88,6 +65,14 @@ static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
   return sbufP(sb);
 }
 
+/* Low-level buffer put operations */
+LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len);
+LJ_FUNC SBuf * lj_buf_putmem(SBuf *sb, const void *q, MSize len);
+#if LJ_HASJIT
+LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
+#endif
+LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
+
 static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
 {
   char *p = lj_buf_more(sb, 1);
@@ -95,4 +80,22 @@ static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
   setsbufP(sb, p);
 }
 
+/* High-level buffer put operations */
+LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
+LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
+LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
+LJ_FUNC SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep);
+LJ_FUNC SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep,
+			    int32_t i, int32_t e);
+
+/* Miscellaneous buffer operations */
+LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
+LJ_FUNC GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2);
+LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
+
+static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
+{
+  return lj_str_new(L, sbufB(sb), sbuflen(sb));
+}
+
 #endif

+ 0 - 1
src/lj_ccall.c

@@ -9,7 +9,6 @@
 
 #include "lj_gc.h"
 #include "lj_err.h"
-#include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_ctype.h"
 #include "lj_cconv.h"

+ 0 - 1
src/lj_cdata.c

@@ -9,7 +9,6 @@
 
 #include "lj_gc.h"
 #include "lj_err.h"
-#include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_ctype.h"
 #include "lj_cconv.h"

+ 0 - 1
src/lj_cparse.c

@@ -10,7 +10,6 @@
 #include "lj_gc.h"
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_ctype.h"
 #include "lj_cparse.h"
 #include "lj_frame.h"

+ 0 - 1
src/lj_crecord.c

@@ -11,7 +11,6 @@
 #if LJ_HASJIT && LJ_HASFFI
 
 #include "lj_err.h"
-#include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_frame.h"
 #include "lj_ctype.h"

+ 4 - 3
src/lj_ctype.c

@@ -11,6 +11,7 @@
 #include "lj_err.h"
 #include "lj_str.h"
 #include "lj_tab.h"
+#include "lj_strfmt.h"
 #include "lj_ctype.h"
 #include "lj_ccallback.h"
 
@@ -568,16 +569,16 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned)
 /* Convert complex to string with 'i' or 'I' suffix. */
 GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size)
 {
-  char buf[2*LJ_STR_NUMBUF+2+1], *p = buf;
+  char buf[2*STRFMT_MAXBUF_NUM+2+1], *p = buf;
   TValue re, im;
   if (size == 2*sizeof(double)) {
     re.n = *(double *)sp; im.n = ((double *)sp)[1];
   } else {
     re.n = (double)*(float *)sp; im.n = (double)((float *)sp)[1];
   }
-  p = lj_str_bufnum(p, &re);
+  p = lj_strfmt_wnum(p, &re);
   if (!(im.u32.hi & 0x80000000u) || im.n != im.n) *p++ = '+';
-  p = lj_str_bufnum(p, &im);
+  p = lj_strfmt_wnum(p, &im);
   *p = *(p-1) >= 'a' ? 'I' : 'i';
   p++;
   return lj_str_new(L, buf, p-buf);

+ 0 - 1
src/lj_debug.c

@@ -10,7 +10,6 @@
 #include "lj_err.h"
 #include "lj_debug.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_state.h"
 #include "lj_frame.h"

+ 1 - 0
src/lj_dispatch.c

@@ -18,6 +18,7 @@
 #include "lj_frame.h"
 #include "lj_bc.h"
 #include "lj_ff.h"
+#include "lj_strfmt.h"
 #if LJ_HASJIT
 #include "lj_jit.h"
 #endif

+ 1 - 1
src/lj_dispatch.h

@@ -34,7 +34,7 @@
   _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
   _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
   _(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \
-  _(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \
+  _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_num) \
   _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
   _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
   _(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \

+ 1 - 1
src/lj_ffrecord.c

@@ -80,7 +80,7 @@ static GCstr *argv2str(jit_State *J, TValue *o)
     GCstr *s;
     if (!tvisnumber(o))
       lj_trace_err(J, LJ_TRERR_BADTYPE);
-    s = lj_str_fromnumber(J->L, o);
+    s = lj_strfmt_number(J->L, o);
     setstrV(J->L, o, s);
     return s;
   }

+ 2 - 1
src/lj_gdbjit.c

@@ -15,6 +15,7 @@
 #include "lj_debug.h"
 #include "lj_frame.h"
 #include "lj_buf.h"
+#include "lj_strfmt.h"
 #include "lj_jit.h"
 #include "lj_dispatch.h"
 
@@ -443,7 +444,7 @@ static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v)
 #define DU16(x)		(*(uint16_t *)p = (x), p += 2)
 #define DU32(x)		(*(uint32_t *)p = (x), p += 4)
 #define DADDR(x)	(*(uintptr_t *)p = (x), p += sizeof(uintptr_t))
-#define DUV(x)		(p = (uint8_t *)lj_buf_wuleb128((char *)p, (x)))
+#define DUV(x)		(p = (uint8_t *)lj_strfmt_wuleb128((char *)p, (x)))
 #define DSV(x)		(ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p)
 #define DSTR(str)	(ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p)
 #define DALIGNNOP(s)	while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop

+ 1 - 0
src/lj_ir.c

@@ -30,6 +30,7 @@
 #endif
 #include "lj_vm.h"
 #include "lj_strscan.h"
+#include "lj_strfmt.h"
 #include "lj_lib.h"
 
 /* Some local macros to save typing. Undef'd at the end. */

+ 5 - 5
src/lj_ircall.h

@@ -104,14 +104,14 @@ typedef struct CCallInfo {
   _(ANY,	lj_str_find,		4,   N, P32, 0) \
   _(ANY,	lj_str_new,		3,   S, STR, CCI_L) \
   _(ANY,	lj_strscan_num,		2,  FN, INT, 0) \
-  _(ANY,	lj_str_fromint,		2,  FN, STR, CCI_L) \
-  _(ANY,	lj_str_fromnum,		2,  FN, STR, CCI_L) \
-  _(ANY,	lj_str_fromchar,	2,  FN, STR, CCI_L) \
+  _(ANY,	lj_strfmt_int,		2,  FN, STR, CCI_L) \
+  _(ANY,	lj_strfmt_num,		2,  FN, STR, CCI_L) \
+  _(ANY,	lj_strfmt_char,		2,  FN, STR, CCI_L) \
+  _(ANY,	lj_strfmt_putint,	2,  FL, P32, 0) \
+  _(ANY,	lj_strfmt_putnum,	2,  FL, P32, 0) \
   _(ANY,	lj_buf_putmem,		3,   S, P32, 0) \
   _(ANY,	lj_buf_putstr,		2,  FL, P32, 0) \
   _(ANY,	lj_buf_putchar,		2,  FL, P32, 0) \
-  _(ANY,	lj_buf_putint,		2,  FL, P32, 0) \
-  _(ANY,	lj_buf_putnum,		2,  FL, P32, 0) \
   _(ANY,	lj_buf_putstr_reverse,	2,  FL, P32, 0) \
   _(ANY,	lj_buf_putstr_lower,	2,  FL, P32, 0) \
   _(ANY,	lj_buf_putstr_upper,	2,  FL, P32, 0) \

+ 2 - 1
src/lj_lib.c

@@ -18,6 +18,7 @@
 #include "lj_dispatch.h"
 #include "lj_vm.h"
 #include "lj_strscan.h"
+#include "lj_strfmt.h"
 #include "lj_lex.h"
 #include "lj_bcdump.h"
 #include "lj_lib.h"
@@ -164,7 +165,7 @@ GCstr *lj_lib_checkstr(lua_State *L, int narg)
     if (LJ_LIKELY(tvisstr(o))) {
       return strV(o);
     } else if (tvisnumber(o)) {
-      GCstr *s = lj_str_fromnumber(L, o);
+      GCstr *s = lj_strfmt_number(L, o);
       setstrV(L, o, s);
       return s;
     }

+ 0 - 1
src/lj_load.c

@@ -16,7 +16,6 @@
 #include "lj_gc.h"
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_func.h"
 #include "lj_frame.h"
 #include "lj_vm.h"

+ 5 - 4
src/lj_meta.c

@@ -20,6 +20,7 @@
 #include "lj_bc.h"
 #include "lj_vm.h"
 #include "lj_strscan.h"
+#include "lj_strfmt.h"
 #include "lj_lib.h"
 
 /* -- Metamethod handling ------------------------------------------------- */
@@ -269,10 +270,10 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
       ** next step: [...][CAT stack ............]
       */
       TValue *e, *o = top;
-      uint64_t tlen = tvisstr(o) ? strV(o)->len : LJ_STR_NUMBERBUF;
+      uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
       char *p, *buf;
       do {
-	o--; tlen += tvisstr(o) ? strV(o)->len : LJ_STR_NUMBERBUF;
+	o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
       } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1)));
       if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV);
       p = buf = lj_buf_tmp(L, (MSize)tlen);
@@ -282,10 +283,10 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
 	  MSize len = s->len;
 	  p = lj_buf_wmem(p, strdata(s), len);
 	} else if (tvisint(o)) {
-	  p = lj_str_bufint(p, intV(o));
+	  p = lj_strfmt_wint(p, intV(o));
 	} else {
 	  lua_assert(tvisnum(o));
-	  p = lj_str_bufnum(p, o);
+	  p = lj_strfmt_wnum(p, o);
 	}
       }
       setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf)));

+ 4 - 3
src/lj_opt_fold.c

@@ -28,6 +28,7 @@
 #endif
 #include "lj_vm.h"
 #include "lj_strscan.h"
+#include "lj_strfmt.h"
 
 /* Here's a short description how the FOLD engine processes instructions:
 **
@@ -809,15 +810,15 @@ LJFOLDF(kfold_conv_knum_u64_num)
 LJFOLD(TOSTR KNUM any)
 LJFOLDF(kfold_tostr_knum)
 {
-  return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft));
+  return lj_ir_kstr(J, lj_strfmt_num(J->L, ir_knum(fleft)));
 }
 
 LJFOLD(TOSTR KINT any)
 LJFOLDF(kfold_tostr_kint)
 {
   return lj_ir_kstr(J, fins->op2 == IRTOSTR_INT ?
-		       lj_str_fromint(J->L, fleft->i) :
-		       lj_str_fromchar(J->L, fleft->i));
+		       lj_strfmt_int(J->L, fleft->i) :
+		       lj_strfmt_char(J->L, fleft->i));
 }
 
 LJFOLD(STRTO KGC)

+ 0 - 1
src/lj_opt_loop.c

@@ -12,7 +12,6 @@
 
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_ir.h"
 #include "lj_jit.h"
 #include "lj_iropt.h"

+ 0 - 1
src/lj_opt_split.c

@@ -12,7 +12,6 @@
 
 #include "lj_err.h"
 #include "lj_buf.h"
-#include "lj_str.h"
 #include "lj_ir.h"
 #include "lj_jit.h"
 #include "lj_ircall.h"

+ 3 - 2
src/lj_parse.c

@@ -22,6 +22,7 @@
 #if LJ_HASFFI
 #include "lj_ctype.h"
 #endif
+#include "lj_strfmt.h"
 #include "lj_lex.h"
 #include "lj_parse.h"
 #include "lj_vm.h"
@@ -1462,8 +1463,8 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
 	p = lj_buf_wmem(p, strdata(s), len);
       }
       startpc = vs->startpc;
-      p = lj_buf_wuleb128(p, startpc-lastpc);
-      p = lj_buf_wuleb128(p, vs->endpc-startpc);
+      p = lj_strfmt_wuleb128(p, startpc-lastpc);
+      p = lj_strfmt_wuleb128(p, vs->endpc-startpc);
       setsbufP(&ls->sb, p);
       lastpc = startpc;
     }

+ 0 - 1
src/lj_record.c

@@ -11,7 +11,6 @@
 #if LJ_HASJIT
 
 #include "lj_err.h"
-#include "lj_buf.h"
 #include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_meta.h"

+ 0 - 118
src/lj_str.c

@@ -11,7 +11,6 @@
 #include "lj_obj.h"
 #include "lj_gc.h"
 #include "lj_err.h"
-#include "lj_buf.h"
 #include "lj_str.h"
 #include "lj_char.h"
 
@@ -198,120 +197,3 @@ void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s)
   lj_mem_free(g, s, sizestring(s));
 }
 
-/* -- Type conversions ---------------------------------------------------- */
-
-/* Print number to buffer. Canonicalizes non-finite values. */
-char * LJ_FASTCALL lj_str_bufnum(char *p, cTValue *o)
-{
-  if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) {  /* Finite? */
-#if __BIONIC__
-    if (tvismzero(o)) { *p++ = '-'; *p++ = '0'; return p; }
-#endif
-    return p + lua_number2str(p, o->n);
-  } else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
-    *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
-  } else if ((o->u32.hi & 0x80000000) == 0) {
-    *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
-  } else {
-    *p++ = '-'; *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
-  }
-  return p;
-}
-
-#define STR_BUFINT_R(x, sh, sc) \
-  { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); }
-
-/* Print integer to buffer. */
-char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
-{
-  uint32_t u = (uint32_t)k;
-  if (k < 0) { u = (uint32_t)-k; *p++ = '-'; }
-  if (u < 10000) {
-    if (u < 10) goto dig1; if (u < 100) goto dig2; if (u < 1000) goto dig3;
-  } else {
-    uint32_t v = u / 10000; u -= v * 10000;
-    if (v < 10000) {
-      if (v < 10) goto dig5; if (v < 100) goto dig6; if (v < 1000) goto dig7;
-    } else {
-      uint32_t w = v / 10000; v -= w * 10000;
-      if (w >= 10) STR_BUFINT_R(w, 10, 10)
-      *p++ = (char)('0'+w);
-    }
-    STR_BUFINT_R(v, 23, 1000)
-    dig7: STR_BUFINT_R(v, 12, 100)
-    dig6: STR_BUFINT_R(v, 10, 10)
-    dig5: *p++ = (char)('0'+v);
-  }
-  STR_BUFINT_R(u, 23, 1000)
-  dig3: STR_BUFINT_R(u, 12, 100)
-  dig2: STR_BUFINT_R(u, 10, 10)
-  dig1: *p++ = (char)('0'+u);
-  return p;
-}
-
-/* Print pointer to buffer. */
-char * LJ_FASTCALL lj_str_bufptr(char *p, const void *v)
-{
-  ptrdiff_t x = (ptrdiff_t)v;
-  MSize i, n = LJ_STR_PTRBUF;
-  if (x == 0) {
-    *p++ = 'N'; *p++ = 'U'; *p++ = 'L'; *p++ = 'L';
-    return p;
-  }
-#if LJ_64
-  /* Shorten output for 64 bit pointers. */
-  n = 2+2*4+((x >> 32) ? 2+2*(lj_fls((uint32_t)(x >> 32))>>3) : 0);
-#endif
-  p[0] = '0';
-  p[1] = 'x';
-  for (i = n-1; i >= 2; i--, x >>= 4)
-    p[i] = "0123456789abcdef"[(x & 15)];
-  return p+n;
-}
-
-/* Print TValue to buffer (only for numbers) and return pointer to start. */
-const char *lj_str_buftv(char *buf, cTValue *o, MSize *lenp)
-{
-  if (tvisstr(o)) {
-    *lenp = strV(o)->len;
-    return strVdata(o);
-  } else if (tvisint(o)) {
-    *lenp = (MSize)(lj_str_bufint(buf, intV(o)) - buf);
-    return buf;
-  } else if (tvisnum(o)) {
-    *lenp = (MSize)(lj_str_bufnum(buf, o) - buf);
-    return buf;
-  } else {
-    return NULL;
-  }
-}
-
-/* Convert number to string. */
-GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
-{
-  char buf[LJ_STR_NUMBUF];
-  MSize len = (MSize)(lj_str_bufnum(buf, (TValue *)np) - buf);
-  return lj_str_new(L, buf, len);
-}
-
-/* Convert integer to string. */
-GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
-{
-  char buf[LJ_STR_INTBUF];
-  MSize len = (MSize)(lj_str_bufint(buf, k) - buf);
-  return lj_str_new(L, buf, len);
-}
-
-GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
-{
-  return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
-}
-
-/* Convert char value to string. */
-GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c)
-{
-  char buf[1];
-  buf[0] = c;
-  return lj_str_new(L, buf, 1);
-}
-

+ 0 - 15
src/lj_str.h

@@ -24,19 +24,4 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
 #define lj_str_newz(L, s)	(lj_str_new(L, s, strlen(s)))
 #define lj_str_newlit(L, s)	(lj_str_new(L, "" s, sizeof(s)-1))
 
-/* Type conversions. */
-LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k);
-LJ_FUNC char * LJ_FASTCALL lj_str_bufnum(char *p, cTValue *o);
-LJ_FUNC char * LJ_FASTCALL lj_str_bufptr(char *p, const void *v);
-LJ_FUNC const char *lj_str_buftv(char *buf, cTValue *o, MSize *lenp);
-LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
-LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
-LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
-LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c);
-
-#define LJ_STR_INTBUF		(1+10)
-#define LJ_STR_NUMBUF		LUAI_MAXNUMBER2STR
-#define LJ_STR_NUMBERBUF	LUAI_MAXNUMBER2STR
-#define LJ_STR_PTRBUF		(2*sizeof(ptrdiff_t)+2)
-
 #endif

+ 185 - 36
src/lj_strfmt.c

@@ -10,6 +10,7 @@
 
 #include "lj_obj.h"
 #include "lj_buf.h"
+#include "lj_str.h"
 #include "lj_state.h"
 #include "lj_char.h"
 #include "lj_strfmt.h"
@@ -86,35 +87,124 @@ retlit:
   return fs->len ? STRFMT_LIT : STRFMT_EOF;
 }
 
-/* -- Formatted conversions to buffer ------------------------------------- */
+/* -- Raw conversions ----------------------------------------------------- */
 
-/* Add formatted char to buffer. */
-SBuf *lj_strfmt_putchar(SBuf *sb, SFormat sf, int32_t c)
+/* Write number to bufer. */
+char * LJ_FASTCALL lj_strfmt_wnum(char *p, cTValue *o)
 {
-  MSize width = STRFMT_WIDTH(sf);
-  char *p = lj_buf_more(sb, width > 1 ? width : 1);
-  if ((sf & STRFMT_F_LEFT)) *p++ = (char)c;
-  while (width-- > 1) *p++ = ' ';
-  if (!(sf & STRFMT_F_LEFT)) *p++ = (char)c;
-  setsbufP(sb, p);
+  if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) {  /* Finite? */
+#if __BIONIC__
+    if (tvismzero(o)) { *p++ = '-'; *p++ = '0'; return p; }
+#endif
+    return p + lua_number2str(p, o->n);
+  } else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
+    *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+  } else if ((o->u32.hi & 0x80000000) == 0) {
+    *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+  } else {
+    *p++ = '-'; *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+  }
+  return p;
+}
+
+#define WINT_R(x, sh, sc) \
+  { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); }
+
+/* Write integer to buffer. */
+char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k)
+{
+  uint32_t u = (uint32_t)k;
+  if (k < 0) { u = (uint32_t)-k; *p++ = '-'; }
+  if (u < 10000) {
+    if (u < 10) goto dig1; if (u < 100) goto dig2; if (u < 1000) goto dig3;
+  } else {
+    uint32_t v = u / 10000; u -= v * 10000;
+    if (v < 10000) {
+      if (v < 10) goto dig5; if (v < 100) goto dig6; if (v < 1000) goto dig7;
+    } else {
+      uint32_t w = v / 10000; v -= w * 10000;
+      if (w >= 10) WINT_R(w, 10, 10)
+      *p++ = (char)('0'+w);
+    }
+    WINT_R(v, 23, 1000)
+    dig7: WINT_R(v, 12, 100)
+    dig6: WINT_R(v, 10, 10)
+    dig5: *p++ = (char)('0'+v);
+  }
+  WINT_R(u, 23, 1000)
+  dig3: WINT_R(u, 12, 100)
+  dig2: WINT_R(u, 10, 10)
+  dig1: *p++ = (char)('0'+u);
+  return p;
+}
+#undef WINT_R
+
+/* Write pointer to buffer. */
+char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v)
+{
+  ptrdiff_t x = (ptrdiff_t)v;
+  MSize i, n = STRFMT_MAXBUF_PTR;
+  if (x == 0) {
+    *p++ = 'N'; *p++ = 'U'; *p++ = 'L'; *p++ = 'L';
+    return p;
+  }
+#if LJ_64
+  /* Shorten output for 64 bit pointers. */
+  n = 2+2*4+((x >> 32) ? 2+2*(lj_fls((uint32_t)(x >> 32))>>3) : 0);
+#endif
+  p[0] = '0';
+  p[1] = 'x';
+  for (i = n-1; i >= 2; i--, x >>= 4)
+    p[i] = "0123456789abcdef"[(x & 15)];
+  return p+n;
+}
+
+/* Write ULEB128 to buffer. */
+char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v)
+{
+  for (; v >= 0x80; v >>= 7)
+    *p++ = (char)((v & 0x7f) | 0x80);
+  *p++ = (char)v;
+  return p;
+}
+
+/* Return string or write number to buffer and return pointer to start. */
+const char *lj_strfmt_wstrnum(char *buf, cTValue *o, MSize *lenp)
+{
+  if (tvisstr(o)) {
+    *lenp = strV(o)->len;
+    return strVdata(o);
+  } else if (tvisint(o)) {
+    *lenp = (MSize)(lj_strfmt_wint(buf, intV(o)) - buf);
+    return buf;
+  } else if (tvisnum(o)) {
+    *lenp = (MSize)(lj_strfmt_wnum(buf, o) - buf);
+    return buf;
+  } else {
+    return NULL;
+  }
+}
+
+/* -- Unformatted conversions to buffer ----------------------------------- */
+
+/* Add integer to buffer. */
+SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k)
+{
+  setsbufP(sb, lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT), k));
   return sb;
 }
 
-/* Add formatted string to buffer. */
-SBuf *lj_strfmt_putstr(SBuf *sb, SFormat sf, GCstr *str)
+#if LJ_HASJIT
+/* Add number to buffer. */
+SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o)
 {
-  MSize len = str->len <= STRFMT_PREC(sf) ? str->len : STRFMT_PREC(sf);
-  MSize width = STRFMT_WIDTH(sf);
-  char *p = lj_buf_more(sb, width > len ? width : len);
-  if ((sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len);
-  while (width-- > len) *p++ = ' ';
-  if (!(sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len);
-  setsbufP(sb, p);
+  setsbufP(sb, lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM), o));
   return sb;
 }
+#endif
 
-/* Add quoted string to buffer (no formatting). */
-SBuf *lj_strfmt_putquoted(SBuf *sb, GCstr *str)
+/* Add quoted string to buffer. */
+SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str)
 {
   const char *s = strdata(str);
   MSize len = str->len;
@@ -143,10 +233,37 @@ SBuf *lj_strfmt_putquoted(SBuf *sb, GCstr *str)
   return sb;
 }
 
+/* -- Formatted conversions to buffer ------------------------------------- */
+
+/* Add formatted char to buffer. */
+SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat sf, int32_t c)
+{
+  MSize width = STRFMT_WIDTH(sf);
+  char *p = lj_buf_more(sb, width > 1 ? width : 1);
+  if ((sf & STRFMT_F_LEFT)) *p++ = (char)c;
+  while (width-- > 1) *p++ = ' ';
+  if (!(sf & STRFMT_F_LEFT)) *p++ = (char)c;
+  setsbufP(sb, p);
+  return sb;
+}
+
+/* Add formatted string to buffer. */
+SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat sf, GCstr *str)
+{
+  MSize len = str->len <= STRFMT_PREC(sf) ? str->len : STRFMT_PREC(sf);
+  MSize width = STRFMT_WIDTH(sf);
+  char *p = lj_buf_more(sb, width > len ? width : len);
+  if ((sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len);
+  while (width-- > len) *p++ = ' ';
+  if (!(sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len);
+  setsbufP(sb, p);
+  return sb;
+}
+
 /* Add formatted signed/unsigned integer to buffer. */
-SBuf *lj_strfmt_putxint(SBuf *sb, SFormat sf, uint64_t k)
+SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k)
 {
-  char buf[1+22], *q = buf + sizeof(buf), *p;
+  char buf[STRFMT_MAXBUF_XINT], *q = buf + sizeof(buf), *p;
 #ifdef LUA_USE_ASSERT
   char *ps;
 #endif
@@ -217,31 +334,31 @@ SBuf *lj_strfmt_putxint(SBuf *sb, SFormat sf, uint64_t k)
 }
 
 /* Add number formatted as signed integer to buffer. */
-SBuf *lj_strfmt_putnum_int(SBuf *sb, SFormat sf, lua_Number n)
+SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n)
 {
   int64_t k = (int64_t)n;
   if (checki32(k) && sf == STRFMT_INT)
-    return lj_buf_putint(sb, k);  /* Shortcut for plain %d. */
+    return lj_strfmt_putint(sb, k);  /* Shortcut for plain %d. */
   else
-    return lj_strfmt_putxint(sb, sf, (uint64_t)k);
+    return lj_strfmt_putfxint(sb, sf, (uint64_t)k);
 }
 
 /* Add number formatted as unsigned integer to buffer. */
-SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n)
+SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n)
 {
   int64_t k;
   if (n >= 9223372036854775808.0)
     k = (int64_t)(n - 18446744073709551616.0);
   else
     k = (int64_t)n;
-  return lj_strfmt_putxint(sb, sf, (uint64_t)k);
+  return lj_strfmt_putfxint(sb, sf, (uint64_t)k);
 }
 
 /* Max. sprintf buffer size needed. At least #string.format("%.99f", -1e308). */
 #define STRFMT_FMTNUMBUF	512
 
 /* Add formatted floating-point number to buffer. */
-SBuf *lj_strfmt_putnum(SBuf *sb, SFormat sf, lua_Number n)
+SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n)
 {
   TValue tv;
   tv.n = n;
@@ -296,13 +413,45 @@ SBuf *lj_strfmt_putnum(SBuf *sb, SFormat sf, lua_Number n)
 
 /* -- Conversions to strings ---------------------------------------------- */
 
+/* Convert integer to string. */
+GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k)
+{
+  char buf[STRFMT_MAXBUF_INT];
+  MSize len = (MSize)(lj_strfmt_wint(buf, k) - buf);
+  return lj_str_new(L, buf, len);
+}
+
+/* Convert number to string. */
+GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o)
+{
+  char buf[STRFMT_MAXBUF_NUM];
+  MSize len = (MSize)(lj_strfmt_wnum(buf, o) - buf);
+  return lj_str_new(L, buf, len);
+}
+
+/* Convert integer or number to string. */
+GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o)
+{
+  return tvisint(o) ? lj_strfmt_int(L, intV(o)) : lj_strfmt_num(L, o);
+}
+
+#if LJ_HASJIT
+/* Convert char value to string. */
+GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c)
+{
+  char buf[1];
+  buf[0] = c;
+  return lj_str_new(L, buf, 1);
+}
+#endif
+
 /* Raw conversion of object to string. */
 GCstr *lj_strfmt_obj(lua_State *L, cTValue *o)
 {
   if (tvisstr(o)) {
     return strV(o);
   } else if (tvisnumber(o)) {
-    return lj_str_fromnumber(L, o);
+    return lj_strfmt_number(L, o);
   } else if (tvisnil(o)) {
     return lj_str_newlit(L, "nil");
   } else if (tvisfalse(o)) {
@@ -315,9 +464,9 @@ GCstr *lj_strfmt_obj(lua_State *L, cTValue *o)
     *p++ = ':'; *p++ = ' ';
     if (tvisfunc(o) && isffunc(funcV(o))) {
       p = lj_buf_wmem(p, "builtin#", 8);
-      p = lj_str_bufint(p, funcV(o)->c.ffid);
+      p = lj_strfmt_wint(p, funcV(o)->c.ffid);
     } else {
-      p = lj_str_bufptr(p, lj_obj_ptr(o));
+      p = lj_strfmt_wptr(p, lj_obj_ptr(o));
     }
     return lj_str_new(L, buf, (size_t)(p - buf));
   }
@@ -350,15 +499,15 @@ const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, va_list argp)
       lj_buf_putmem(sb, fs.str, fs.len);
       break;
     case STRFMT_INT:
-      lj_strfmt_putxint(sb, sf, va_arg(argp, int32_t));
+      lj_strfmt_putfxint(sb, sf, va_arg(argp, int32_t));
       break;
     case STRFMT_UINT:
-      lj_strfmt_putxint(sb, sf, va_arg(argp, uint32_t));
+      lj_strfmt_putfxint(sb, sf, va_arg(argp, uint32_t));
       break;
     case STRFMT_NUM: {
       TValue tv;
       tv.n = va_arg(argp, lua_Number);
-      setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), &tv));
+      setsbufP(sb, lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM), &tv));
       break;
       }
     case STRFMT_STR: {
@@ -371,8 +520,8 @@ const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, va_list argp)
       lj_buf_putb(sb, va_arg(argp, int));
       break;
     case STRFMT_PTR:
-      setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF),
-				 va_arg(argp, void *)));
+      setsbufP(sb, lj_strfmt_wptr(lj_buf_more(sb, STRFMT_MAXBUF_PTR),
+				  va_arg(argp, void *)));
       break;
     case STRFMT_ERR:
     default:

+ 40 - 11
src/lj_strfmt.h

@@ -65,6 +65,15 @@ typedef enum FormatType {
 #define STRFMT_U	(STRFMT_UINT)
 #define STRFMT_X	(STRFMT_UINT|STRFMT_T_HEX)
 
+/* Maximum buffer sizes for conversions. */
+#define STRFMT_MAXBUF_XINT	(1+22)  /* '0' prefix + uint64_t in octal. */
+#define STRFMT_MAXBUF_INT	(1+10)  /* Sign + int32_t in decimal. */
+#define STRFMT_MAXBUF_NUM	LUAI_MAXNUMBER2STR
+#define STRFMT_MAXBUF_PTR	(2+2*sizeof(ptrdiff_t))  /* "0x" + hex ptr. */
+
+/* Format parser. */
+LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs);
+
 static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len)
 {
   fs->p = (const uint8_t *)p;
@@ -72,18 +81,38 @@ static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len)
   lua_assert(*fs->e == 0);  /* Must be NUL-terminated (may have NULs inside). */
 }
 
-LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs);
-
-LJ_FUNC SBuf *lj_strfmt_putchar(SBuf *sb, SFormat, int32_t c);
-LJ_FUNC SBuf *lj_strfmt_putstr(SBuf *sb, SFormat, GCstr *str);
-LJ_FUNC SBuf *lj_strfmt_putquoted(SBuf *sb, GCstr *str);
-LJ_FUNC SBuf *lj_strfmt_putxint(SBuf *sb, SFormat sf, uint64_t k);
-LJ_FUNC SBuf *lj_strfmt_putnum_int(SBuf *sb, SFormat sf, lua_Number n);
-LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n);
-LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n);
-
-LJ_FUNC GCstr *lj_strfmt_obj(lua_State *L, cTValue *o);
+/* Raw conversions. */
+LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k);
+LJ_FUNC char * LJ_FASTCALL lj_strfmt_wnum(char *p, cTValue *o);
+LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v);
+LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v);
+LJ_FUNC const char *lj_strfmt_wstrnum(char *buf, cTValue *o, MSize *lenp);
+
+/* Unformatted conversions to buffer. */
+LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k);
+#if LJ_HASJIT
+LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o);
+#endif
+LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str);
+
+/* Formatted conversions to buffer. */
+LJ_FUNC SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k);
+LJ_FUNC SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n);
+LJ_FUNC SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n);
+LJ_FUNC SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat, lua_Number n);
+LJ_FUNC SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat, int32_t c);
+LJ_FUNC SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat, GCstr *str);
+
+/* Conversions to strings. */
+LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k);
+LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o);
+LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o);
+#if LJ_HASJIT
+LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c);
+#endif
+LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_obj(lua_State *L, cTValue *o);
 
+/* Internal string formatting. */
 LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt,
 				     va_list argp);
 LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...)

+ 1 - 1
src/vm_arm.dasc

@@ -1084,7 +1084,7 @@ static void build_subroutines(BuildCtx *ctx)
   |  ffgccheck
   |  mov CARG1, L
   |  mov CARG2, BASE
-  |  bl extern lj_str_fromnumber	// (lua_State *L, cTValue *o)
+  |  bl extern lj_strfmt_number		// (lua_State *L, cTValue *o)
   |  // Returns GCstr *.
   |  ldr BASE, L->base
   |  mvn CARG2, #~LJ_TSTR

+ 2 - 2
src/vm_mips.dasc

@@ -1152,9 +1152,9 @@ static void build_subroutines(BuildCtx *ctx)
   |.  sw BASE, L->base			// Add frame since C call can throw.
   |  ffgccheck
   |.  sw PC, SAVE_PC			// Redundant (but a defined value).
-  |  load_got lj_str_fromnum
+  |  load_got lj_strfmt_num
   |  move CARG1, L
-  |  call_intern lj_str_fromnum		// (lua_State *L, lua_Number *np)
+  |  call_intern lj_strfmt_num		// (lua_State *L, lua_Number *np)
   |.  move CARG2, BASE
   |  // Returns GCstr *.
   |  li CARG3, LJ_TSTR

+ 2 - 2
src/vm_ppc.dasc

@@ -1394,9 +1394,9 @@ static void build_subroutines(BuildCtx *ctx)
   |  mr CARG1, L
   |  mr CARG2, BASE
   |.if DUALNUM
-  |  bl extern lj_str_fromnumber	// (lua_State *L, cTValue *o)
+  |  bl extern lj_strfmt_number		// (lua_State *L, cTValue *o)
   |.else
-  |  bl extern lj_str_fromnum		// (lua_State *L, lua_Number *np)
+  |  bl extern lj_strfmt_num		// (lua_State *L, lua_Number *np)
   |.endif
   |  // Returns GCstr *.
   |  li CARG3, LJ_TSTR

+ 2 - 2
src/vm_x86.dasc

@@ -1586,9 +1586,9 @@ static void build_subroutines(BuildCtx *ctx)
   |.endif
   |  mov L:FCARG1, L:RB
   |.if DUALNUM
-  |  call extern lj_str_fromnumber@8	// (lua_State *L, cTValue *o)
+  |  call extern lj_strfmt_number@8	// (lua_State *L, cTValue *o)
   |.else
-  |  call extern lj_str_fromnum@8	// (lua_State *L, lua_Number *np)
+  |  call extern lj_strfmt_num@8	// (lua_State *L, lua_Number *np)
   |.endif
   |  // GCstr returned in eax (RD).
   |  mov BASE, L:RB->base