@@ -11261,9 +11261,10 @@ static JSValue js_dtoa(JSContext *ctx,
1126111261 return JS_NewStringLen(ctx, buf, len);
1126211262}
1126311263
11264+ /* d is guaranteed to be finite */
1126411265static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
1126511266{
11266- char buf[2200], *ptr, *ptr2;
11267+ char buf[2200], *ptr, *ptr2, *ptr3 ;
1126711268 /* d is finite */
1126811269 int sign = d < 0;
1126911270 int digit;
@@ -11272,8 +11273,8 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
1127211273 d = fabs(d);
1127311274 d0 = trunc(d);
1127411275 frac = d - d0;
11275- ptr = buf + 1100;
11276- * ptr = '\0';
11276+ ptr2 = buf + 1100; /* ptr2 points to the end of the string */
11277+ ptr = ptr2; /* ptr points to the beginning of the string */
1127711278 if (d0 <= MAX_SAFE_INTEGER) {
1127811279 int64_t n = n0 = (int64_t)d0;
1127911280 while (n >= radix) {
@@ -11297,7 +11298,6 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
1129711298 if (frac != 0) {
1129811299 double log2_radix = log2(radix);
1129911300 double prec = 1023 + 51; // handle subnormals
11300- ptr2 = buf + 1100;
1130111301 *ptr2++ = '.';
1130211302 while (frac != 0 && n0 <= MAX_SAFE_INTEGER/2 && prec > 0) {
1130311303 frac *= radix;
@@ -11307,32 +11307,45 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
1130711307 n0 = n0 * radix + digit;
1130811308 prec -= log2_radix;
1130911309 }
11310- *ptr2 = '\0';
1131111310 if (frac * radix >= radix / 2) {
11311+ /* round up the string representation manually */
1131211312 char nine = digits36[radix - 1];
11313- // round to closest
11314- while (ptr2[-1] == nine)
11315- *--ptr2 = '\0';
11313+ while (ptr2[-1] == nine) {
11314+ /* strip trailing '9' or equivalent digits */
11315+ ptr2--;
11316+ }
1131611317 if (ptr2[-1] == '.') {
11317- *--ptr2 = '\0';
11318- while (ptr2[-1] == nine)
11319- *--ptr2 = '0';
11318+ /* strip the 'decimal' point */
11319+ ptr2--;
11320+ /* increment the integral part */
11321+ for (ptr3 = ptr2;;) {
11322+ if (ptr3[-1] != nine) {
11323+ ptr3[-1] = (ptr3[-1] == '9') ? 'a' : ptr3[-1] + 1;
11324+ break;
11325+ }
11326+ *--ptr3 = '0';
11327+ if (ptr3 <= ptr) {
11328+ /* prepend a '1' if number was all nines */
11329+ *--ptr = '1';
11330+ break;
11331+ }
11332+ }
11333+ } else {
11334+ /* increment the last fractional digit */
11335+ ptr2[-1] = (ptr2[-1] == '9') ? 'a' : ptr2[-1] + 1;
1132011336 }
11321- if (ptr2 - 1 == ptr)
11322- *--ptr = '1';
11323- else
11324- ptr2[-1] += 1;
1132511337 } else {
11338+ /* strip trailing fractional zeroes */
1132611339 while (ptr2[-1] == '0')
11327- *--ptr2 = '\0' ;
11328- if (ptr2[-1] == '.')
11329- *-- ptr2 = '\0' ;
11340+ ptr2-- ;
11341+ /* strip the 'decimal' point if last */
11342+ ptr2 -= ( ptr2[-1] == '.') ;
1133011343 }
1133111344 }
1133211345done:
1133311346 ptr[-1] = '-';
1133411347 ptr -= sign;
11335- return JS_NewString (ctx, ptr);
11348+ return js_new_string8 (ctx, (uint8_t *)ptr, ptr2 - ptr);
1133611349}
1133711350
1133811351JSValue JS_ToStringInternal(JSContext *ctx, JSValue val, BOOL is_ToPropertyKey)
0 commit comments