Line data Source code
1 : /*
2 : ** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
3 : ** Some generic functions over Lua objects
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 : #define lobject_c
8 : #define LUA_CORE
9 :
10 : #include "lprefix.h"
11 :
12 :
13 : #include <locale.h>
14 : #include <math.h>
15 : #include <stdarg.h>
16 : #include <stdio.h>
17 : #include <stdlib.h>
18 : #include <string.h>
19 :
20 : #include "lua.h"
21 :
22 : #include "lctype.h"
23 : #include "ldebug.h"
24 : #include "ldo.h"
25 : #include "lmem.h"
26 : #include "lobject.h"
27 : #include "lstate.h"
28 : #include "lstring.h"
29 : #include "lvm.h"
30 :
31 :
32 :
33 : LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
34 :
35 :
36 : /*
37 : ** converts an integer to a "floating point byte", represented as
38 : ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
39 : ** eeeee != 0 and (xxx) otherwise.
40 : */
41 1462 : int luaO_int2fb (unsigned int x) {
42 1462 : int e = 0; /* exponent */
43 1462 : if (x < 8) return x;
44 10 : while (x >= (8 << 4)) { /* coarse steps */
45 1 : x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
46 1 : e += 4;
47 : }
48 12 : while (x >= (8 << 1)) { /* fine steps */
49 3 : x = (x + 1) >> 1; /* x = ceil(x / 2) */
50 3 : e++;
51 : }
52 9 : return ((e+1) << 3) | (cast_int(x) - 8);
53 : }
54 :
55 :
56 : /* converts back */
57 526 : int luaO_fb2int (int x) {
58 526 : return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
59 : }
60 :
61 :
62 : /*
63 : ** Computes ceil(log2(x))
64 : */
65 29309 : int luaO_ceillog2 (unsigned int x) {
66 : static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */
67 : 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
68 : 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
69 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
70 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
71 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
72 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
73 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
74 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
75 : };
76 29309 : int l = 0;
77 29309 : x--;
78 29316 : while (x >= 256) { l += 8; x >>= 8; }
79 29309 : return l + log_2[x];
80 : }
81 :
82 :
83 139 : static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
84 : lua_Integer v2) {
85 139 : switch (op) {
86 4 : case LUA_OPADD: return intop(+, v1, v2);
87 2 : case LUA_OPSUB:return intop(-, v1, v2);
88 1 : case LUA_OPMUL:return intop(*, v1, v2);
89 1 : case LUA_OPMOD: return luaV_mod(L, v1, v2);
90 3 : case LUA_OPIDIV: return luaV_div(L, v1, v2);
91 1 : case LUA_OPBAND: return intop(&, v1, v2);
92 1 : case LUA_OPBOR: return intop(|, v1, v2);
93 1 : case LUA_OPBXOR: return intop(^, v1, v2);
94 1 : case LUA_OPSHL: return luaV_shiftl(v1, v2);
95 1 : case LUA_OPSHR: return luaV_shiftl(v1, -v2);
96 122 : case LUA_OPUNM: return intop(-, 0, v1);
97 1 : case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
98 0 : default: lua_assert(0); return 0;
99 : }
100 : }
101 :
102 :
103 33 : static lua_Number numarith (lua_State *L, int op, lua_Number v1,
104 : lua_Number v2) {
105 33 : switch (op) {
106 2 : case LUA_OPADD: return luai_numadd(L, v1, v2);
107 1 : case LUA_OPSUB: return luai_numsub(L, v1, v2);
108 3 : case LUA_OPMUL: return luai_nummul(L, v1, v2);
109 4 : case LUA_OPDIV: return luai_numdiv(L, v1, v2);
110 3 : case LUA_OPPOW: return luai_numpow(L, v1, v2);
111 1 : case LUA_OPIDIV: return luai_numidiv(L, v1, v2);
112 18 : case LUA_OPUNM: return luai_numunm(L, v1);
113 1 : case LUA_OPMOD: {
114 : lua_Number m;
115 1 : luai_nummod(L, v1, v2, m);
116 1 : return m;
117 : }
118 0 : default: lua_assert(0); return 0;
119 : }
120 : }
121 :
122 :
123 172 : void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
124 : TValue *res) {
125 172 : switch (op) {
126 6 : case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
127 : case LUA_OPSHL: case LUA_OPSHR:
128 : case LUA_OPBNOT: { /* operate only on integers */
129 : lua_Integer i1; lua_Integer i2;
130 6 : if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
131 6 : setivalue(res, intarith(L, op, i1, i2));
132 6 : return;
133 : }
134 : else break; /* go to the end */
135 : }
136 7 : case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */
137 : lua_Number n1; lua_Number n2;
138 7 : if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
139 7 : setfltvalue(res, numarith(L, op, n1, n2));
140 7 : return;
141 : }
142 : else break; /* go to the end */
143 : }
144 159 : default: { /* other operations */
145 : lua_Number n1; lua_Number n2;
146 159 : if (ttisinteger(p1) && ttisinteger(p2)) {
147 133 : setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
148 159 : return;
149 : }
150 26 : else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
151 26 : setfltvalue(res, numarith(L, op, n1, n2));
152 26 : return;
153 : }
154 : else break; /* go to the end */
155 : }
156 : }
157 : /* could not perform raw operation; try metamethod */
158 : lua_assert(L != NULL); /* should not fail when folding (compile time) */
159 0 : luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
160 : }
161 :
162 :
163 783 : int luaO_hexavalue (int c) {
164 783 : if (lisdigit(c)) return c - '0';
165 281 : else return (ltolower(c) - 'a') + 10;
166 : }
167 :
168 :
169 3920 : static int isneg (const char **s) {
170 3920 : if (**s == '-') { (*s)++; return 1; }
171 3895 : else if (**s == '+') (*s)++;
172 3895 : return 0;
173 : }
174 :
175 :
176 :
177 : /*
178 : ** {==================================================================
179 : ** Lua's implementation for 'lua_strx2number'
180 : ** ===================================================================
181 : */
182 :
183 : #if !defined(lua_strx2number)
184 :
185 : /* maximum number of significant digits to read (to avoid overflows
186 : even with single floats) */
187 : #define MAXSIGDIG 30
188 :
189 : /*
190 : ** convert an hexadecimal numeric string to a number, following
191 : ** C99 specification for 'strtod'
192 : */
193 : static lua_Number lua_strx2number (const char *s, char **endptr) {
194 : int dot = lua_getlocaledecpoint();
195 : lua_Number r = 0.0; /* result (accumulator) */
196 : int sigdig = 0; /* number of significant digits */
197 : int nosigdig = 0; /* number of non-significant digits */
198 : int e = 0; /* exponent correction */
199 : int neg; /* 1 if number is negative */
200 : int hasdot = 0; /* true after seen a dot */
201 : *endptr = cast(char *, s); /* nothing is valid yet */
202 : while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
203 : neg = isneg(&s); /* check signal */
204 : if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
205 : return 0.0; /* invalid format (no '0x') */
206 : for (s += 2; ; s++) { /* skip '0x' and read numeral */
207 : if (*s == dot) {
208 : if (hasdot) break; /* second dot? stop loop */
209 : else hasdot = 1;
210 : }
211 : else if (lisxdigit(cast_uchar(*s))) {
212 : if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
213 : nosigdig++;
214 : else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
215 : r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
216 : else e++; /* too many digits; ignore, but still count for exponent */
217 : if (hasdot) e--; /* decimal digit? correct exponent */
218 : }
219 : else break; /* neither a dot nor a digit */
220 : }
221 : if (nosigdig + sigdig == 0) /* no digits? */
222 : return 0.0; /* invalid format */
223 : *endptr = cast(char *, s); /* valid up to here */
224 : e *= 4; /* each digit multiplies/divides value by 2^4 */
225 : if (*s == 'p' || *s == 'P') { /* exponent part? */
226 : int exp1 = 0; /* exponent value */
227 : int neg1; /* exponent signal */
228 : s++; /* skip 'p' */
229 : neg1 = isneg(&s); /* signal */
230 : if (!lisdigit(cast_uchar(*s)))
231 : return 0.0; /* invalid; must have at least one digit */
232 : while (lisdigit(cast_uchar(*s))) /* read exponent */
233 : exp1 = exp1 * 10 + *(s++) - '0';
234 : if (neg1) exp1 = -exp1;
235 : e += exp1;
236 : *endptr = cast(char *, s); /* valid up to here */
237 : }
238 : if (neg) r = -r;
239 : return l_mathop(ldexp)(r, e);
240 : }
241 :
242 : #endif
243 : /* }====================================================== */
244 :
245 :
246 : /* maximum length of a numeral */
247 : #if !defined (L_MAXLENNUM)
248 : #define L_MAXLENNUM 200
249 : #endif
250 :
251 301 : static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
252 : char *endptr;
253 45 : *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
254 301 : : lua_str2number(s, &endptr);
255 301 : if (endptr == s) return NULL; /* nothing recognized? */
256 245 : while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
257 243 : return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
258 : }
259 :
260 :
261 : /*
262 : ** Convert string 's' to a Lua number (put in 'result'). Return NULL
263 : ** on fail or the address of the ending '\0' on success.
264 : ** 'pmode' points to (and 'mode' contains) special things in the string:
265 : ** - 'x'/'X' means an hexadecimal numeral
266 : ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
267 : ** - '.' just optimizes the search for the common case (nothing special)
268 : ** This function accepts both the current locale or a dot as the radix
269 : ** mark. If the conversion fails, it may mean number has a dot but
270 : ** locale accepts something else. In that case, the code copies 's'
271 : ** to a buffer (because 's' is read-only), changes the dot to the
272 : ** current locale radix mark, and tries to convert again.
273 : */
274 301 : static const char *l_str2d (const char *s, lua_Number *result) {
275 : const char *endptr;
276 301 : const char *pmode = strpbrk(s, ".xXnN");
277 301 : int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
278 301 : if (mode == 'n') /* reject 'inf' and 'nan' */
279 0 : return NULL;
280 301 : endptr = l_str2dloc(s, result, mode); /* try to convert */
281 301 : if (endptr == NULL) { /* failed? may be a different locale */
282 : char buff[L_MAXLENNUM + 1];
283 60 : const char *pdot = strchr(s, '.');
284 60 : if (strlen(s) > L_MAXLENNUM || pdot == NULL)
285 60 : return NULL; /* string too long or no dot; fail */
286 0 : strcpy(buff, s); /* copy string to buffer */
287 0 : buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
288 0 : endptr = l_str2dloc(buff, result, mode); /* try again */
289 0 : if (endptr != NULL)
290 0 : endptr = s + (endptr - buff); /* make relative to 's' */
291 : }
292 241 : return endptr;
293 : }
294 :
295 :
296 : #define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
297 : #define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
298 :
299 3920 : static const char *l_str2int (const char *s, lua_Integer *result) {
300 3920 : lua_Unsigned a = 0;
301 3920 : int empty = 1;
302 : int neg;
303 3922 : while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
304 3920 : neg = isneg(&s);
305 3920 : if (s[0] == '0' &&
306 911 : (s[1] == 'x' || s[1] == 'X')) { /* hex? */
307 109 : s += 2; /* skip '0x' */
308 550 : for (; lisxdigit(cast_uchar(*s)); s++) {
309 441 : a = a * 16 + luaO_hexavalue(*s);
310 441 : empty = 0;
311 : }
312 : }
313 : else { /* decimal */
314 8326 : for (; lisdigit(cast_uchar(*s)); s++) {
315 4515 : int d = *s - '0';
316 4515 : if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
317 0 : return NULL; /* do not accept it (as integer) */
318 4515 : a = a * 10 + d;
319 4515 : empty = 0;
320 : }
321 : }
322 3920 : while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */
323 3920 : if (empty || *s != '\0') return NULL; /* something wrong in the numeral */
324 : else {
325 3619 : *result = l_castU2S((neg) ? 0u - a : a);
326 3619 : return s;
327 : }
328 : }
329 :
330 :
331 3920 : size_t luaO_str2num (const char *s, TValue *o) {
332 : lua_Integer i; lua_Number n;
333 : const char *e;
334 3920 : if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */
335 3619 : setivalue(o, i);
336 : }
337 301 : else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */
338 241 : setfltvalue(o, n);
339 : }
340 : else
341 60 : return 0; /* conversion failed */
342 3860 : return (e - s) + 1; /* success; return string size */
343 : }
344 :
345 :
346 67 : int luaO_utf8esc (char *buff, unsigned long x) {
347 67 : int n = 1; /* number of bytes put in buffer (backwards) */
348 : lua_assert(x <= 0x10FFFF);
349 67 : if (x < 0x80) /* ascii? */
350 11 : buff[UTF8BUFFSZ - 1] = cast(char, x);
351 : else { /* need continuation bytes */
352 56 : unsigned int mfb = 0x3f; /* maximum that fits in first byte */
353 : do { /* add continuation bytes */
354 112 : buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f));
355 112 : x >>= 6; /* remove added bits */
356 112 : mfb >>= 1; /* now there is one less bit available in first byte */
357 112 : } while (x > mfb); /* still needs continuation byte? */
358 56 : buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
359 : }
360 67 : return n;
361 : }
362 :
363 :
364 : /* maximum length of the conversion of a number to a string */
365 : #define MAXNUMBER2STR 50
366 :
367 :
368 : /*
369 : ** Convert a number object to a string
370 : */
371 2726 : void luaO_tostring (lua_State *L, StkId obj) {
372 : char buff[MAXNUMBER2STR];
373 : size_t len;
374 : lua_assert(ttisnumber(obj));
375 2726 : if (ttisinteger(obj))
376 2699 : len = lua_integer2str(buff, sizeof(buff), ivalue(obj));
377 : else {
378 27 : len = lua_number2str(buff, sizeof(buff), fltvalue(obj));
379 : #if !defined(LUA_COMPAT_FLOATSTRING)
380 27 : if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
381 22 : buff[len++] = lua_getlocaledecpoint();
382 22 : buff[len++] = '0'; /* adds '.0' to result */
383 : }
384 : #endif
385 : }
386 2726 : setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
387 2726 : }
388 :
389 :
390 15791 : static void pushstr (lua_State *L, const char *str, size_t l) {
391 15791 : setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
392 15791 : luaD_inctop(L);
393 15791 : }
394 :
395 :
396 : /*
397 : ** this function handles only '%d', '%c', '%f', '%p', and '%s'
398 : conventional formats, plus Lua-specific '%I' and '%U'
399 : */
400 5083 : const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
401 5083 : int n = 0;
402 6712 : for (;;) {
403 11795 : const char *e = strchr(fmt, '%');
404 11795 : if (e == NULL) break;
405 6712 : pushstr(L, fmt, e - fmt);
406 6712 : switch (*(e+1)) {
407 3943 : case 's': { /* zero-terminated string */
408 3943 : const char *s = va_arg(argp, char *);
409 3943 : if (s == NULL) s = "(null)";
410 3943 : pushstr(L, s, strlen(s));
411 3943 : break;
412 : }
413 16 : case 'c': { /* an 'int' as a character */
414 16 : char buff = cast(char, va_arg(argp, int));
415 16 : if (lisprint(cast_uchar(buff)))
416 16 : pushstr(L, &buff, 1);
417 : else /* non-printable character; print its code */
418 0 : luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
419 16 : break;
420 : }
421 530 : case 'd': { /* an 'int' */
422 530 : setivalue(L->top, va_arg(argp, int));
423 530 : goto top2str;
424 : }
425 2159 : case 'I': { /* a 'lua_Integer' */
426 2159 : setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
427 2159 : goto top2str;
428 : }
429 27 : case 'f': { /* a 'lua_Number' */
430 27 : setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
431 2716 : top2str: /* convert the top element to a string */
432 2716 : luaD_inctop(L);
433 2716 : luaO_tostring(L, L->top - 1);
434 2716 : break;
435 : }
436 15 : case 'p': { /* a pointer */
437 : char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
438 15 : void *p = va_arg(argp, void *);
439 15 : int l = lua_pointer2str(buff, sizeof(buff), p);
440 15 : pushstr(L, buff, l);
441 15 : break;
442 : }
443 14 : case 'U': { /* an 'int' as a UTF-8 sequence */
444 : char buff[UTF8BUFFSZ];
445 14 : int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
446 14 : pushstr(L, buff + UTF8BUFFSZ - l, l);
447 14 : break;
448 : }
449 8 : case '%': {
450 8 : pushstr(L, "%", 1);
451 8 : break;
452 : }
453 0 : default: {
454 0 : luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
455 0 : *(e + 1));
456 : }
457 : }
458 6712 : n += 2;
459 6712 : fmt = e+2;
460 : }
461 5083 : luaD_checkstack(L, 1);
462 5083 : pushstr(L, fmt, strlen(fmt));
463 5083 : if (n > 0) luaV_concat(L, n + 1);
464 5083 : return svalue(L->top - 1);
465 : }
466 :
467 :
468 501 : const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
469 : const char *msg;
470 : va_list argp;
471 501 : va_start(argp, fmt);
472 501 : msg = luaO_pushvfstring(L, fmt, argp);
473 501 : va_end(argp);
474 501 : return msg;
475 : }
476 :
477 :
478 : /* number of chars of a literal string without the ending \0 */
479 : #define LL(x) (sizeof(x)/sizeof(char) - 1)
480 :
481 : #define RETS "..."
482 : #define PRE "[string \""
483 : #define POS "\"]"
484 :
485 : #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
486 :
487 507 : void luaO_chunkid (char *out, const char *source, size_t bufflen) {
488 507 : size_t l = strlen(source);
489 507 : if (*source == '=') { /* 'literal' source */
490 63 : if (l <= bufflen) /* small enough? */
491 63 : memcpy(out, source + 1, l * sizeof(char));
492 : else { /* truncate it */
493 0 : addstr(out, source + 1, bufflen - 1);
494 0 : *out = '\0';
495 : }
496 : }
497 444 : else if (*source == '@') { /* file name */
498 405 : if (l <= bufflen) /* small enough? */
499 405 : memcpy(out, source + 1, l * sizeof(char));
500 : else { /* add '...' before rest of name */
501 0 : addstr(out, RETS, LL(RETS));
502 0 : bufflen -= LL(RETS);
503 0 : memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
504 : }
505 : }
506 : else { /* string; format as [string "source"] */
507 39 : const char *nl = strchr(source, '\n'); /* find first new line (if any) */
508 39 : addstr(out, PRE, LL(PRE)); /* add prefix */
509 39 : bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
510 39 : if (l < bufflen && nl == NULL) { /* small one-line source? */
511 29 : addstr(out, source, l); /* keep it */
512 : }
513 : else {
514 10 : if (nl != NULL) l = nl - source; /* stop at first newline */
515 10 : if (l > bufflen) l = bufflen;
516 10 : addstr(out, source, l);
517 10 : addstr(out, RETS, LL(RETS));
518 : }
519 39 : memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
520 : }
521 507 : }
522 :
|