immunio 1.1.2 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/lib/immunio/version.rb +1 -1
  3. data/lua-hooks/Makefile +56 -109
  4. data/lua-hooks/ext/all.c +3 -14
  5. data/lua-hooks/ext/libinjection/module.mk +5 -0
  6. data/lua-hooks/ext/lpeg/module.mk +6 -0
  7. data/lua-hooks/ext/lua-cmsgpack/module.mk +2 -0
  8. data/lua-hooks/ext/lua-snapshot/module.mk +2 -0
  9. data/lua-hooks/ext/luajit/COPYRIGHT +1 -1
  10. data/lua-hooks/ext/luajit/Makefile +2 -2
  11. data/lua-hooks/ext/luajit/README +2 -2
  12. data/lua-hooks/ext/luajit/doc/bluequad-print.css +1 -1
  13. data/lua-hooks/ext/luajit/doc/bluequad.css +1 -1
  14. data/lua-hooks/ext/luajit/doc/changes.html +15 -2
  15. data/lua-hooks/ext/luajit/doc/contact.html +3 -3
  16. data/lua-hooks/ext/luajit/doc/ext_c_api.html +2 -2
  17. data/lua-hooks/ext/luajit/doc/ext_ffi.html +2 -2
  18. data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +2 -2
  19. data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +4 -2
  20. data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +2 -2
  21. data/lua-hooks/ext/luajit/doc/ext_jit.html +2 -2
  22. data/lua-hooks/ext/luajit/doc/ext_profiler.html +2 -2
  23. data/lua-hooks/ext/luajit/doc/extensions.html +9 -2
  24. data/lua-hooks/ext/luajit/doc/faq.html +2 -2
  25. data/lua-hooks/ext/luajit/doc/install.html +22 -18
  26. data/lua-hooks/ext/luajit/doc/luajit.html +3 -3
  27. data/lua-hooks/ext/luajit/doc/running.html +2 -2
  28. data/lua-hooks/ext/luajit/doc/status.html +2 -2
  29. data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +1 -1
  30. data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +4 -4
  31. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +1 -1
  32. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +4 -4
  33. data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +1 -1
  34. data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +4 -4
  35. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +1 -1
  36. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +4 -4
  37. data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +3 -3
  38. data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +1 -1
  39. data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +34 -7
  40. data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +427 -102
  41. data/lua-hooks/ext/luajit/dynasm/dynasm.lua +5 -5
  42. data/lua-hooks/ext/luajit/etc/luajit.1 +1 -1
  43. data/lua-hooks/ext/luajit/etc/luajit.pc +1 -1
  44. data/lua-hooks/ext/luajit/src/Makefile +36 -21
  45. data/lua-hooks/ext/luajit/src/Makefile.dep +3 -1
  46. data/lua-hooks/ext/luajit/src/host/buildvm.c +1 -1
  47. data/lua-hooks/ext/luajit/src/host/buildvm.h +1 -1
  48. data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +10 -1
  49. data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +1 -1
  50. data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +1 -1
  51. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +1 -1
  52. data/lua-hooks/ext/luajit/src/host/genlibbc.lua +1 -1
  53. data/lua-hooks/ext/luajit/src/host/genminilua.lua +1 -1
  54. data/lua-hooks/ext/luajit/src/jit/bc.lua +1 -1
  55. data/lua-hooks/ext/luajit/src/jit/bcsave.lua +2 -2
  56. data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +1 -1
  57. data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +1 -1
  58. data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +1 -1
  59. data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +1 -1
  60. data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +1 -1
  61. data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +163 -73
  62. data/lua-hooks/ext/luajit/src/jit/dump.lua +2 -1
  63. data/lua-hooks/ext/luajit/src/jit/p.lua +1 -1
  64. data/lua-hooks/ext/luajit/src/jit/v.lua +1 -1
  65. data/lua-hooks/ext/luajit/src/jit/zone.lua +1 -1
  66. data/lua-hooks/ext/luajit/src/lib_aux.c +1 -1
  67. data/lua-hooks/ext/luajit/src/lib_base.c +4 -5
  68. data/lua-hooks/ext/luajit/src/lib_bit.c +1 -1
  69. data/lua-hooks/ext/luajit/src/lib_debug.c +1 -1
  70. data/lua-hooks/ext/luajit/src/lib_ffi.c +2 -5
  71. data/lua-hooks/ext/luajit/src/lib_init.c +1 -1
  72. data/lua-hooks/ext/luajit/src/lib_io.c +2 -3
  73. data/lua-hooks/ext/luajit/src/lib_jit.c +1 -1
  74. data/lua-hooks/ext/luajit/src/lib_math.c +1 -1
  75. data/lua-hooks/ext/luajit/src/lib_os.c +2 -2
  76. data/lua-hooks/ext/luajit/src/lib_package.c +1 -1
  77. data/lua-hooks/ext/luajit/src/lib_string.c +1 -1
  78. data/lua-hooks/ext/luajit/src/lib_table.c +1 -1
  79. data/lua-hooks/ext/luajit/src/lj.supp +15 -0
  80. data/lua-hooks/ext/luajit/src/lj_alloc.c +1 -1
  81. data/lua-hooks/ext/luajit/src/lj_api.c +4 -1
  82. data/lua-hooks/ext/luajit/src/lj_arch.h +33 -7
  83. data/lua-hooks/ext/luajit/src/lj_asm.c +12 -5
  84. data/lua-hooks/ext/luajit/src/lj_asm.h +1 -1
  85. data/lua-hooks/ext/luajit/src/lj_asm_arm.h +3 -13
  86. data/lua-hooks/ext/luajit/src/lj_asm_mips.h +337 -71
  87. data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2 -2
  88. data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2 -2
  89. data/lua-hooks/ext/luajit/src/lj_bc.c +1 -1
  90. data/lua-hooks/ext/luajit/src/lj_bc.h +1 -1
  91. data/lua-hooks/ext/luajit/src/lj_bcdump.h +1 -1
  92. data/lua-hooks/ext/luajit/src/lj_bcread.c +1 -1
  93. data/lua-hooks/ext/luajit/src/lj_bcwrite.c +1 -1
  94. data/lua-hooks/ext/luajit/src/lj_buf.c +2 -4
  95. data/lua-hooks/ext/luajit/src/lj_buf.h +1 -3
  96. data/lua-hooks/ext/luajit/src/lj_carith.c +1 -1
  97. data/lua-hooks/ext/luajit/src/lj_carith.h +1 -1
  98. data/lua-hooks/ext/luajit/src/lj_ccall.c +37 -14
  99. data/lua-hooks/ext/luajit/src/lj_ccall.h +3 -3
  100. data/lua-hooks/ext/luajit/src/lj_ccallback.c +16 -7
  101. data/lua-hooks/ext/luajit/src/lj_ccallback.h +1 -1
  102. data/lua-hooks/ext/luajit/src/lj_cconv.c +1 -1
  103. data/lua-hooks/ext/luajit/src/lj_cconv.h +1 -1
  104. data/lua-hooks/ext/luajit/src/lj_cdata.c +10 -1
  105. data/lua-hooks/ext/luajit/src/lj_cdata.h +3 -1
  106. data/lua-hooks/ext/luajit/src/lj_clib.c +1 -1
  107. data/lua-hooks/ext/luajit/src/lj_clib.h +1 -1
  108. data/lua-hooks/ext/luajit/src/lj_cparse.c +27 -6
  109. data/lua-hooks/ext/luajit/src/lj_cparse.h +1 -1
  110. data/lua-hooks/ext/luajit/src/lj_crecord.c +1 -1
  111. data/lua-hooks/ext/luajit/src/lj_crecord.h +1 -1
  112. data/lua-hooks/ext/luajit/src/lj_ctype.c +10 -8
  113. data/lua-hooks/ext/luajit/src/lj_ctype.h +1 -1
  114. data/lua-hooks/ext/luajit/src/lj_debug.c +1 -1
  115. data/lua-hooks/ext/luajit/src/lj_debug.h +1 -1
  116. data/lua-hooks/ext/luajit/src/lj_def.h +1 -1
  117. data/lua-hooks/ext/luajit/src/lj_dispatch.c +1 -1
  118. data/lua-hooks/ext/luajit/src/lj_dispatch.h +21 -4
  119. data/lua-hooks/ext/luajit/src/lj_emit_arm.h +1 -1
  120. data/lua-hooks/ext/luajit/src/lj_emit_mips.h +7 -5
  121. data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +1 -1
  122. data/lua-hooks/ext/luajit/src/lj_emit_x86.h +1 -1
  123. data/lua-hooks/ext/luajit/src/lj_err.c +69 -31
  124. data/lua-hooks/ext/luajit/src/lj_err.h +1 -1
  125. data/lua-hooks/ext/luajit/src/lj_errmsg.h +1 -1
  126. data/lua-hooks/ext/luajit/src/lj_ff.h +1 -1
  127. data/lua-hooks/ext/luajit/src/lj_ffrecord.c +10 -40
  128. data/lua-hooks/ext/luajit/src/lj_ffrecord.h +1 -1
  129. data/lua-hooks/ext/luajit/src/lj_frame.h +12 -1
  130. data/lua-hooks/ext/luajit/src/lj_func.c +1 -1
  131. data/lua-hooks/ext/luajit/src/lj_func.h +1 -1
  132. data/lua-hooks/ext/luajit/src/lj_gc.c +2 -2
  133. data/lua-hooks/ext/luajit/src/lj_gc.h +1 -1
  134. data/lua-hooks/ext/luajit/src/lj_gdbjit.c +1 -1
  135. data/lua-hooks/ext/luajit/src/lj_gdbjit.h +1 -1
  136. data/lua-hooks/ext/luajit/src/lj_ir.c +31 -15
  137. data/lua-hooks/ext/luajit/src/lj_ir.h +1 -1
  138. data/lua-hooks/ext/luajit/src/lj_ircall.h +29 -1
  139. data/lua-hooks/ext/luajit/src/lj_iropt.h +2 -1
  140. data/lua-hooks/ext/luajit/src/lj_jit.h +2 -1
  141. data/lua-hooks/ext/luajit/src/lj_lex.c +28 -1
  142. data/lua-hooks/ext/luajit/src/lj_lex.h +1 -1
  143. data/lua-hooks/ext/luajit/src/lj_lib.c +1 -1
  144. data/lua-hooks/ext/luajit/src/lj_lib.h +1 -1
  145. data/lua-hooks/ext/luajit/src/lj_load.c +1 -1
  146. data/lua-hooks/ext/luajit/src/lj_mcode.c +1 -1
  147. data/lua-hooks/ext/luajit/src/lj_mcode.h +1 -1
  148. data/lua-hooks/ext/luajit/src/lj_meta.c +8 -8
  149. data/lua-hooks/ext/luajit/src/lj_meta.h +1 -1
  150. data/lua-hooks/ext/luajit/src/lj_obj.c +1 -1
  151. data/lua-hooks/ext/luajit/src/lj_obj.h +1 -1
  152. data/lua-hooks/ext/luajit/src/lj_opt_dce.c +1 -1
  153. data/lua-hooks/ext/luajit/src/lj_opt_fold.c +1 -1
  154. data/lua-hooks/ext/luajit/src/lj_opt_loop.c +1 -1
  155. data/lua-hooks/ext/luajit/src/lj_opt_mem.c +1 -1
  156. data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +1 -1
  157. data/lua-hooks/ext/luajit/src/lj_opt_sink.c +1 -1
  158. data/lua-hooks/ext/luajit/src/lj_opt_split.c +10 -5
  159. data/lua-hooks/ext/luajit/src/lj_parse.c +1 -1
  160. data/lua-hooks/ext/luajit/src/lj_parse.h +1 -1
  161. data/lua-hooks/ext/luajit/src/lj_profile.c +1 -1
  162. data/lua-hooks/ext/luajit/src/lj_profile.h +1 -1
  163. data/lua-hooks/ext/luajit/src/lj_record.c +13 -5
  164. data/lua-hooks/ext/luajit/src/lj_record.h +1 -1
  165. data/lua-hooks/ext/luajit/src/lj_snap.c +20 -23
  166. data/lua-hooks/ext/luajit/src/lj_snap.h +1 -1
  167. data/lua-hooks/ext/luajit/src/lj_state.c +1 -1
  168. data/lua-hooks/ext/luajit/src/lj_state.h +1 -1
  169. data/lua-hooks/ext/luajit/src/lj_str.c +1 -1
  170. data/lua-hooks/ext/luajit/src/lj_str.h +1 -1
  171. data/lua-hooks/ext/luajit/src/lj_strfmt.c +12 -98
  172. data/lua-hooks/ext/luajit/src/lj_strfmt.h +4 -4
  173. data/lua-hooks/ext/luajit/src/lj_strfmt_num.c +591 -0
  174. data/lua-hooks/ext/luajit/src/lj_strscan.c +1 -1
  175. data/lua-hooks/ext/luajit/src/lj_strscan.h +1 -1
  176. data/lua-hooks/ext/luajit/src/lj_tab.c +1 -1
  177. data/lua-hooks/ext/luajit/src/lj_tab.h +1 -1
  178. data/lua-hooks/ext/luajit/src/lj_target.h +1 -1
  179. data/lua-hooks/ext/luajit/src/lj_target_arm.h +1 -1
  180. data/lua-hooks/ext/luajit/src/lj_target_arm64.h +1 -1
  181. data/lua-hooks/ext/luajit/src/lj_target_mips.h +30 -2
  182. data/lua-hooks/ext/luajit/src/lj_target_ppc.h +1 -1
  183. data/lua-hooks/ext/luajit/src/lj_target_x86.h +1 -1
  184. data/lua-hooks/ext/luajit/src/lj_trace.c +7 -2
  185. data/lua-hooks/ext/luajit/src/lj_trace.h +1 -1
  186. data/lua-hooks/ext/luajit/src/lj_traceerr.h +1 -3
  187. data/lua-hooks/ext/luajit/src/lj_udata.c +1 -1
  188. data/lua-hooks/ext/luajit/src/lj_udata.h +1 -1
  189. data/lua-hooks/ext/luajit/src/lj_vm.h +5 -3
  190. data/lua-hooks/ext/luajit/src/lj_vmevent.c +1 -1
  191. data/lua-hooks/ext/luajit/src/lj_vmevent.h +1 -1
  192. data/lua-hooks/ext/luajit/src/lj_vmmath.c +15 -15
  193. data/lua-hooks/ext/luajit/src/ljamalg.c +2 -1
  194. data/lua-hooks/ext/luajit/src/lua.h +1 -0
  195. data/lua-hooks/ext/luajit/src/luaconf.h +2 -2
  196. data/lua-hooks/ext/luajit/src/luajit.c +1 -1
  197. data/lua-hooks/ext/luajit/src/luajit.h +4 -4
  198. data/lua-hooks/ext/luajit/src/lualib.h +1 -1
  199. data/lua-hooks/ext/luajit/src/msvcbuild.bat +1 -1
  200. data/lua-hooks/ext/luajit/src/ps4build.bat +26 -6
  201. data/lua-hooks/ext/luajit/src/vm_arm.dasc +17 -9
  202. data/lua-hooks/ext/luajit/src/vm_arm64.dasc +1 -1
  203. data/lua-hooks/ext/luajit/src/vm_mips.dasc +1562 -656
  204. data/lua-hooks/ext/luajit/src/vm_ppc.dasc +3 -7
  205. data/lua-hooks/ext/luajit/src/vm_x64.dasc +10 -2
  206. data/lua-hooks/ext/luajit/src/vm_x86.dasc +5 -8
  207. data/lua-hooks/ext/luautf8/module.mk +2 -0
  208. data/lua-hooks/ext/module.mk +15 -0
  209. data/lua-hooks/ext/modules.h +17 -0
  210. data/lua-hooks/ext/perf/luacpu.c +1 -1
  211. data/lua-hooks/ext/perf/lualoadavg.c +1 -1
  212. data/lua-hooks/ext/perf/luameminfo.c +1 -1
  213. data/lua-hooks/ext/perf/luaoslib.c +124 -2
  214. data/lua-hooks/ext/perf/module.mk +5 -0
  215. data/lua-hooks/ext/sha1/luasha1.c +4 -2
  216. data/lua-hooks/ext/sha1/module.mk +5 -0
  217. data/lua-hooks/ext/sha2/luasha256.c +4 -2
  218. data/lua-hooks/ext/sha2/module.mk +5 -0
  219. data/lua-hooks/ext/sysutils/lua_utils.c +56 -0
  220. data/lua-hooks/ext/sysutils/module.mk +2 -0
  221. data/lua-hooks/lib/boot.lua +2 -1
  222. data/lua-hooks/lib/hooks/module.mk +31 -0
  223. data/lua-hooks/lib/hooks/xss/module.mk +4 -0
  224. data/lua-hooks/lib/lexers/module.mk +10 -0
  225. data/lua-hooks/lib/module.mk +38 -0
  226. data/lua-hooks/lib/schema/module.mk +3 -0
  227. data/lua-hooks/options.mk +59 -0
  228. metadata +21 -2
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  ** String formatting.
3
- ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
3
+ ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
4
4
  */
5
5
 
6
6
  #ifndef _LJ_STRFMT_H
@@ -64,11 +64,12 @@ typedef enum FormatType {
64
64
  #define STRFMT_S (STRFMT_STR)
65
65
  #define STRFMT_U (STRFMT_UINT)
66
66
  #define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX)
67
+ #define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC))
67
68
 
68
69
  /* Maximum buffer sizes for conversions. */
69
70
  #define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */
70
71
  #define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */
71
- #define STRFMT_MAXBUF_NUM LUAI_MAXNUMBER2STR
72
+ #define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */
72
73
  #define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */
73
74
 
74
75
  /* Format parser. */
@@ -83,10 +84,9 @@ static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len)
83
84
 
84
85
  /* Raw conversions. */
85
86
  LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k);
86
- LJ_FUNC char * LJ_FASTCALL lj_strfmt_wnum(char *p, cTValue *o);
87
87
  LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v);
88
88
  LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v);
89
- LJ_FUNC const char *lj_strfmt_wstrnum(char *buf, cTValue *o, MSize *lenp);
89
+ LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp);
90
90
 
91
91
  /* Unformatted conversions to buffer. */
92
92
  LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k);
@@ -0,0 +1,591 @@
1
+ /*
2
+ ** String formatting for floating-point numbers.
3
+ ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
4
+ ** Contributed by Peter Cawley.
5
+ */
6
+
7
+ #include <stdio.h>
8
+
9
+ #define lj_strfmt_num_c
10
+ #define LUA_CORE
11
+
12
+ #include "lj_obj.h"
13
+ #include "lj_buf.h"
14
+ #include "lj_str.h"
15
+ #include "lj_strfmt.h"
16
+
17
+ /* -- Precomputed tables -------------------------------------------------- */
18
+
19
+ /* Rescale factors to push the exponent of a number towards zero. */
20
+ #define RESCALE_EXPONENTS(P, N) \
21
+ P(308), P(289), P(270), P(250), P(231), P(212), P(193), P(173), P(154), \
22
+ P(135), P(115), P(96), P(77), P(58), P(38), P(0), P(0), P(0), N(39), N(58), \
23
+ N(77), N(96), N(116), N(135), N(154), N(174), N(193), N(212), N(231), \
24
+ N(251), N(270), N(289)
25
+
26
+ #define ONE_E_P(X) 1e+0 ## X
27
+ #define ONE_E_N(X) 1e-0 ## X
28
+ static const int16_t rescale_e[] = { RESCALE_EXPONENTS(-, +) };
29
+ static const double rescale_n[] = { RESCALE_EXPONENTS(ONE_E_P, ONE_E_N) };
30
+ #undef ONE_E_N
31
+ #undef ONE_E_P
32
+
33
+ /*
34
+ ** For p in range -70 through 57, this table encodes pairs (m, e) such that
35
+ ** 4*2^p <= (uint8_t)m*10^e, and is the smallest value for which this holds.
36
+ */
37
+ static const int8_t four_ulp_m_e[] = {
38
+ 34, -21, 68, -21, 14, -20, 28, -20, 55, -20, 2, -19, 3, -19, 5, -19, 9, -19,
39
+ -82, -18, 35, -18, 7, -17, -117, -17, 28, -17, 56, -17, 112, -16, -33, -16,
40
+ 45, -16, 89, -16, -78, -15, 36, -15, 72, -15, -113, -14, 29, -14, 57, -14,
41
+ 114, -13, -28, -13, 46, -13, 91, -12, -74, -12, 37, -12, 73, -12, 15, -11, 3,
42
+ -11, 59, -11, 2, -10, 3, -10, 5, -10, 1, -9, -69, -9, 38, -9, 75, -9, 15, -7,
43
+ 3, -7, 6, -7, 12, -6, -17, -7, 48, -7, 96, -7, -65, -6, 39, -6, 77, -6, -103,
44
+ -5, 31, -5, 62, -5, 123, -4, -11, -4, 49, -4, 98, -4, -60, -3, 4, -2, 79, -3,
45
+ 16, -2, 32, -2, 63, -2, 2, -1, 25, 0, 5, 1, 1, 2, 2, 2, 4, 2, 8, 2, 16, 2,
46
+ 32, 2, 64, 2, -128, 2, 26, 2, 52, 2, 103, 3, -51, 3, 41, 4, 82, 4, -92, 4,
47
+ 33, 4, 66, 4, -124, 5, 27, 5, 53, 5, 105, 6, 21, 6, 42, 6, 84, 6, 17, 7, 34,
48
+ 7, 68, 7, 2, 8, 3, 8, 6, 8, 108, 9, -41, 9, 43, 10, 86, 9, -84, 10, 35, 10,
49
+ 69, 10, -118, 11, 28, 11, 55, 12, 11, 13, 22, 13, 44, 13, 88, 13, -80, 13,
50
+ 36, 13, 71, 13, -115, 14, 29, 14, 57, 14, 113, 15, -30, 15, 46, 15, 91, 15,
51
+ 19, 16, 37, 16, 73, 16, 2, 17, 3, 17, 6, 17
52
+ };
53
+
54
+ /* min(2^32-1, 10^e-1) for e in range 0 through 10 */
55
+ static uint32_t ndigits_dec_threshold[] = {
56
+ 0, 9U, 99U, 999U, 9999U, 99999U, 999999U,
57
+ 9999999U, 99999999U, 999999999U, 0xffffffffU
58
+ };
59
+
60
+ /* -- Helper functions ---------------------------------------------------- */
61
+
62
+ /* Compute the number of digits in the decimal representation of x. */
63
+ static MSize ndigits_dec(uint32_t x)
64
+ {
65
+ MSize t = ((lj_fls(x | 1) * 77) >> 8) + 1; /* 2^8/77 is roughly log2(10) */
66
+ return t + (x > ndigits_dec_threshold[t]);
67
+ }
68
+
69
+ #define WINT_R(x, sh, sc) \
70
+ { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); }
71
+
72
+ /* Write 9-digit unsigned integer to buffer. */
73
+ static char *lj_strfmt_wuint9(char *p, uint32_t u)
74
+ {
75
+ uint32_t v = u / 10000, w;
76
+ u -= v * 10000;
77
+ w = v / 10000;
78
+ v -= w * 10000;
79
+ *p++ = (char)('0'+w);
80
+ WINT_R(v, 23, 1000)
81
+ WINT_R(v, 12, 100)
82
+ WINT_R(v, 10, 10)
83
+ *p++ = (char)('0'+v);
84
+ WINT_R(u, 23, 1000)
85
+ WINT_R(u, 12, 100)
86
+ WINT_R(u, 10, 10)
87
+ *p++ = (char)('0'+u);
88
+ return p;
89
+ }
90
+ #undef WINT_R
91
+
92
+ /* -- Extended precision arithmetic --------------------------------------- */
93
+
94
+ /*
95
+ ** The "nd" format is a fixed-precision decimal representation for numbers. It
96
+ ** consists of up to 64 uint32_t values, with each uint32_t storing a value
97
+ ** in the range [0, 1e9). A number in "nd" format consists of three variables:
98
+ **
99
+ ** uint32_t nd[64];
100
+ ** uint32_t ndlo;
101
+ ** uint32_t ndhi;
102
+ **
103
+ ** The integral part of the number is stored in nd[0 ... ndhi], the value of
104
+ ** which is sum{i in [0, ndhi] | nd[i] * 10^(9*i)}. If the fractional part of
105
+ ** the number is zero, ndlo is zero. Otherwise, the fractional part is stored
106
+ ** in nd[ndlo ... 63], the value of which is taken to be
107
+ ** sum{i in [ndlo, 63] | nd[i] * 10^(9*(i-64))}.
108
+ **
109
+ ** If the array part had 128 elements rather than 64, then every double would
110
+ ** have an exact representation in "nd" format. With 64 elements, all integral
111
+ ** doubles have an exact representation, and all non-integral doubles have
112
+ ** enough digits to make both %.99e and %.99f do the right thing.
113
+ */
114
+
115
+ #if LJ_64
116
+ #define ND_MUL2K_MAX_SHIFT 29
117
+ #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) / 1000000000))
118
+ #else
119
+ #define ND_MUL2K_MAX_SHIFT 11
120
+ #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) >> 9) / 1953125)
121
+ #endif
122
+
123
+ /* Multiply nd by 2^k and add carry_in (ndlo is assumed to be zero). */
124
+ static uint32_t nd_mul2k(uint32_t* nd, uint32_t ndhi, uint32_t k,
125
+ uint32_t carry_in, SFormat sf)
126
+ {
127
+ uint32_t i, ndlo = 0, start = 1;
128
+ /* Performance hacks. */
129
+ if (k > ND_MUL2K_MAX_SHIFT*2 && STRFMT_FP(sf) != STRFMT_FP(STRFMT_T_FP_F)) {
130
+ start = ndhi - (STRFMT_PREC(sf) + 17) / 8;
131
+ }
132
+ /* Real logic. */
133
+ while (k >= ND_MUL2K_MAX_SHIFT) {
134
+ for (i = ndlo; i <= ndhi; i++) {
135
+ uint64_t val = ((uint64_t)nd[i] << ND_MUL2K_MAX_SHIFT) | carry_in;
136
+ carry_in = ND_MUL2K_DIV1E9(val);
137
+ nd[i] = (uint32_t)val - carry_in * 1000000000;
138
+ }
139
+ if (carry_in) {
140
+ nd[++ndhi] = carry_in; carry_in = 0;
141
+ if(start++ == ndlo) ++ndlo;
142
+ }
143
+ k -= ND_MUL2K_MAX_SHIFT;
144
+ }
145
+ if (k) {
146
+ for (i = ndlo; i <= ndhi; i++) {
147
+ uint64_t val = ((uint64_t)nd[i] << k) | carry_in;
148
+ carry_in = ND_MUL2K_DIV1E9(val);
149
+ nd[i] = (uint32_t)val - carry_in * 1000000000;
150
+ }
151
+ if (carry_in) nd[++ndhi] = carry_in;
152
+ }
153
+ return ndhi;
154
+ }
155
+
156
+ /* Divide nd by 2^k (ndlo is assumed to be zero). */
157
+ static uint32_t nd_div2k(uint32_t* nd, uint32_t ndhi, uint32_t k, SFormat sf)
158
+ {
159
+ uint32_t ndlo = 0, stop1 = ~0, stop2 = ~0;
160
+ /* Performance hacks. */
161
+ if (!ndhi) {
162
+ if (!nd[0]) {
163
+ return 0;
164
+ } else {
165
+ uint32_t s = lj_ffs(nd[0]);
166
+ if (s >= k) { nd[0] >>= k; return 0; }
167
+ nd[0] >>= s; k -= s;
168
+ }
169
+ }
170
+ if (k > 18) {
171
+ if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_F)) {
172
+ stop1 = 63 - (int32_t)STRFMT_PREC(sf) / 9;
173
+ } else {
174
+ int32_t floorlog2 = ndhi * 29 + lj_fls(nd[ndhi]) - k;
175
+ int32_t floorlog10 = (int32_t)(floorlog2 * 0.30102999566398114);
176
+ stop1 = 62 + (floorlog10 - (int32_t)STRFMT_PREC(sf)) / 9;
177
+ stop2 = 61 + ndhi - (int32_t)STRFMT_PREC(sf) / 8;
178
+ }
179
+ }
180
+ /* Real logic. */
181
+ while (k >= 9) {
182
+ uint32_t i = ndhi, carry = 0;
183
+ for (;;) {
184
+ uint32_t val = nd[i];
185
+ nd[i] = (val >> 9) + carry;
186
+ carry = (val & 0x1ff) * 1953125;
187
+ if (i == ndlo) break;
188
+ i = (i - 1) & 0x3f;
189
+ }
190
+ if (ndlo != stop1 && ndlo != stop2) {
191
+ if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; }
192
+ if (!nd[ndhi]) { ndhi = (ndhi - 1) & 0x3f; stop2--; }
193
+ } else if (!nd[ndhi]) {
194
+ if (ndhi != ndlo) { ndhi = (ndhi - 1) & 0x3f; stop2--; }
195
+ else return ndlo;
196
+ }
197
+ k -= 9;
198
+ }
199
+ if (k) {
200
+ uint32_t mask = (1U << k) - 1, mul = 1000000000 >> k, i = ndhi, carry = 0;
201
+ for (;;) {
202
+ uint32_t val = nd[i];
203
+ nd[i] = (val >> k) + carry;
204
+ carry = (val & mask) * mul;
205
+ if (i == ndlo) break;
206
+ i = (i - 1) & 0x3f;
207
+ }
208
+ if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; }
209
+ }
210
+ return ndlo;
211
+ }
212
+
213
+ /* Add m*10^e to nd (assumes ndlo <= e/9 <= ndhi and 0 <= m <= 9). */
214
+ static uint32_t nd_add_m10e(uint32_t* nd, uint32_t ndhi, uint8_t m, int32_t e)
215
+ {
216
+ uint32_t i, carry;
217
+ if (e >= 0) {
218
+ i = (uint32_t)e/9;
219
+ carry = m * (ndigits_dec_threshold[e - (int32_t)i*9] + 1);
220
+ } else {
221
+ int32_t f = (e-8)/9;
222
+ i = (uint32_t)(64 + f);
223
+ carry = m * (ndigits_dec_threshold[e - f*9] + 1);
224
+ }
225
+ for (;;) {
226
+ uint32_t val = nd[i] + carry;
227
+ if (LJ_UNLIKELY(val >= 1000000000)) {
228
+ val -= 1000000000;
229
+ nd[i] = val;
230
+ if (LJ_UNLIKELY(i == ndhi)) {
231
+ ndhi = (ndhi + 1) & 0x3f;
232
+ nd[ndhi] = 1;
233
+ break;
234
+ }
235
+ carry = 1;
236
+ i = (i + 1) & 0x3f;
237
+ } else {
238
+ nd[i] = val;
239
+ break;
240
+ }
241
+ }
242
+ return ndhi;
243
+ }
244
+
245
+ /* Test whether two "nd" values are equal in their most significant digits. */
246
+ static int nd_similar(uint32_t* nd, uint32_t ndhi, uint32_t* ref, MSize hilen,
247
+ MSize prec)
248
+ {
249
+ char nd9[9], ref9[9];
250
+ if (hilen <= prec) {
251
+ if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0;
252
+ prec -= hilen; ref--; ndhi = (ndhi - 1) & 0x3f;
253
+ if (prec >= 9) {
254
+ if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0;
255
+ prec -= 9; ref--; ndhi = (ndhi - 1) & 0x3f;
256
+ }
257
+ } else {
258
+ prec -= hilen - 9;
259
+ }
260
+ lua_assert(prec < 9);
261
+ lj_strfmt_wuint9(nd9, nd[ndhi]);
262
+ lj_strfmt_wuint9(ref9, *ref);
263
+ return !memcmp(nd9, ref9, prec) && (nd9[prec] < '5') == (ref9[prec] < '5');
264
+ }
265
+
266
+ /* -- Formatted conversions to buffer ------------------------------------- */
267
+
268
+ /* Write formatted floating-point number to either sb or p. */
269
+ static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p)
270
+ {
271
+ MSize width = STRFMT_WIDTH(sf), prec = STRFMT_PREC(sf), len;
272
+ TValue t;
273
+ t.n = n;
274
+ if (LJ_UNLIKELY((t.u32.hi << 1) >= 0xffe00000)) {
275
+ /* Handle non-finite values uniformly for %a, %e, %f, %g. */
276
+ int prefix = 0, ch = (sf & STRFMT_F_UPPER) ? 0x202020 : 0;
277
+ if (((t.u32.hi & 0x000fffff) | t.u32.lo) != 0) {
278
+ ch ^= ('n' << 16) | ('a' << 8) | 'n';
279
+ if ((sf & STRFMT_F_SPACE)) prefix = ' ';
280
+ } else {
281
+ ch ^= ('i' << 16) | ('n' << 8) | 'f';
282
+ if ((t.u32.hi & 0x80000000)) prefix = '-';
283
+ else if ((sf & STRFMT_F_PLUS)) prefix = '+';
284
+ else if ((sf & STRFMT_F_SPACE)) prefix = ' ';
285
+ }
286
+ len = 3 + (prefix != 0);
287
+ if (!p) p = lj_buf_more(sb, width > len ? width : len);
288
+ if (!(sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' ';
289
+ if (prefix) *p++ = prefix;
290
+ *p++ = (char)(ch >> 16); *p++ = (char)(ch >> 8); *p++ = (char)ch;
291
+ } else if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_A)) {
292
+ /* %a */
293
+ const char *hexdig = (sf & STRFMT_F_UPPER) ? "0123456789ABCDEFPX"
294
+ : "0123456789abcdefpx";
295
+ int32_t e = (t.u32.hi >> 20) & 0x7ff;
296
+ char prefix = 0, eprefix = '+';
297
+ if (t.u32.hi & 0x80000000) prefix = '-';
298
+ else if ((sf & STRFMT_F_PLUS)) prefix = '+';
299
+ else if ((sf & STRFMT_F_SPACE)) prefix = ' ';
300
+ t.u32.hi &= 0xfffff;
301
+ if (e) {
302
+ t.u32.hi |= 0x100000;
303
+ e -= 1023;
304
+ } else if (t.u32.lo | t.u32.hi) {
305
+ /* Non-zero denormal - normalise it. */
306
+ uint32_t shift = t.u32.hi ? 20-lj_fls(t.u32.hi) : 52-lj_fls(t.u32.lo);
307
+ e = -1022 - shift;
308
+ t.u64 <<= shift;
309
+ }
310
+ /* abs(n) == t.u64 * 2^(e - 52) */
311
+ /* If n != 0, bit 52 of t.u64 is set, and is the highest set bit. */
312
+ if ((int32_t)prec < 0) {
313
+ /* Default precision: use smallest precision giving exact result. */
314
+ prec = t.u32.lo ? 13-lj_ffs(t.u32.lo)/4 : 5-lj_ffs(t.u32.hi|0x100000)/4;
315
+ } else if (prec < 13) {
316
+ /* Precision is sufficiently low as to maybe require rounding. */
317
+ t.u64 += (((uint64_t)1) << (51 - prec*4));
318
+ }
319
+ if (e < 0) {
320
+ eprefix = '-';
321
+ e = -e;
322
+ }
323
+ len = 5 + ndigits_dec((uint32_t)e) + prec + (prefix != 0)
324
+ + ((prec | (sf & STRFMT_F_ALT)) != 0);
325
+ if (!p) p = lj_buf_more(sb, width > len ? width : len);
326
+ if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) {
327
+ while (width-- > len) *p++ = ' ';
328
+ }
329
+ if (prefix) *p++ = prefix;
330
+ *p++ = '0';
331
+ *p++ = hexdig[17]; /* x or X */
332
+ if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) {
333
+ while (width-- > len) *p++ = '0';
334
+ }
335
+ *p++ = '0' + (t.u32.hi >> 20); /* Usually '1', sometimes '0' or '2'. */
336
+ if ((prec | (sf & STRFMT_F_ALT))) {
337
+ /* Emit fractional part. */
338
+ char *q = p + 1 + prec;
339
+ *p = '.';
340
+ if (prec < 13) t.u64 >>= (52 - prec*4);
341
+ else while (prec > 13) p[prec--] = '0';
342
+ while (prec) { p[prec--] = hexdig[t.u64 & 15]; t.u64 >>= 4; }
343
+ p = q;
344
+ }
345
+ *p++ = hexdig[16]; /* p or P */
346
+ *p++ = eprefix; /* + or - */
347
+ p = lj_strfmt_wint(p, e);
348
+ } else {
349
+ /* %e or %f or %g - begin by converting n to "nd" format. */
350
+ uint32_t nd[64];
351
+ uint32_t ndhi = 0, ndlo, i;
352
+ int32_t e = (t.u32.hi >> 20) & 0x7ff, ndebias = 0;
353
+ char prefix = 0, *q;
354
+ if (t.u32.hi & 0x80000000) prefix = '-';
355
+ else if ((sf & STRFMT_F_PLUS)) prefix = '+';
356
+ else if ((sf & STRFMT_F_SPACE)) prefix = ' ';
357
+ prec += ((int32_t)prec >> 31) & 7; /* Default precision is 6. */
358
+ if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_G)) {
359
+ /* %g - decrement precision if non-zero (to make it like %e). */
360
+ prec--;
361
+ prec ^= (uint32_t)((int32_t)prec >> 31);
362
+ }
363
+ if ((sf & STRFMT_T_FP_E) && prec < 14 && n != 0) {
364
+ /* Precision is sufficiently low that rescaling will probably work. */
365
+ if ((ndebias = rescale_e[e >> 6])) {
366
+ t.n = n * rescale_n[e >> 6];
367
+ t.u64 -= 2; /* Convert 2ulp below (later we convert 2ulp above). */
368
+ nd[0] = 0x100000 | (t.u32.hi & 0xfffff);
369
+ e = ((t.u32.hi >> 20) & 0x7ff) - 1075 - (ND_MUL2K_MAX_SHIFT < 29);
370
+ goto load_t_lo; rescale_failed:
371
+ t.n = n;
372
+ e = (t.u32.hi >> 20) & 0x7ff;
373
+ ndebias = ndhi = 0;
374
+ }
375
+ }
376
+ nd[0] = t.u32.hi & 0xfffff;
377
+ if (e == 0) e++; else nd[0] |= 0x100000;
378
+ e -= 1043;
379
+ if (t.u32.lo) {
380
+ e -= 32 + (ND_MUL2K_MAX_SHIFT < 29); load_t_lo:
381
+ #if ND_MUL2K_MAX_SHIFT >= 29
382
+ nd[0] = (nd[0] << 3) | (t.u32.lo >> 29);
383
+ ndhi = nd_mul2k(nd, ndhi, 29, t.u32.lo & 0x1fffffff, sf);
384
+ #elif ND_MUL2K_MAX_SHIFT >= 11
385
+ ndhi = nd_mul2k(nd, ndhi, 11, t.u32.lo >> 21, sf);
386
+ ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo >> 10) & 0x7ff, sf);
387
+ ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo << 1) & 0x7ff, sf);
388
+ #else
389
+ #error "ND_MUL2K_MAX_SHIFT too small"
390
+ #endif
391
+ }
392
+ if (e >= 0) {
393
+ ndhi = nd_mul2k(nd, ndhi, (uint32_t)e, 0, sf);
394
+ ndlo = 0;
395
+ } else {
396
+ ndlo = nd_div2k(nd, ndhi, (uint32_t)-e, sf);
397
+ if (ndhi && !nd[ndhi]) ndhi--;
398
+ }
399
+ /* abs(n) == nd * 10^ndebias (for slightly loose interpretation of ==) */
400
+ if ((sf & STRFMT_T_FP_E)) {
401
+ /* %e or %g - assume %e and start by calculating nd's exponent (nde). */
402
+ char eprefix = '+';
403
+ int32_t nde = -1;
404
+ MSize hilen;
405
+ if (ndlo && !nd[ndhi]) {
406
+ ndhi = 64; do {} while (!nd[--ndhi]);
407
+ nde -= 64 * 9;
408
+ }
409
+ hilen = ndigits_dec(nd[ndhi]);
410
+ nde += ndhi * 9 + hilen;
411
+ if (ndebias) {
412
+ /*
413
+ ** Rescaling was performed, but this introduced some error, and might
414
+ ** have pushed us across a rounding boundary. We check whether this
415
+ ** error affected the result by introducing even more error (2ulp in
416
+ ** either direction), and seeing whether a roundary boundary was
417
+ ** crossed. Having already converted the -2ulp case, we save off its
418
+ ** most significant digits, convert the +2ulp case, and compare them.
419
+ */
420
+ int32_t eidx = e + 70 + (ND_MUL2K_MAX_SHIFT < 29)
421
+ + (t.u32.lo >= 0xfffffffe && !(~t.u32.hi << 12));
422
+ const int8_t *m_e = four_ulp_m_e + eidx * 2;
423
+ lua_assert(0 <= eidx && eidx < 128);
424
+ nd[33] = nd[ndhi];
425
+ nd[32] = nd[(ndhi - 1) & 0x3f];
426
+ nd[31] = nd[(ndhi - 2) & 0x3f];
427
+ nd_add_m10e(nd, ndhi, (uint8_t)*m_e, m_e[1]);
428
+ if (LJ_UNLIKELY(!nd_similar(nd, ndhi, nd + 33, hilen, prec + 1))) {
429
+ goto rescale_failed;
430
+ }
431
+ }
432
+ if ((int32_t)(prec - nde) < (0x3f & -(int32_t)ndlo) * 9) {
433
+ /* Precision is sufficiently low as to maybe require rounding. */
434
+ ndhi = nd_add_m10e(nd, ndhi, 5, nde - prec - 1);
435
+ nde += (hilen != ndigits_dec(nd[ndhi]));
436
+ }
437
+ nde += ndebias;
438
+ if ((sf & STRFMT_T_FP_F)) {
439
+ /* %g */
440
+ if ((int32_t)prec >= nde && nde >= -4) {
441
+ if (nde < 0) ndhi = 0;
442
+ prec -= nde;
443
+ goto g_format_like_f;
444
+ } else if (!(sf & STRFMT_F_ALT) && prec && width > 5) {
445
+ /* Decrease precision in order to strip trailing zeroes. */
446
+ char tail[9];
447
+ uint32_t maxprec = hilen - 1 + ((ndhi - ndlo) & 0x3f) * 9;
448
+ if (prec >= maxprec) prec = maxprec;
449
+ else ndlo = (ndhi - (((int32_t)(prec - hilen) + 9) / 9)) & 0x3f;
450
+ i = prec - hilen - (((ndhi - ndlo) & 0x3f) * 9) + 10;
451
+ lj_strfmt_wuint9(tail, nd[ndlo]);
452
+ while (prec && tail[--i] == '0') {
453
+ prec--;
454
+ if (!i) {
455
+ if (ndlo == ndhi) { prec = 0; break; }
456
+ lj_strfmt_wuint9(tail, nd[++ndlo]);
457
+ i = 9;
458
+ }
459
+ }
460
+ }
461
+ }
462
+ if (nde < 0) {
463
+ /* Make nde non-negative. */
464
+ eprefix = '-';
465
+ nde = -nde;
466
+ }
467
+ len = 3 + prec + (prefix != 0) + ndigits_dec((uint32_t)nde) + (nde < 10)
468
+ + ((prec | (sf & STRFMT_F_ALT)) != 0);
469
+ if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 5);
470
+ if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) {
471
+ while (width-- > len) *p++ = ' ';
472
+ }
473
+ if (prefix) *p++ = prefix;
474
+ if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) {
475
+ while (width-- > len) *p++ = '0';
476
+ }
477
+ q = lj_strfmt_wint(p + 1, nd[ndhi]);
478
+ p[0] = p[1]; /* Put leading digit in the correct place. */
479
+ if ((prec | (sf & STRFMT_F_ALT))) {
480
+ /* Emit fractional part. */
481
+ p[1] = '.'; p += 2;
482
+ prec -= (q - p); p = q; /* Account for the digits already emitted. */
483
+ /* Then emit chunks of 9 digits (this may emit 8 digits too many). */
484
+ for (i = ndhi; (int32_t)prec > 0 && i != ndlo; prec -= 9) {
485
+ i = (i - 1) & 0x3f;
486
+ p = lj_strfmt_wuint9(p, nd[i]);
487
+ }
488
+ if ((sf & STRFMT_T_FP_F) && !(sf & STRFMT_F_ALT)) {
489
+ /* %g (and not %#g) - strip trailing zeroes. */
490
+ p += (int32_t)prec & ((int32_t)prec >> 31);
491
+ while (p[-1] == '0') p--;
492
+ if (p[-1] == '.') p--;
493
+ } else {
494
+ /* %e (or %#g) - emit trailing zeroes. */
495
+ while ((int32_t)prec > 0) { *p++ = '0'; prec--; }
496
+ p += (int32_t)prec;
497
+ }
498
+ } else {
499
+ p++;
500
+ }
501
+ *p++ = (sf & STRFMT_F_UPPER) ? 'E' : 'e';
502
+ *p++ = eprefix; /* + or - */
503
+ if (nde < 10) *p++ = '0'; /* Always at least two digits of exponent. */
504
+ p = lj_strfmt_wint(p, nde);
505
+ } else {
506
+ /* %f (or, shortly, %g in %f style) */
507
+ if (prec < (MSize)(0x3f & -(int32_t)ndlo) * 9) {
508
+ /* Precision is sufficiently low as to maybe require rounding. */
509
+ ndhi = nd_add_m10e(nd, ndhi, 5, 0 - prec - 1);
510
+ }
511
+ g_format_like_f:
512
+ if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT) && prec && width) {
513
+ /* Decrease precision in order to strip trailing zeroes. */
514
+ if (ndlo) {
515
+ /* nd has a fractional part; we need to look at its digits. */
516
+ char tail[9];
517
+ uint32_t maxprec = (64 - ndlo) * 9;
518
+ if (prec >= maxprec) prec = maxprec;
519
+ else ndlo = 64 - (prec + 8) / 9;
520
+ i = prec - ((63 - ndlo) * 9);
521
+ lj_strfmt_wuint9(tail, nd[ndlo]);
522
+ while (prec && tail[--i] == '0') {
523
+ prec--;
524
+ if (!i) {
525
+ if (ndlo == 63) { prec = 0; break; }
526
+ lj_strfmt_wuint9(tail, nd[++ndlo]);
527
+ i = 9;
528
+ }
529
+ }
530
+ } else {
531
+ /* nd has no fractional part, so precision goes straight to zero. */
532
+ prec = 0;
533
+ }
534
+ }
535
+ len = ndhi * 9 + ndigits_dec(nd[ndhi]) + prec + (prefix != 0)
536
+ + ((prec | (sf & STRFMT_F_ALT)) != 0);
537
+ if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 8);
538
+ if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) {
539
+ while (width-- > len) *p++ = ' ';
540
+ }
541
+ if (prefix) *p++ = prefix;
542
+ if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) {
543
+ while (width-- > len) *p++ = '0';
544
+ }
545
+ /* Emit integer part. */
546
+ p = lj_strfmt_wint(p, nd[ndhi]);
547
+ i = ndhi;
548
+ while (i) p = lj_strfmt_wuint9(p, nd[--i]);
549
+ if ((prec | (sf & STRFMT_F_ALT))) {
550
+ /* Emit fractional part. */
551
+ *p++ = '.';
552
+ /* Emit chunks of 9 digits (this may emit 8 digits too many). */
553
+ while ((int32_t)prec > 0 && i != ndlo) {
554
+ i = (i - 1) & 0x3f;
555
+ p = lj_strfmt_wuint9(p, nd[i]);
556
+ prec -= 9;
557
+ }
558
+ if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT)) {
559
+ /* %g (and not %#g) - strip trailing zeroes. */
560
+ p += (int32_t)prec & ((int32_t)prec >> 31);
561
+ while (p[-1] == '0') p--;
562
+ if (p[-1] == '.') p--;
563
+ } else {
564
+ /* %f (or %#g) - emit trailing zeroes. */
565
+ while ((int32_t)prec > 0) { *p++ = '0'; prec--; }
566
+ p += (int32_t)prec;
567
+ }
568
+ }
569
+ }
570
+ }
571
+ if ((sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' ';
572
+ return p;
573
+ }
574
+
575
+ /* Add formatted floating-point number to buffer. */
576
+ SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n)
577
+ {
578
+ setsbufP(sb, lj_strfmt_wfnum(sb, sf, n, NULL));
579
+ return sb;
580
+ }
581
+
582
+ /* -- Conversions to strings ---------------------------------------------- */
583
+
584
+ /* Convert number to string. */
585
+ GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o)
586
+ {
587
+ char buf[STRFMT_MAXBUF_NUM];
588
+ MSize len = (MSize)(lj_strfmt_wfnum(NULL, STRFMT_G14, o->n, buf) - buf);
589
+ return lj_str_new(L, buf, len);
590
+ }
591
+