aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-05-20 00:40:51 +0200
committerMike Pall <mike>2010-05-20 00:40:51 +0200
commit926f688cd0cc177a779ee3bdb2c6a346383dd8e4 (patch)
treed9539304a9f0d8cf1b8fd47d6252de6bfbe75b62 /src
parentc7a3103f41616defdd639ead97ce4ced18ad2206 (diff)
downloadluajit-926f688cd0cc177a779ee3bdb2c6a346383dd8e4.tar.gz
luajit-926f688cd0cc177a779ee3bdb2c6a346383dd8e4.tar.bz2
luajit-926f688cd0cc177a779ee3bdb2c6a346383dd8e4.zip
Canonicalize string conversion of nan, inf, -inf.
Diffstat (limited to 'src')
-rw-r--r--src/lib_base.c3
-rw-r--r--src/lib_string.c18
-rw-r--r--src/lj_str.c32
-rw-r--r--src/lj_str.h1
4 files changed, 42 insertions, 12 deletions
diff --git a/src/lib_base.c b/src/lib_base.c
index 66b514dc..1f677b50 100644
--- a/src/lib_base.c
+++ b/src/lib_base.c
@@ -413,8 +413,7 @@ LJLIB_CF(print)
413 size = strV(o)->len; 413 size = strV(o)->len;
414 } else if (shortcut && tvisnum(o)) { 414 } else if (shortcut && tvisnum(o)) {
415 char buf[LUAI_MAXNUMBER2STR]; 415 char buf[LUAI_MAXNUMBER2STR];
416 lua_Number n = numV(o); 416 size = lj_str_bufnum(buf, o);
417 size = (size_t)lua_number2str(buf, n);
418 str = buf; 417 str = buf;
419 } else { 418 } else {
420 copyTV(L, L->top+1, o); 419 copyTV(L, L->top+1, o);
diff --git a/src/lib_string.c b/src/lib_string.c
index 1231aeb2..528b3d0e 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -734,9 +734,23 @@ LJLIB_CF(string_format)
734 addintlen(form); 734 addintlen(form);
735 sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg)); 735 sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg));
736 break; 736 break;
737 case 'e': case 'E': case 'f': case 'g': case 'G': 737 case 'e': case 'E': case 'f': case 'g': case 'G': {
738 sprintf(buff, form, (double)lj_lib_checknum(L, arg)); 738 TValue tv;
739 tv.n = lj_lib_checknum(L, arg);
740 if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
741 /* Canonicalize output of non-finite values. */
742 size_t len = lj_str_bufnum(buff, &tv);
743 if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') {
744 buff[len-3] = buff[len-3] - 0x20;
745 buff[len-2] = buff[len-2] - 0x20;
746 buff[len-1] = buff[len-1] - 0x20;
747 }
748 luaL_addlstring(&b, buff, len);
749 continue;
750 }
751 sprintf(buff, form, (double)tv.n);
739 break; 752 break;
753 }
740 case 'q': 754 case 'q':
741 addquoted(L, &b, arg); 755 addquoted(L, &b, arg);
742 continue; 756 continue;
diff --git a/src/lj_str.c b/src/lj_str.c
index 7b38cecc..4a9477dd 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -173,13 +173,27 @@ parsedbl:
173 } 173 }
174} 174}
175 175
176/* Print number to buffer. Canonicalizes non-finite values. */
177size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o)
178{
179 if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) { /* Finite? */
180 lua_Number n = o->n;
181 return (size_t)lua_number2str(s, n);
182 } else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
183 s[0] = 'n'; s[1] = 'a'; s[2] = 'n'; return 3;
184 } else if ((o->u32.hi & 0x80000000) == 0) {
185 s[0] = 'i'; s[1] = 'n'; s[2] = 'f'; return 3;
186 } else {
187 s[0] = '-'; s[1] = 'i'; s[2] = 'n'; s[3] = 'f'; return 4;
188 }
189}
190
176/* Convert number to string. */ 191/* Convert number to string. */
177GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np) 192GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
178{ 193{
179 char s[LUAI_MAXNUMBER2STR]; 194 char buf[LUAI_MAXNUMBER2STR];
180 lua_Number n = *np; 195 size_t len = lj_str_bufnum(buf, (TValue *)np);
181 size_t len = (size_t)lua_number2str(s, n); 196 return lj_str_new(L, buf, len);
182 return lj_str_new(L, s, len);
183} 197}
184 198
185#if LJ_HASJIT 199#if LJ_HASJIT
@@ -252,10 +266,12 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
252 break; 266 break;
253 } 267 }
254 case 'f': { 268 case 'f': {
255 char buff[LUAI_MAXNUMBER2STR]; 269 char buf[LUAI_MAXNUMBER2STR];
256 lua_Number n = cast_num(va_arg(argp, LUAI_UACNUMBER)); 270 TValue tv;
257 MSize len = (MSize)lua_number2str(buff, n); 271 MSize len;
258 addstr(L, sb, buff, len); 272 tv.n = cast_num(va_arg(argp, LUAI_UACNUMBER));
273 len = (MSize)lj_str_bufnum(buf, &tv);
274 addstr(L, sb, buf, len);
259 break; 275 break;
260 } 276 }
261 case 'p': { 277 case 'p': {
diff --git a/src/lj_str.h b/src/lj_str.h
index cdb04568..50d1ae5f 100644
--- a/src/lj_str.h
+++ b/src/lj_str.h
@@ -22,6 +22,7 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
22/* Type conversions. */ 22/* Type conversions. */
23LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n); 23LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
24LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n); 24LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
25LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
25LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); 26LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
26#if LJ_HASJIT 27#if LJ_HASJIT
27LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); 28LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);