immunio 1.1.2 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/immunio/version.rb +1 -1
- data/lua-hooks/Makefile +56 -109
- data/lua-hooks/ext/all.c +3 -14
- data/lua-hooks/ext/libinjection/module.mk +5 -0
- data/lua-hooks/ext/lpeg/module.mk +6 -0
- data/lua-hooks/ext/lua-cmsgpack/module.mk +2 -0
- data/lua-hooks/ext/lua-snapshot/module.mk +2 -0
- data/lua-hooks/ext/luajit/COPYRIGHT +1 -1
- data/lua-hooks/ext/luajit/Makefile +2 -2
- data/lua-hooks/ext/luajit/README +2 -2
- data/lua-hooks/ext/luajit/doc/bluequad-print.css +1 -1
- data/lua-hooks/ext/luajit/doc/bluequad.css +1 -1
- data/lua-hooks/ext/luajit/doc/changes.html +15 -2
- data/lua-hooks/ext/luajit/doc/contact.html +3 -3
- data/lua-hooks/ext/luajit/doc/ext_c_api.html +2 -2
- data/lua-hooks/ext/luajit/doc/ext_ffi.html +2 -2
- data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +2 -2
- data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +4 -2
- data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +2 -2
- data/lua-hooks/ext/luajit/doc/ext_jit.html +2 -2
- data/lua-hooks/ext/luajit/doc/ext_profiler.html +2 -2
- data/lua-hooks/ext/luajit/doc/extensions.html +9 -2
- data/lua-hooks/ext/luajit/doc/faq.html +2 -2
- data/lua-hooks/ext/luajit/doc/install.html +22 -18
- data/lua-hooks/ext/luajit/doc/luajit.html +3 -3
- data/lua-hooks/ext/luajit/doc/running.html +2 -2
- data/lua-hooks/ext/luajit/doc/status.html +2 -2
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +1 -1
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +4 -4
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +1 -1
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +4 -4
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +1 -1
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +4 -4
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +1 -1
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +4 -4
- data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +3 -3
- data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +1 -1
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +34 -7
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +427 -102
- data/lua-hooks/ext/luajit/dynasm/dynasm.lua +5 -5
- data/lua-hooks/ext/luajit/etc/luajit.1 +1 -1
- data/lua-hooks/ext/luajit/etc/luajit.pc +1 -1
- data/lua-hooks/ext/luajit/src/Makefile +36 -21
- data/lua-hooks/ext/luajit/src/Makefile.dep +3 -1
- data/lua-hooks/ext/luajit/src/host/buildvm.c +1 -1
- data/lua-hooks/ext/luajit/src/host/buildvm.h +1 -1
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +10 -1
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +1 -1
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +1 -1
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +1 -1
- data/lua-hooks/ext/luajit/src/host/genlibbc.lua +1 -1
- data/lua-hooks/ext/luajit/src/host/genminilua.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/bc.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/bcsave.lua +2 -2
- data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +163 -73
- data/lua-hooks/ext/luajit/src/jit/dump.lua +2 -1
- data/lua-hooks/ext/luajit/src/jit/p.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/v.lua +1 -1
- data/lua-hooks/ext/luajit/src/jit/zone.lua +1 -1
- data/lua-hooks/ext/luajit/src/lib_aux.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_base.c +4 -5
- data/lua-hooks/ext/luajit/src/lib_bit.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_debug.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_ffi.c +2 -5
- data/lua-hooks/ext/luajit/src/lib_init.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_io.c +2 -3
- data/lua-hooks/ext/luajit/src/lib_jit.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_math.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_os.c +2 -2
- data/lua-hooks/ext/luajit/src/lib_package.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_string.c +1 -1
- data/lua-hooks/ext/luajit/src/lib_table.c +1 -1
- data/lua-hooks/ext/luajit/src/lj.supp +15 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_api.c +4 -1
- data/lua-hooks/ext/luajit/src/lj_arch.h +33 -7
- data/lua-hooks/ext/luajit/src/lj_asm.c +12 -5
- data/lua-hooks/ext/luajit/src/lj_asm.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_asm_arm.h +3 -13
- data/lua-hooks/ext/luajit/src/lj_asm_mips.h +337 -71
- data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2 -2
- data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2 -2
- data/lua-hooks/ext/luajit/src/lj_bc.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_bc.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_bcdump.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_bcread.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_bcwrite.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_buf.c +2 -4
- data/lua-hooks/ext/luajit/src/lj_buf.h +1 -3
- data/lua-hooks/ext/luajit/src/lj_carith.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_carith.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ccall.c +37 -14
- data/lua-hooks/ext/luajit/src/lj_ccall.h +3 -3
- data/lua-hooks/ext/luajit/src/lj_ccallback.c +16 -7
- data/lua-hooks/ext/luajit/src/lj_ccallback.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_cconv.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_cconv.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_cdata.c +10 -1
- data/lua-hooks/ext/luajit/src/lj_cdata.h +3 -1
- data/lua-hooks/ext/luajit/src/lj_clib.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_clib.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_cparse.c +27 -6
- data/lua-hooks/ext/luajit/src/lj_cparse.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_crecord.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_crecord.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ctype.c +10 -8
- data/lua-hooks/ext/luajit/src/lj_ctype.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_debug.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_debug.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_def.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_dispatch.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_dispatch.h +21 -4
- data/lua-hooks/ext/luajit/src/lj_emit_arm.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_emit_mips.h +7 -5
- data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_emit_x86.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_err.c +69 -31
- data/lua-hooks/ext/luajit/src/lj_err.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_errmsg.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ff.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ffrecord.c +10 -40
- data/lua-hooks/ext/luajit/src/lj_ffrecord.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_frame.h +12 -1
- data/lua-hooks/ext/luajit/src/lj_func.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_func.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_gc.c +2 -2
- data/lua-hooks/ext/luajit/src/lj_gc.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_gdbjit.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_gdbjit.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ir.c +31 -15
- data/lua-hooks/ext/luajit/src/lj_ir.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_ircall.h +29 -1
- data/lua-hooks/ext/luajit/src/lj_iropt.h +2 -1
- data/lua-hooks/ext/luajit/src/lj_jit.h +2 -1
- data/lua-hooks/ext/luajit/src/lj_lex.c +28 -1
- data/lua-hooks/ext/luajit/src/lj_lex.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_lib.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_lib.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_load.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_mcode.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_mcode.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_meta.c +8 -8
- data/lua-hooks/ext/luajit/src/lj_meta.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_obj.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_obj.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_dce.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_fold.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_loop.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_mem.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_sink.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_opt_split.c +10 -5
- data/lua-hooks/ext/luajit/src/lj_parse.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_parse.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_profile.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_profile.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_record.c +13 -5
- data/lua-hooks/ext/luajit/src/lj_record.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_snap.c +20 -23
- data/lua-hooks/ext/luajit/src/lj_snap.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_state.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_state.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_str.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_str.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_strfmt.c +12 -98
- data/lua-hooks/ext/luajit/src/lj_strfmt.h +4 -4
- data/lua-hooks/ext/luajit/src/lj_strfmt_num.c +591 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_strscan.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_tab.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_tab.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_target.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_target_arm.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_target_arm64.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_target_mips.h +30 -2
- data/lua-hooks/ext/luajit/src/lj_target_ppc.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_target_x86.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_trace.c +7 -2
- data/lua-hooks/ext/luajit/src/lj_trace.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_traceerr.h +1 -3
- data/lua-hooks/ext/luajit/src/lj_udata.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_udata.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_vm.h +5 -3
- data/lua-hooks/ext/luajit/src/lj_vmevent.c +1 -1
- data/lua-hooks/ext/luajit/src/lj_vmevent.h +1 -1
- data/lua-hooks/ext/luajit/src/lj_vmmath.c +15 -15
- data/lua-hooks/ext/luajit/src/ljamalg.c +2 -1
- data/lua-hooks/ext/luajit/src/lua.h +1 -0
- data/lua-hooks/ext/luajit/src/luaconf.h +2 -2
- data/lua-hooks/ext/luajit/src/luajit.c +1 -1
- data/lua-hooks/ext/luajit/src/luajit.h +4 -4
- data/lua-hooks/ext/luajit/src/lualib.h +1 -1
- data/lua-hooks/ext/luajit/src/msvcbuild.bat +1 -1
- data/lua-hooks/ext/luajit/src/ps4build.bat +26 -6
- data/lua-hooks/ext/luajit/src/vm_arm.dasc +17 -9
- data/lua-hooks/ext/luajit/src/vm_arm64.dasc +1 -1
- data/lua-hooks/ext/luajit/src/vm_mips.dasc +1562 -656
- data/lua-hooks/ext/luajit/src/vm_ppc.dasc +3 -7
- data/lua-hooks/ext/luajit/src/vm_x64.dasc +10 -2
- data/lua-hooks/ext/luajit/src/vm_x86.dasc +5 -8
- data/lua-hooks/ext/luautf8/module.mk +2 -0
- data/lua-hooks/ext/module.mk +15 -0
- data/lua-hooks/ext/modules.h +17 -0
- data/lua-hooks/ext/perf/luacpu.c +1 -1
- data/lua-hooks/ext/perf/lualoadavg.c +1 -1
- data/lua-hooks/ext/perf/luameminfo.c +1 -1
- data/lua-hooks/ext/perf/luaoslib.c +124 -2
- data/lua-hooks/ext/perf/module.mk +5 -0
- data/lua-hooks/ext/sha1/luasha1.c +4 -2
- data/lua-hooks/ext/sha1/module.mk +5 -0
- data/lua-hooks/ext/sha2/luasha256.c +4 -2
- data/lua-hooks/ext/sha2/module.mk +5 -0
- data/lua-hooks/ext/sysutils/lua_utils.c +56 -0
- data/lua-hooks/ext/sysutils/module.mk +2 -0
- data/lua-hooks/lib/boot.lua +2 -1
- data/lua-hooks/lib/hooks/module.mk +31 -0
- data/lua-hooks/lib/hooks/xss/module.mk +4 -0
- data/lua-hooks/lib/lexers/module.mk +10 -0
- data/lua-hooks/lib/module.mk +38 -0
- data/lua-hooks/lib/schema/module.mk +3 -0
- data/lua-hooks/options.mk +59 -0
- metadata +21 -2
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
** String formatting.
|
3
|
-
** Copyright (C) 2005-
|
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
|
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(
|
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
|
+
|