Skip to content

Commit ac87b7b

Browse files
committed
Rely on memcpy
1 parent 272872f commit ac87b7b

File tree

1 file changed

+83
-47
lines changed

1 file changed

+83
-47
lines changed

ext/json/ext/vendor/jeaiii-ltoa.h

+83-47
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ typedef uint_fast64_t u64_t;
4444
#define u32(x) ((u32_t)(x))
4545
#define u64(x) ((u64_t)(x))
4646

47-
struct pair
47+
struct digit_pair
4848
{
4949
char dd[2];
5050
};
5151

52-
#define cast_to_pair_ptr(b) ((struct pair*)(void*)(b))
53-
54-
static const struct pair *digits_dd = (struct pair *)(
52+
static const struct digit_pair *digits_dd = (struct digit_pair *)(
5553
"00" "01" "02" "03" "04" "05" "06" "07" "08" "09"
5654
"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
5755
"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
@@ -64,7 +62,7 @@ static const struct pair *digits_dd = (struct pair *)(
6462
"90" "91" "92" "93" "94" "95" "96" "97" "98" "99"
6563
);
6664

67-
static const struct pair *digits_fd = (struct pair *)(
65+
static const struct digit_pair *digits_fd = (struct digit_pair *)(
6866
"0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_"
6967
"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
7068
"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
@@ -81,57 +79,74 @@ static const u64_t mask24 = (u64(1) << 24) - 1;
8179
static const u64_t mask32 = (u64(1) << 32) - 1;
8280
static const u64_t mask57 = (u64(1) << 57) - 1;
8381

82+
#define COPY(buffer, digits) memcpy(buffer, &(digits), sizeof(struct digit_pair))
83+
8484
static char *
8585
to_text_from_ulong(char *b, u64_t n)
8686
{
8787
if (n < u32(1e2)) {
88-
*cast_to_pair_ptr(b) = digits_fd[n];
88+
COPY(b, digits_fd[n]);
8989
return n < 10 ? b + 1 : b + 2;
9090
}
9191

9292
if (n < u32(1e6)) {
9393
if (n < u32(1e4)) {
9494
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * n;
95-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
95+
COPY(b, digits_fd[f0 >> 24]);
96+
9697
b -= n < u32(1e3);
9798
u32_t f2 = (f0 & mask24) * 100;
98-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
99+
COPY(b + 2, digits_dd[f2 >> 24]);
100+
99101
return b + 4;
100102
}
103+
101104
u64_t f0 = u64(10 * (1ull << 32ull)/ 1e5 + 1) * n;
102-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
105+
COPY(b, digits_fd[f0 >> 32]);
106+
103107
b -= n < u32(1e5);
104108
u64_t f2 = (f0 & mask32) * 100;
105-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
109+
COPY(b + 2, digits_dd[f2 >> 32]);
110+
106111
u64_t f4 = (f2 & mask32) * 100;
107-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
112+
COPY(b + 4, digits_dd[f4 >> 32]);
108113
return b + 6;
109114
}
110115

111116
if (n < u64(1ull << 32ull)) {
112117
if (n < u32(1e8)) {
113118
u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * n >> 16;
114-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
119+
COPY(b, digits_fd[f0 >> 32]);
120+
115121
b -= n < u32(1e7);
116122
u64_t f2 = (f0 & mask32) * 100;
117-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
123+
COPY(b + 2, digits_dd[f2 >> 32]);
124+
118125
u64_t f4 = (f2 & mask32) * 100;
119-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
126+
COPY(b + 4, digits_dd[f4 >> 32]);
127+
120128
u64_t f6 = (f4 & mask32) * 100;
121-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
129+
COPY(b + 6, digits_dd[f6 >> 32]);
130+
122131
return b + 8;
123132
}
133+
124134
u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * n;
125-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 57];
135+
COPY(b, digits_fd[f0 >> 57]);
136+
126137
b -= n < u32(1e9);
127138
u64_t f2 = (f0 & mask57) * 100;
128-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 57];
139+
COPY(b + 2, digits_dd[f2 >> 57]);
140+
129141
u64_t f4 = (f2 & mask57) * 100;
130-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 57];
142+
COPY(b + 4, digits_dd[f4 >> 57]);
143+
131144
u64_t f6 = (f4 & mask57) * 100;
132-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 57];
145+
COPY(b + 6, digits_dd[f6 >> 57]);
146+
133147
u64_t f8 = (f6 & mask57) * 100;
134-
*cast_to_pair_ptr(b + 8) = digits_dd[f8 >> 57];
148+
COPY(b + 8, digits_dd[f8 >> 57]);
149+
135150
return b + 10;
136151
}
137152

@@ -141,53 +156,64 @@ to_text_from_ulong(char *b, u64_t n)
141156

142157
if (u < u32(1e2)) {
143158
// u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number)
144-
*cast_to_pair_ptr(b) = digits_dd[u];
159+
COPY(b, digits_dd[u]);
145160
b += 2;
146161
}
147162
else if (u < u32(1e6)) {
148163
if (u < u32(1e4)) {
149164
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * u;
150-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
165+
COPY(b, digits_fd[f0 >> 24]);
166+
151167
b -= u < u32(1e3);
152168
u32_t f2 = (f0 & mask24) * 100;
153-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
169+
COPY(b + 2, digits_dd[f2 >> 24]);
154170
b += 4;
155171
}
156172
else {
157173
u64_t f0 = u64(10 * (1ull << 32ull) / 1e5 + 1) * u;
158-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
174+
COPY(b, digits_fd[f0 >> 32]);
175+
159176
b -= u < u32(1e5);
160177
u64_t f2 = (f0 & mask32) * 100;
161-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
178+
COPY(b + 2, digits_dd[f2 >> 32]);
179+
162180
u64_t f4 = (f2 & mask32) * 100;
163-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
181+
COPY(b + 4, digits_dd[f4 >> 32]);
164182
b += 6;
165183
}
166184
}
167185
else if (u < u32(1e8)) {
168186
u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * u >> 16;
169-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
187+
COPY(b, digits_fd[f0 >> 32]);
188+
170189
b -= u < u32(1e7);
171190
u64_t f2 = (f0 & mask32) * 100;
172-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
191+
COPY(b + 2, digits_dd[f2 >> 32]);
192+
173193
u64_t f4 = (f2 & mask32) * 100;
174-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
194+
COPY(b + 4, digits_dd[f4 >> 32]);
195+
175196
u64_t f6 = (f4 & mask32) * 100;
176-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
197+
COPY(b + 6, digits_dd[f6 >> 32]);
198+
177199
b += 8;
178200
}
179201
else if (u < u64(1ull << 32ull)) {
180202
u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * u;
181-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 57];
203+
COPY(b, digits_fd[f0 >> 57]);
204+
182205
b -= u < u32(1e9);
183206
u64_t f2 = (f0 & mask57) * 100;
184-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 57];
207+
COPY(b + 2, digits_dd[f2 >> 57]);
208+
185209
u64_t f4 = (f2 & mask57) * 100;
186-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 57];
210+
COPY(b + 4, digits_dd[f4 >> 57]);
211+
187212
u64_t f6 = (f4 & mask57) * 100;
188-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 57];
213+
COPY(b + 6, digits_dd[f6 >> 57]);
214+
189215
u64_t f8 = (f6 & mask57) * 100;
190-
*cast_to_pair_ptr(b + 8) = digits_dd[f8 >> 57];
216+
COPY(b + 8, digits_dd[f8 >> 57]);
191217
b += 10;
192218
}
193219
else {
@@ -196,43 +222,53 @@ to_text_from_ulong(char *b, u64_t n)
196222

197223
// u is 2, 3, or 4 digits (if u < 10 it would have been handled above)
198224
if (u < u32(1e2)) {
199-
*cast_to_pair_ptr(b) = digits_dd[u];
225+
COPY(b, digits_dd[u]);
200226
b += 2;
201227
}
202228
else {
203229
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * u;
204-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
230+
COPY(b, digits_fd[f0 >> 24]);
231+
205232
b -= u < u32(1e3);
206233
u32_t f2 = (f0 & mask24) * 100;
207-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
234+
COPY(b + 2, digits_dd[f2 >> 24]);
235+
208236
b += 4;
209237
}
210238
// do 8 digits
211239
u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * y >> 16) + 1;
212-
*cast_to_pair_ptr(b) = digits_dd[f0 >> 32];
240+
COPY(b, digits_dd[f0 >> 32]);
241+
213242
u64_t f2 = (f0 & mask32) * 100;
214-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
243+
COPY(b + 2, digits_dd[f2 >> 32]);
244+
215245
u64_t f4 = (f2 & mask32) * 100;
216-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
246+
COPY(b + 4, digits_dd[f4 >> 32]);
247+
217248
u64_t f6 = (f4 & mask32) * 100;
218-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
249+
COPY(b + 6, digits_dd[f6 >> 32]);
219250
b += 8;
220251
}
252+
221253
// do 8 digits
222254
u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * z >> 16) + 1;
223-
*cast_to_pair_ptr(b) = digits_dd[f0 >> 32];
255+
COPY(b, digits_dd[f0 >> 32]);
256+
224257
u64_t f2 = (f0 & mask32) * 100;
225-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
258+
COPY(b + 2, digits_dd[f2 >> 32]);
259+
226260
u64_t f4 = (f2 & mask32) * 100;
227-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
261+
COPY(b + 4, digits_dd[f4 >> 32]);
262+
228263
u64_t f6 = (f4 & mask32) * 100;
229-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
264+
COPY(b + 6, digits_dd[f6 >> 32]);
265+
230266
return b + 8;
231267
}
232268

233269
#undef u32
234270
#undef u64
235-
#undef cast_to_pair_ptr
271+
#undef COPY
236272

237273
#pragma clang diagnostic pop
238274
#pragma GCC diagnostic pop

0 commit comments

Comments
 (0)