new macro 'cvt2str' to better control whether numbers are convertible

to strings
This commit is contained in:
Roberto Ierusalimschy
2014-07-30 11:00:14 -03:00
parent 1aa5262634
commit 34ac039fb8
6 changed files with 54 additions and 52 deletions

37
lvm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.219 2014/07/18 13:36:14 roberto Exp roberto $
** $Id: lvm.c,v 2.220 2014/07/21 16:02:10 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -33,10 +33,6 @@
#define MAXTAGLOOP 2000
/* maximum length of the conversion of a number to a string */
#define MAXNUMBER2STR 50
/*
** Similar to 'tonumber', but does not attempt to convert strings and
** ensure correct precision (no extra bits). Used in comparisons.
@@ -119,32 +115,6 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
}
/*
** Convert a number object to a string
*/
int luaV_tostring (lua_State *L, StkId obj) {
if (!ttisnumber(obj))
return 0;
else {
char buff[MAXNUMBER2STR];
size_t len;
if (ttisinteger(obj))
len = lua_integer2str(buff, ivalue(obj));
else {
len = lua_number2str(buff, fltvalue(obj));
#if !defined(LUA_COMPAT_FLOATSTRING)
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
buff[len++] = '.';
buff[len++] = '0'; /* adds '.0' to result */
}
#endif
}
setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
return 1;
}
}
/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
@@ -374,7 +344,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */
#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
#define tostring(L,o) \
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
/*
** Main operation for concatenation: concat 'total' values in the stack,
@@ -385,7 +356,7 @@ void luaV_concat (lua_State *L, int total) {
do {
StkId top = L->top;
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1))
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
cast_void(tostring(L, top - 2)); /* result is first operand */