Skip to content

Commit 1bcebef

Browse files
committed
Refactor jeaiii-ltoa.h
Some relatively minor change to make the library more in line with the gem. Some renaming, etc.
1 parent 0e60e05 commit 1bcebef

File tree

3 files changed

+139
-111
lines changed

3 files changed

+139
-111
lines changed

ext/json/ext/fbuffer/fbuffer.h

+13-4
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,23 @@ static inline void fbuffer_append_char(FBuffer *fb, char newchr)
175175
fb->len++;
176176
}
177177

178+
static inline char *fbuffer_cursor(FBuffer *fb)
179+
{
180+
return fb->ptr + fb->len;
181+
}
182+
183+
static inline void fbuffer_advance_to(FBuffer *fb, char *end)
184+
{
185+
fb->len = end - fb->ptr;
186+
}
187+
178188
/*
179189
* Appends the decimal string representation of \a number into the buffer.
180190
*/
181191
static void fbuffer_append_long(FBuffer *fb, long number)
182192
{
183193
/*
184-
* The to_text_from_ulong() function produces digits left-to-right,
194+
* The jeaiii_ultoa() function produces digits left-to-right,
185195
* allowing us to write directly into the buffer, but we don't know
186196
* the number of resulting characters.
187197
*
@@ -205,9 +215,8 @@ static void fbuffer_append_long(FBuffer *fb, long number)
205215
number = -number;
206216
}
207217

208-
char* d = fb->ptr + fb->len;
209-
char* end = to_text_from_ulong(d, number);
210-
fb->len += end - d;
218+
char *end = jeaiii_ultoa(fbuffer_cursor(fb), number);
219+
fbuffer_advance_to(fb, end);
211220
}
212221

213222
static VALUE fbuffer_finalize(FBuffer *fb)

ext/json/ext/generator/generator.c

-1
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,6 @@ void Init_generator(void)
17101710
cFragment = rb_const_get(mJSON, rb_intern("Fragment"));
17111711

17121712
VALUE mExt = rb_define_module_under(mJSON, "Ext");
1713-
17141713
VALUE mGenerator = rb_define_module_under(mExt, "Generator");
17151714

17161715
rb_global_variable(&eGeneratorError);

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

+126-106
Original file line numberDiff line numberDiff line change
@@ -44,211 +44,231 @@ 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))
52+
static const struct digit_pair *digits_dd = (struct digit_pair *)(
53+
"00" "01" "02" "03" "04" "05" "06" "07" "08" "09"
54+
"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
55+
"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
56+
"30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
57+
"40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
58+
"50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
59+
"60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
60+
"70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
61+
"80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
62+
"90" "91" "92" "93" "94" "95" "96" "97" "98" "99"
63+
);
5364

54-
static struct pair digits_dd[100] =
55-
{
56-
{ '0', '0' }, { '0', '1' }, { '0', '2' }, { '0', '3' }, { '0', '4' }, { '0', '5' }, { '0', '6' }, { '0', '7' }, { '0', '8' }, { '0', '9' },
57-
{ '1', '0' }, { '1', '1' }, { '1', '2' }, { '1', '3' }, { '1', '4' }, { '1', '5' }, { '1', '6' }, { '1', '7' }, { '1', '8' }, { '1', '9' },
58-
{ '2', '0' }, { '2', '1' }, { '2', '2' }, { '2', '3' }, { '2', '4' }, { '2', '5' }, { '2', '6' }, { '2', '7' }, { '2', '8' }, { '2', '9' },
59-
{ '3', '0' }, { '3', '1' }, { '3', '2' }, { '3', '3' }, { '3', '4' }, { '3', '5' }, { '3', '6' }, { '3', '7' }, { '3', '8' }, { '3', '9' },
60-
{ '4', '0' }, { '4', '1' }, { '4', '2' }, { '4', '3' }, { '4', '4' }, { '4', '5' }, { '4', '6' }, { '4', '7' }, { '4', '8' }, { '4', '9' },
61-
{ '5', '0' }, { '5', '1' }, { '5', '2' }, { '5', '3' }, { '5', '4' }, { '5', '5' }, { '5', '6' }, { '5', '7' }, { '5', '8' }, { '5', '9' },
62-
{ '6', '0' }, { '6', '1' }, { '6', '2' }, { '6', '3' }, { '6', '4' }, { '6', '5' }, { '6', '6' }, { '6', '7' }, { '6', '8' }, { '6', '9' },
63-
{ '7', '0' }, { '7', '1' }, { '7', '2' }, { '7', '3' }, { '7', '4' }, { '7', '5' }, { '7', '6' }, { '7', '7' }, { '7', '8' }, { '7', '9' },
64-
{ '8', '0' }, { '8', '1' }, { '8', '2' }, { '8', '3' }, { '8', '4' }, { '8', '5' }, { '8', '6' }, { '8', '7' }, { '8', '8' }, { '8', '9' },
65-
{ '9', '0' }, { '9', '1' }, { '9', '2' }, { '9', '3' }, { '9', '4' }, { '9', '5' }, { '9', '6' }, { '9', '7' }, { '9', '8' }, { '9', '9' },
66-
};
67-
68-
#define NUL 'x'
69-
70-
static struct pair digits_fd[100] =
71-
{
72-
{ '0', NUL }, { '1', NUL }, { '2', NUL }, { '3', NUL }, { '4', NUL }, { '5', NUL }, { '6', NUL }, { '7', NUL }, { '8', NUL }, { '9', NUL },
73-
{ '1', '0' }, { '1', '1' }, { '1', '2' }, { '1', '3' }, { '1', '4' }, { '1', '5' }, { '1', '6' }, { '1', '7' }, { '1', '8' }, { '1', '9' },
74-
{ '2', '0' }, { '2', '1' }, { '2', '2' }, { '2', '3' }, { '2', '4' }, { '2', '5' }, { '2', '6' }, { '2', '7' }, { '2', '8' }, { '2', '9' },
75-
{ '3', '0' }, { '3', '1' }, { '3', '2' }, { '3', '3' }, { '3', '4' }, { '3', '5' }, { '3', '6' }, { '3', '7' }, { '3', '8' }, { '3', '9' },
76-
{ '4', '0' }, { '4', '1' }, { '4', '2' }, { '4', '3' }, { '4', '4' }, { '4', '5' }, { '4', '6' }, { '4', '7' }, { '4', '8' }, { '4', '9' },
77-
{ '5', '0' }, { '5', '1' }, { '5', '2' }, { '5', '3' }, { '5', '4' }, { '5', '5' }, { '5', '6' }, { '5', '7' }, { '5', '8' }, { '5', '9' },
78-
{ '6', '0' }, { '6', '1' }, { '6', '2' }, { '6', '3' }, { '6', '4' }, { '6', '5' }, { '6', '6' }, { '6', '7' }, { '6', '8' }, { '6', '9' },
79-
{ '7', '0' }, { '7', '1' }, { '7', '2' }, { '7', '3' }, { '7', '4' }, { '7', '5' }, { '7', '6' }, { '7', '7' }, { '7', '8' }, { '7', '9' },
80-
{ '8', '0' }, { '8', '1' }, { '8', '2' }, { '8', '3' }, { '8', '4' }, { '8', '5' }, { '8', '6' }, { '8', '7' }, { '8', '8' }, { '8', '9' },
81-
{ '9', '0' }, { '9', '1' }, { '9', '2' }, { '9', '3' }, { '9', '4' }, { '9', '5' }, { '9', '6' }, { '9', '7' }, { '9', '8' }, { '9', '9' },
82-
};
65+
static const struct digit_pair *digits_fd = (struct digit_pair *)(
66+
"0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_"
67+
"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
68+
"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
69+
"30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
70+
"40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
71+
"50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
72+
"60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
73+
"70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
74+
"80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
75+
"90" "91" "92" "93" "94" "95" "96" "97" "98" "99"
76+
);
8377

84-
#undef NUL
78+
static const u64_t mask24 = (u64(1) << 24) - 1;
79+
static const u64_t mask32 = (u64(1) << 32) - 1;
80+
static const u64_t mask57 = (u64(1) << 57) - 1;
8581

86-
static u64_t mask24 = (u64(1) << 24) - 1;
87-
static u64_t mask32 = (u64(1) << 32) - 1;
88-
static u64_t mask57 = (u64(1) << 57) - 1;
82+
#define COPY(buffer, digits) memcpy(buffer, &(digits), sizeof(struct digit_pair))
8983

90-
static
91-
char* to_text_from_ulong(char* b, u64_t n) {
92-
if (n < u32(1e2))
93-
{
94-
*cast_to_pair_ptr(b) = digits_fd[n];
84+
static char *
85+
jeaiii_ultoa(char *b, u64_t n)
86+
{
87+
if (n < u32(1e2)) {
88+
COPY(b, digits_fd[n]);
9589
return n < 10 ? b + 1 : b + 2;
9690
}
97-
if (n < u32(1e6))
98-
{
99-
if (n < u32(1e4))
100-
{
91+
92+
if (n < u32(1e6)) {
93+
if (n < u32(1e4)) {
10194
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * n;
102-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
95+
COPY(b, digits_fd[f0 >> 24]);
96+
10397
b -= n < u32(1e3);
10498
u32_t f2 = (f0 & mask24) * 100;
105-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
99+
COPY(b + 2, digits_dd[f2 >> 24]);
100+
106101
return b + 4;
107102
}
103+
108104
u64_t f0 = u64(10 * (1ull << 32ull)/ 1e5 + 1) * n;
109-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
105+
COPY(b, digits_fd[f0 >> 32]);
106+
110107
b -= n < u32(1e5);
111108
u64_t f2 = (f0 & mask32) * 100;
112-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
109+
COPY(b + 2, digits_dd[f2 >> 32]);
110+
113111
u64_t f4 = (f2 & mask32) * 100;
114-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
112+
COPY(b + 4, digits_dd[f4 >> 32]);
115113
return b + 6;
116114
}
117-
if (n < u64(1ull << 32ull))
118-
{
119-
if (n < u32(1e8))
120-
{
115+
116+
if (n < u64(1ull << 32ull)) {
117+
if (n < u32(1e8)) {
121118
u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * n >> 16;
122-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
119+
COPY(b, digits_fd[f0 >> 32]);
120+
123121
b -= n < u32(1e7);
124122
u64_t f2 = (f0 & mask32) * 100;
125-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
123+
COPY(b + 2, digits_dd[f2 >> 32]);
124+
126125
u64_t f4 = (f2 & mask32) * 100;
127-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
126+
COPY(b + 4, digits_dd[f4 >> 32]);
127+
128128
u64_t f6 = (f4 & mask32) * 100;
129-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
129+
COPY(b + 6, digits_dd[f6 >> 32]);
130+
130131
return b + 8;
131132
}
133+
132134
u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * n;
133-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 57];
135+
COPY(b, digits_fd[f0 >> 57]);
136+
134137
b -= n < u32(1e9);
135138
u64_t f2 = (f0 & mask57) * 100;
136-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 57];
139+
COPY(b + 2, digits_dd[f2 >> 57]);
140+
137141
u64_t f4 = (f2 & mask57) * 100;
138-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 57];
142+
COPY(b + 4, digits_dd[f4 >> 57]);
143+
139144
u64_t f6 = (f4 & mask57) * 100;
140-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 57];
145+
COPY(b + 6, digits_dd[f6 >> 57]);
146+
141147
u64_t f8 = (f6 & mask57) * 100;
142-
*cast_to_pair_ptr(b + 8) = digits_dd[f8 >> 57];
148+
COPY(b + 8, digits_dd[f8 >> 57]);
149+
143150
return b + 10;
144151
}
145152

146153
// if we get here U must be u64 but some compilers don't know that, so reassign n to a u64 to avoid warnings
147154
u32_t z = n % u32(1e8);
148155
u64_t u = n / u32(1e8);
149156

150-
if (u < u32(1e2))
151-
{
157+
if (u < u32(1e2)) {
152158
// u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number)
153-
*cast_to_pair_ptr(b) = digits_dd[u];
159+
COPY(b, digits_dd[u]);
154160
b += 2;
155161
}
156-
else if (u < u32(1e6))
157-
{
158-
if (u < u32(1e4))
159-
{
162+
else if (u < u32(1e6)) {
163+
if (u < u32(1e4)) {
160164
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * u;
161-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
165+
COPY(b, digits_fd[f0 >> 24]);
166+
162167
b -= u < u32(1e3);
163168
u32_t f2 = (f0 & mask24) * 100;
164-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
169+
COPY(b + 2, digits_dd[f2 >> 24]);
165170
b += 4;
166171
}
167-
else
168-
{
172+
else {
169173
u64_t f0 = u64(10 * (1ull << 32ull) / 1e5 + 1) * u;
170-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
174+
COPY(b, digits_fd[f0 >> 32]);
175+
171176
b -= u < u32(1e5);
172177
u64_t f2 = (f0 & mask32) * 100;
173-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
178+
COPY(b + 2, digits_dd[f2 >> 32]);
179+
174180
u64_t f4 = (f2 & mask32) * 100;
175-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
181+
COPY(b + 4, digits_dd[f4 >> 32]);
176182
b += 6;
177183
}
178184
}
179-
else if (u < u32(1e8))
180-
{
185+
else if (u < u32(1e8)) {
181186
u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * u >> 16;
182-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 32];
187+
COPY(b, digits_fd[f0 >> 32]);
188+
183189
b -= u < u32(1e7);
184190
u64_t f2 = (f0 & mask32) * 100;
185-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
191+
COPY(b + 2, digits_dd[f2 >> 32]);
192+
186193
u64_t f4 = (f2 & mask32) * 100;
187-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
194+
COPY(b + 4, digits_dd[f4 >> 32]);
195+
188196
u64_t f6 = (f4 & mask32) * 100;
189-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
197+
COPY(b + 6, digits_dd[f6 >> 32]);
198+
190199
b += 8;
191200
}
192-
else if (u < u64(1ull << 32ull))
193-
{
201+
else if (u < u64(1ull << 32ull)) {
194202
u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * u;
195-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 57];
203+
COPY(b, digits_fd[f0 >> 57]);
204+
196205
b -= u < u32(1e9);
197206
u64_t f2 = (f0 & mask57) * 100;
198-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 57];
207+
COPY(b + 2, digits_dd[f2 >> 57]);
208+
199209
u64_t f4 = (f2 & mask57) * 100;
200-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 57];
210+
COPY(b + 4, digits_dd[f4 >> 57]);
211+
201212
u64_t f6 = (f4 & mask57) * 100;
202-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 57];
213+
COPY(b + 6, digits_dd[f6 >> 57]);
214+
203215
u64_t f8 = (f6 & mask57) * 100;
204-
*cast_to_pair_ptr(b + 8) = digits_dd[f8 >> 57];
216+
COPY(b + 8, digits_dd[f8 >> 57]);
205217
b += 10;
206218
}
207-
else
208-
{
219+
else {
209220
u32_t y = u % u32(1e8);
210221
u /= u32(1e8);
211222

212223
// u is 2, 3, or 4 digits (if u < 10 it would have been handled above)
213-
if (u < u32(1e2))
214-
{
215-
*cast_to_pair_ptr(b) = digits_dd[u];
224+
if (u < u32(1e2)) {
225+
COPY(b, digits_dd[u]);
216226
b += 2;
217227
}
218-
else
219-
{
228+
else {
220229
u32_t f0 = u32(10 * (1 << 24) / 1e3 + 1) * u;
221-
*cast_to_pair_ptr(b) = digits_fd[f0 >> 24];
230+
COPY(b, digits_fd[f0 >> 24]);
231+
222232
b -= u < u32(1e3);
223233
u32_t f2 = (f0 & mask24) * 100;
224-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 24];
234+
COPY(b + 2, digits_dd[f2 >> 24]);
235+
225236
b += 4;
226237
}
227238
// do 8 digits
228239
u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * y >> 16) + 1;
229-
*cast_to_pair_ptr(b) = digits_dd[f0 >> 32];
240+
COPY(b, digits_dd[f0 >> 32]);
241+
230242
u64_t f2 = (f0 & mask32) * 100;
231-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
243+
COPY(b + 2, digits_dd[f2 >> 32]);
244+
232245
u64_t f4 = (f2 & mask32) * 100;
233-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
246+
COPY(b + 4, digits_dd[f4 >> 32]);
247+
234248
u64_t f6 = (f4 & mask32) * 100;
235-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
249+
COPY(b + 6, digits_dd[f6 >> 32]);
236250
b += 8;
237251
}
252+
238253
// do 8 digits
239254
u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * z >> 16) + 1;
240-
*cast_to_pair_ptr(b) = digits_dd[f0 >> 32];
255+
COPY(b, digits_dd[f0 >> 32]);
256+
241257
u64_t f2 = (f0 & mask32) * 100;
242-
*cast_to_pair_ptr(b + 2) = digits_dd[f2 >> 32];
258+
COPY(b + 2, digits_dd[f2 >> 32]);
259+
243260
u64_t f4 = (f2 & mask32) * 100;
244-
*cast_to_pair_ptr(b + 4) = digits_dd[f4 >> 32];
261+
COPY(b + 4, digits_dd[f4 >> 32]);
262+
245263
u64_t f6 = (f4 & mask32) * 100;
246-
*cast_to_pair_ptr(b + 6) = digits_dd[f6 >> 32];
264+
COPY(b + 6, digits_dd[f6 >> 32]);
265+
247266
return b + 8;
248267
}
249268

250269
#undef u32
251270
#undef u64
271+
#undef COPY
252272

253273
#pragma clang diagnostic pop
254274
#pragma GCC diagnostic pop

0 commit comments

Comments
 (0)