aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-30 11:00:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-30 11:00:14 -0300
commit34ac039fb84e3c12fb8c96c9c99c34224c09872b (patch)
treea859f6338c6c851088a67b129765de662ed6f223
parent1aa526263405fb4906eafab3011b13de4e5daf73 (diff)
downloadlua-34ac039fb84e3c12fb8c96c9c99c34224c09872b.tar.gz
lua-34ac039fb84e3c12fb8c96c9c99c34224c09872b.tar.bz2
lua-34ac039fb84e3c12fb8c96c9c99c34224c09872b.zip
new macro 'cvt2str' to better control whether numbers are convertible
to strings
-rw-r--r--lapi.c12
-rw-r--r--ldebug.c5
-rw-r--r--lobject.c39
-rw-r--r--lobject.h3
-rw-r--r--lvm.c37
-rw-r--r--lvm.h10
6 files changed, 54 insertions, 52 deletions
diff --git a/lapi.c b/lapi.c
index 680630dd..eb901cb3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.230 2014/07/21 16:02:57 roberto Exp roberto $ 2** $Id: lapi.c,v 2.231 2014/07/22 18:07:47 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -279,8 +279,8 @@ LUA_API int lua_isnumber (lua_State *L, int idx) {
279 279
280 280
281LUA_API int lua_isstring (lua_State *L, int idx) { 281LUA_API int lua_isstring (lua_State *L, int idx) {
282 int t = lua_type(L, idx); 282 const TValue *o = index2addr(L, idx);
283 return (t == LUA_TSTRING || t == LUA_TNUMBER); 283 return (ttisstring(o) || cvt2str(o));
284} 284}
285 285
286 286
@@ -371,14 +371,14 @@ LUA_API int lua_toboolean (lua_State *L, int idx) {
371LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { 371LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
372 StkId o = index2addr(L, idx); 372 StkId o = index2addr(L, idx);
373 if (!ttisstring(o)) { 373 if (!ttisstring(o)) {
374 lua_lock(L); /* `luaV_tostring' may create a new string */ 374 if (!cvt2str(o)) { /* not convertible? */
375 if (!luaV_tostring(L, o)) { /* conversion failed? */
376 if (len != NULL) *len = 0; 375 if (len != NULL) *len = 0;
377 lua_unlock(L);
378 return NULL; 376 return NULL;
379 } 377 }
378 lua_lock(L); /* `luaO_tostring' may create a new string */
380 luaC_checkGC(L); 379 luaC_checkGC(L);
381 o = index2addr(L, idx); /* previous call may reallocate the stack */ 380 o = index2addr(L, idx); /* previous call may reallocate the stack */
381 luaO_tostring(L, o);
382 lua_unlock(L); 382 lua_unlock(L);
383 } 383 }
384 if (len != NULL) *len = tsvalue(o)->len; 384 if (len != NULL) *len = tsvalue(o)->len;
diff --git a/ldebug.c b/ldebug.c
index f7b2866e..e31c0607 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.98 2014/07/15 21:26:50 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.99 2014/07/17 12:30:53 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -526,8 +526,7 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
526 526
527 527
528l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { 528l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
529 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; 529 if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
530 lua_assert(!ttisstring(p1) && !ttisnumber(p1));
531 luaG_typeerror(L, p1, "concatenate"); 530 luaG_typeerror(L, p1, "concatenate");
532} 531}
533 532
diff --git a/lobject.c b/lobject.c
index cd049075..d079e937 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.86 2014/05/12 21:44:17 roberto Exp roberto $ 2** $Id: lobject.c,v 2.87 2014/06/30 19:48:08 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -327,6 +327,32 @@ int luaO_utf8esc (char *buff, unsigned int x) {
327} 327}
328 328
329 329
330/* maximum length of the conversion of a number to a string */
331#define MAXNUMBER2STR 50
332
333
334/*
335** Convert a number object to a string
336*/
337void luaO_tostring (lua_State *L, StkId obj) {
338 char buff[MAXNUMBER2STR];
339 size_t len;
340 lua_assert(ttisnumber(obj));
341 if (ttisinteger(obj))
342 len = lua_integer2str(buff, ivalue(obj));
343 else {
344 len = lua_number2str(buff, fltvalue(obj));
345#if !defined(LUA_COMPAT_FLOATSTRING)
346 if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
347 buff[len++] = '.';
348 buff[len++] = '0'; /* adds '.0' to result */
349 }
350#endif
351 }
352 setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
353}
354
355
330static void pushstr (lua_State *L, const char *str, size_t l) { 356static void pushstr (lua_State *L, const char *str, size_t l) {
331 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); 357 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
332} 358}
@@ -349,24 +375,23 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
349 break; 375 break;
350 } 376 }
351 case 'c': { 377 case 'c': {
352 char buff; 378 char buff = cast(char, va_arg(argp, int));
353 buff = cast(char, va_arg(argp, int));
354 pushstr(L, &buff, 1); 379 pushstr(L, &buff, 1);
355 break; 380 break;
356 } 381 }
357 case 'd': { 382 case 'd': {
358 setivalue(L->top++, cast_int(va_arg(argp, int))); 383 setivalue(L->top++, va_arg(argp, int));
359 luaV_tostring(L, L->top - 1); 384 luaO_tostring(L, L->top - 1);
360 break; 385 break;
361 } 386 }
362 case 'I': { 387 case 'I': {
363 setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt))); 388 setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt)));
364 luaV_tostring(L, L->top - 1); 389 luaO_tostring(L, L->top - 1);
365 break; 390 break;
366 } 391 }
367 case 'f': { 392 case 'f': {
368 setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); 393 setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
369 luaV_tostring(L, L->top - 1); 394 luaO_tostring(L, L->top - 1);
370 break; 395 break;
371 } 396 }
372 case 'p': { 397 case 'p': {
diff --git a/lobject.h b/lobject.h
index 93356dd2..8097853c 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.99 2014/07/18 14:46:47 roberto Exp roberto $ 2** $Id: lobject.h,v 2.100 2014/07/29 16:22:24 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -527,6 +527,7 @@ LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
527 const TValue *p2, TValue *res); 527 const TValue *p2, TValue *res);
528LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); 528LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
529LUAI_FUNC int luaO_hexavalue (int c); 529LUAI_FUNC int luaO_hexavalue (int c);
530LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
530LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, 531LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
531 va_list argp); 532 va_list argp);
532LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); 533LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
diff --git a/lvm.c b/lvm.c
index ec5bf62b..89ef8997 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.219 2014/07/18 13:36:14 roberto Exp roberto $ 2** $Id: lvm.c,v 2.220 2014/07/21 16:02:10 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -33,10 +33,6 @@
33#define MAXTAGLOOP 2000 33#define MAXTAGLOOP 2000
34 34
35 35
36/* maximum length of the conversion of a number to a string */
37#define MAXNUMBER2STR 50
38
39
40/* 36/*
41** Similar to 'tonumber', but does not attempt to convert strings and 37** Similar to 'tonumber', but does not attempt to convert strings and
42** ensure correct precision (no extra bits). Used in comparisons. 38** ensure correct precision (no extra bits). Used in comparisons.
@@ -120,32 +116,6 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
120 116
121 117
122/* 118/*
123** Convert a number object to a string
124*/
125int luaV_tostring (lua_State *L, StkId obj) {
126 if (!ttisnumber(obj))
127 return 0;
128 else {
129 char buff[MAXNUMBER2STR];
130 size_t len;
131 if (ttisinteger(obj))
132 len = lua_integer2str(buff, ivalue(obj));
133 else {
134 len = lua_number2str(buff, fltvalue(obj));
135#if !defined(LUA_COMPAT_FLOATSTRING)
136 if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
137 buff[len++] = '.';
138 buff[len++] = '0'; /* adds '.0' to result */
139 }
140#endif
141 }
142 setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
143 return 1;
144 }
145}
146
147
148/*
149** Try to convert a 'for' limit to an integer, preserving the 119** Try to convert a 'for' limit to an integer, preserving the
150** semantics of the loop. 120** semantics of the loop.
151** (The following explanation assumes a non-negative step; it is valid 121** (The following explanation assumes a non-negative step; it is valid
@@ -374,7 +344,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
374 344
375 345
376/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ 346/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */
377#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) 347#define tostring(L,o) \
348 (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
378 349
379/* 350/*
380** Main operation for concatenation: concat 'total' values in the stack, 351** Main operation for concatenation: concat 'total' values in the stack,
@@ -385,7 +356,7 @@ void luaV_concat (lua_State *L, int total) {
385 do { 356 do {
386 StkId top = L->top; 357 StkId top = L->top;
387 int n = 2; /* number of elements handled in this pass (at least 2) */ 358 int n = 2; /* number of elements handled in this pass (at least 2) */
388 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) 359 if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
389 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); 360 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
390 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ 361 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
391 cast_void(tostring(L, top - 2)); /* result is first operand */ 362 cast_void(tostring(L, top - 2)); /* result is first operand */
diff --git a/lvm.h b/lvm.h
index 6dff8b1e..0a4984cb 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.30 2014/05/12 21:22:05 roberto Exp roberto $ 2** $Id: lvm.h,v 2.31 2014/05/26 17:10:22 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,12 +24,18 @@
24#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 24#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
25 25
26 26
27#if !defined(LUA_NOCVTN2S)
28#define cvt2str(o) ttisnumber(o)
29#else
30#define cvt2str(o) 0 /* no convertion from numbers to strings */
31#endif
32
33
27LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 34LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
28LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 35LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
29LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 36LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
30LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 37LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
31LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p); 38LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p);
32LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
33LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 39LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
34 StkId val); 40 StkId val);
35LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 41LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,