shithub: libmujs

Download patch

ref: b24fe47378839db220e747adba2d9b21386d0b85
parent: 69cb649c2ba55c0364c99f2adf20218feb4f53fc
author: Tor Andersson <tor@ccxvii.net>
date: Thu Mar 6 16:40:37 EST 2014

Handle NaN and Infinity in Number.toFixed and friends.

--- a/jsnumber.c
+++ b/jsnumber.c
@@ -22,38 +22,50 @@
 static void Np_toString(js_State *J, unsigned int argc)
 {
 	js_Object *self = js_toobject(J, 0);
+	int radix = js_isundefined(J, 1) ? 10 : js_tointeger(J, 1);
 	if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
+	if (radix < 2 || radix > 36)
+		js_rangeerror(J, "invalid radix");
+	if (radix != 10)
+		js_rangeerror(J, "invalid radix");
 	js_pushliteral(J, jsV_numbertostring(J, self->u.number));
 }
 
-static void Np_toFixed(js_State *J, unsigned int argc)
+/* Customized ToString() on a number */
+void numtostr(js_State *J, const char *fmt, int w, double n)
 {
 	char buf[40];
+	if (isnan(n)) js_pushliteral(J, "NaN");
+	else if (isinf(n)) js_pushliteral(J, n < 0 ? "-Infinity" : "Infinity");
+	else if (n == 0) js_pushliteral(J, "0");
+	else {
+		sprintf(buf, fmt, w, n);
+		js_pushstring(J, buf);
+	}
+}
+
+static void Np_toFixed(js_State *J, unsigned int argc)
+{
 	js_Object *self = js_toobject(J, 0);
-	int width = js_tonumber(J, 1);
+	int width = js_tointeger(J, 1);
 	if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
-	sprintf(buf, "%.*f", width, self->u.number);
-	js_pushstring(J, buf);
+	numtostr(J, "%.*f", width, self->u.number);
 }
 
 static void Np_toExponential(js_State *J, unsigned int argc)
 {
-	char buf[40];
 	js_Object *self = js_toobject(J, 0);
-	int width = js_tonumber(J, 1);
+	int width = js_tointeger(J, 1);
 	if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
-	sprintf(buf, "%.*e", width, self->u.number);
-	js_pushstring(J, buf);
+	numtostr(J, "%.*e", width, self->u.number);
 }
 
 static void Np_toPrecision(js_State *J, unsigned int argc)
 {
-	char buf[40];
 	js_Object *self = js_toobject(J, 0);
-	int width = js_tonumber(J, 1);
+	int width = js_tointeger(J, 1);
 	if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
-	sprintf(buf, "%.*g", width, self->u.number);
-	js_pushstring(J, buf);
+	numtostr(J, "%.*g", width, self->u.number);
 }
 
 void jsB_initnumber(js_State *J)