~ubuntu-branches/ubuntu/trusty/luajit/trusty

« back to all changes in this revision

Viewing changes to src/lj_str.c

  • Committer: Bazaar Package Importer
  • Author(s): Enrico Tassi
  • Date: 2011-05-09 23:14:21 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20110509231421-zdcnqbqk5h6iryxr
Tags: 2.0.0~beta7+dfsg-1
New upstream release with arm support

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
  return (int32_t)(a->len - b->len);
44
44
}
45
45
 
 
46
typedef union
 
47
#ifdef __GNUC__
 
48
__attribute__((packed))
 
49
#endif
 
50
Unaligned32 { uint32_t u; uint8_t b[4]; } Unaligned32;
 
51
 
 
52
/* Unaligned read of uint32_t. */
 
53
static LJ_AINLINE uint32_t str_getu32(const void *p)
 
54
{
 
55
  return ((const Unaligned32 *)p)->u;
 
56
}
 
57
 
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)
48
60
{
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);
54
66
    if (v) {
55
67
      i -= len;
56
68
#if LJ_LE
103
115
  g = G(L);
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);
 
118
    a = str_getu32(str);
 
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)
174
186
{
 
187
  int ok = lj_str_numconv(strdata(str), n);
 
188
  if (ok && tvisint(n))
 
189
    setnumV(n, (lua_Number)intV(n));
 
190
  return ok;
 
191
}
 
192
 
 
193
int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n)
 
194
{
175
195
  return lj_str_numconv(strdata(str), n);
176
196
}
177
197
 
178
198
/* Convert string to number. */
179
199
int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
180
200
{
 
201
#if LJ_DUALNUM
 
202
  int sign = 1;
 
203
#else
181
204
  lua_Number sign = 1;
 
205
#endif
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. */
191
215
      do {
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;
195
219
        p++;
196
220
      } while (lj_char_isxdigit(*p));
197
221
    } else {
198
222
      while ((uint32_t)(*p - '0') < 10) {
199
 
        if (k >= 0x19999999) goto parsedbl;
 
223
        if (LJ_UNLIKELY(k >= 429496729) && (k != 429496729 || *p > '5'))
 
224
          goto parsedbl;
200
225
        k = k * 10u + (uint32_t)(*p++ - '0');
201
226
      }
202
227
    }
203
228
    while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
204
229
    if (LJ_LIKELY(*p == '\0')) {
205
 
      setnumV(n, sign * cast_num(k));
 
230
#if LJ_DUALNUM
 
231
      if (sign == 1) {
 
232
        if (k < 0x80000000u) {
 
233
          setintV(n, (int32_t)k);
 
234
          return 1;
 
235
        }
 
236
      } else if (k <= 0x80000000u) {
 
237
        setintV(n, -(int32_t)k);
 
238
        return 1;
 
239
      }
 
240
#endif
 
241
      setnumV(n, sign * (lua_Number)k);
206
242
      return 1;
207
243
    }
208
244
  }
239
275
  }
240
276
}
241
277
 
 
278
/* Print integer to buffer. Returns pointer to start. */
 
279
char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
 
280
{
 
281
  uint32_t u = (uint32_t)(k < 0 ? -k : k);
 
282
  p += 1+10;
 
283
  do { *--p = (char)('0' + u % 10); } while (u /= 10);
 
284
  if (k < 0) *--p = '-';
 
285
  return p;
 
286
}
 
287
 
242
288
/* Convert number to string. */
243
289
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
244
290
{
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);
248
294
}
249
295
 
250
 
#if LJ_HASJIT
251
296
/* Convert integer to string. */
252
297
GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
253
298
{
254
299
  char s[1+10];
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));
260
302
}
261
 
#endif
 
303
 
 
304
GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
 
305
{
 
306
  return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
 
307
}
262
308
 
263
309
/* -- String formatting --------------------------------------------------- */
264
310
 
282
328
    MSize sz = sb->sz * 2;
283
329
    lj_str_resizebuf(L, sb, sz);
284
330
  }
285
 
  sb->buf[sb->n++] = cast(char, c);
 
331
  sb->buf[sb->n++] = (char)c;
286
332
}
287
333
 
288
334
/* Push formatted message as a string object to Lua stack. va_list variant. */
307
353
      addchar(L, sb, va_arg(argp, int));
308
354
      break;
309
355
    case 'd': {
310
 
      char buff[1+10];
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));
317
359
      break;
318
360
      }
319
361
    case 'f': {
320
 
      char buf[LUAI_MAXNUMBER2STR];
 
362
      char buf[LJ_STR_NUMBUF];
321
363
      TValue tv;
322
364
      MSize len;
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);
326
368
      break;
327
369
      }
328
370
    case 'p': {
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;
333
375
#if LJ_64
334
376
      if ((p >> 32) == 0)  /* Shorten output for true 32 bit pointers. */
335
377
        lasti = 2+2*4;
336
378
#endif
337
 
      buff[0] = '0';
338
 
      buff[1] = 'x';
 
379
      buf[0] = '0';
 
380
      buf[1] = 'x';
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);
342
384
      break;
343
385
      }
344
386
    case '%':