immunio 1.1.2 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|