43
43
return (int32_t)(a->len - b->len);
48
__attribute__((packed))
50
Unaligned32 { uint32_t u; uint8_t b[4]; } Unaligned32;
52
/* Unaligned read of uint32_t. */
53
static LJ_AINLINE uint32_t str_getu32(const void *p)
55
return ((const Unaligned32 *)p)->u;
46
58
/* Fast string data comparison. Caveat: unaligned access to 1st string! */
47
59
static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
50
62
lua_assert(len > 0);
51
63
lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
52
64
do { /* Note: innocuous access up to end of string + 3. */
53
uint32_t v = *(const uint32_t *)(a+i) ^ *(const uint32_t *)(b+i);
65
uint32_t v = str_getu32(a+i) ^ *(const uint32_t *)(b+i);
104
116
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
105
117
if (len >= 4) { /* Caveat: unaligned access! */
106
a = *(const uint32_t *)str;
107
h ^= *(const uint32_t *)(str+len-4);
108
b = *(const uint32_t *)(str+(len>>1)-2);
119
h ^= str_getu32(str+len-4);
120
b = str_getu32(str+(len>>1)-2);
109
121
h ^= b; h -= lj_rol(b, 14);
110
b += *(const uint32_t *)(str+(len>>2)-1);
122
b += str_getu32(str+(len>>2)-1);
111
123
} else if (len > 0) {
112
124
a = *(const uint8_t *)str;
113
125
h ^= *(const uint8_t *)(str+len-1);
172
184
/* Convert string object to number. */
173
185
int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n)
187
int ok = lj_str_numconv(strdata(str), n);
188
if (ok && tvisint(n))
189
setnumV(n, (lua_Number)intV(n));
193
int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n)
175
195
return lj_str_numconv(strdata(str), n);
178
198
/* Convert string to number. */
179
199
int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
181
204
lua_Number sign = 1;
182
206
const uint8_t *p = (const uint8_t *)s;
183
207
while (lj_char_isspace(*p)) p++;
184
208
if (*p == '-') { p++; sign = -1; } else if (*p == '+') { p++; }
189
213
if (!lj_char_isxdigit(*p))
190
214
return 0; /* Don't accept '0x' without hex digits. */
192
if (k >= 0x10000000) goto parsedbl;
216
if (k >= 0x10000000u) goto parsedbl;
193
217
k = (k << 4) + (*p & 15u);
194
218
if (!lj_char_isdigit(*p)) k += 9;
196
220
} while (lj_char_isxdigit(*p));
198
222
while ((uint32_t)(*p - '0') < 10) {
199
if (k >= 0x19999999) goto parsedbl;
223
if (LJ_UNLIKELY(k >= 429496729) && (k != 429496729 || *p > '5'))
200
225
k = k * 10u + (uint32_t)(*p++ - '0');
203
228
while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
204
229
if (LJ_LIKELY(*p == '\0')) {
205
setnumV(n, sign * cast_num(k));
232
if (k < 0x80000000u) {
233
setintV(n, (int32_t)k);
236
} else if (k <= 0x80000000u) {
237
setintV(n, -(int32_t)k);
241
setnumV(n, sign * (lua_Number)k);
278
/* Print integer to buffer. Returns pointer to start. */
279
char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
281
uint32_t u = (uint32_t)(k < 0 ? -k : k);
283
do { *--p = (char)('0' + u % 10); } while (u /= 10);
284
if (k < 0) *--p = '-';
242
288
/* Convert number to string. */
243
289
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
245
char buf[LUAI_MAXNUMBER2STR];
291
char buf[LJ_STR_NUMBUF];
246
292
size_t len = lj_str_bufnum(buf, (TValue *)np);
247
293
return lj_str_new(L, buf, len);
251
296
/* Convert integer to string. */
252
297
GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
255
char *p = s+sizeof(s);
256
uint32_t i = (uint32_t)(k < 0 ? -k : k);
257
do { *--p = (char)('0' + i % 10); } while (i /= 10);
258
if (k < 0) *--p = '-';
300
char *p = lj_str_bufint(s, k);
259
301
return lj_str_new(L, p, (size_t)(s+sizeof(s)-p));
304
GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
306
return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
263
309
/* -- String formatting --------------------------------------------------- */
282
328
MSize sz = sb->sz * 2;
283
329
lj_str_resizebuf(L, sb, sz);
285
sb->buf[sb->n++] = cast(char, c);
331
sb->buf[sb->n++] = (char)c;
288
334
/* Push formatted message as a string object to Lua stack. va_list variant. */
307
353
addchar(L, sb, va_arg(argp, int));
311
char *p = buff+sizeof(buff);
312
int32_t k = va_arg(argp, int32_t);
313
uint32_t i = (uint32_t)(k < 0 ? -k : k);
314
do { *--p = (char)('0' + i % 10); } while (i /= 10);
315
if (k < 0) *--p = '-';
316
addstr(L, sb, p, (MSize)(buff+sizeof(buff)-p));
356
char buf[LJ_STR_INTBUF];
357
char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
358
addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
320
char buf[LUAI_MAXNUMBER2STR];
362
char buf[LJ_STR_NUMBUF];
323
tv.n = cast_num(va_arg(argp, LUAI_UACNUMBER));
365
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
324
366
len = (MSize)lj_str_bufnum(buf, &tv);
325
367
addstr(L, sb, buf, len);
329
371
#define FMTP_CHARS (2*sizeof(ptrdiff_t))
330
char buff[2+FMTP_CHARS];
372
char buf[2+FMTP_CHARS];
331
373
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
332
374
ptrdiff_t i, lasti = 2+FMTP_CHARS;
334
376
if ((p >> 32) == 0) /* Shorten output for true 32 bit pointers. */
339
381
for (i = lasti-1; i >= 2; i--, p >>= 4)
340
buff[i] = "0123456789abcdef"[(p & 15)];
341
addstr(L, sb, buff, (MSize)lasti);
382
buf[i] = "0123456789abcdef"[(p & 15)];
383
addstr(L, sb, buf, (MSize)lasti);