1/*
2 *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
18 *  USA
19 *
20 */
21
22#include "config.h"
23#include "NumberPrototype.h"
24
25#include "BigInteger.h"
26#include "Error.h"
27#include "JSFunction.h"
28#include "JSGlobalObject.h"
29#include "JSString.h"
30#include "JSCInlines.h"
31#include "Uint16WithFraction.h"
32#include <wtf/dtoa.h>
33#include <wtf/Assertions.h>
34#include <wtf/MathExtras.h>
35#include <wtf/Vector.h>
36#include <wtf/dtoa/double-conversion.h>
37
38using namespace WTF::double_conversion;
39
40// To avoid conflict with WTF::StringBuilder.
41typedef WTF::double_conversion::StringBuilder DoubleConversionStringBuilder;
42
43namespace JSC {
44
45static EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState*);
46static EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState*);
47static EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*);
48static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*);
49static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*);
50static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);
51static EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState*);
52
53}
54
55#include "NumberPrototype.lut.h"
56
57namespace JSC {
58
59const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0, ExecState::numberPrototypeTable, CREATE_METHOD_TABLE(NumberPrototype) };
60
61/* Source for NumberPrototype.lut.h
62@begin numberPrototypeTable
63  toString          numberProtoFuncToString         DontEnum|Function 1
64  toLocaleString    numberProtoFuncToLocaleString   DontEnum|Function 0
65  valueOf           numberProtoFuncValueOf          DontEnum|Function 0
66  toFixed           numberProtoFuncToFixed          DontEnum|Function 1
67  toExponential     numberProtoFuncToExponential    DontEnum|Function 1
68  toPrecision       numberProtoFuncToPrecision      DontEnum|Function 1
69  clz               numberProtoFuncClz              DontEnum|Function 1
70@end
71*/
72
73STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NumberPrototype);
74
75NumberPrototype::NumberPrototype(VM& vm, Structure* structure)
76    : NumberObject(vm, structure)
77{
78}
79
80void NumberPrototype::finishCreation(VM& vm, JSGlobalObject*)
81{
82    Base::finishCreation(vm);
83    setInternalValue(vm, jsNumber(0));
84
85    ASSERT(inherits(info()));
86}
87
88bool NumberPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
89{
90    return getStaticFunctionSlot<NumberObject>(exec, ExecState::numberPrototypeTable(exec->vm()), jsCast<NumberPrototype*>(object), propertyName, slot);
91}
92
93// ------------------------------ Functions ---------------------------
94
95static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double& x)
96{
97    if (thisValue.isInt32()) {
98        x = thisValue.asInt32();
99        return true;
100    }
101
102    if (thisValue.isDouble()) {
103        x = thisValue.asDouble();
104        return true;
105    }
106
107    if (thisValue.isCell() && thisValue.asCell()->type() == NumberObjectType) {
108        x = static_cast<const NumberObject*>(thisValue.asCell())->internalValue().asNumber();
109        return true;
110    }
111
112    return false;
113}
114
115static ALWAYS_INLINE bool getIntegerArgumentInRange(ExecState* exec, int low, int high, int& result, bool& isUndefined)
116{
117    result = 0;
118    isUndefined = false;
119
120    JSValue argument0 = exec->argument(0);
121    if (argument0.isUndefined()) {
122        isUndefined = true;
123        return true;
124    }
125
126    double asDouble = argument0.toInteger(exec);
127    if (asDouble < low || asDouble > high)
128        return false;
129
130    result = static_cast<int>(asDouble);
131    return true;
132}
133
134// The largest finite floating point number is 1.mantissa * 2^(0x7fe-0x3ff).
135// Since 2^N in binary is a one bit followed by N zero bits. 1 * 2^3ff requires
136// at most 1024 characters to the left of a decimal point, in base 2 (1025 if
137// we include a minus sign). For the fraction, a value with an exponent of 0
138// has up to 52 bits to the right of the decimal point. Each decrement of the
139// exponent down to a minimum of -0x3fe adds an additional digit to the length
140// of the fraction. As such the maximum fraction size is 1075 (1076 including
141// a point). We pick a buffer size such that can simply place the point in the
142// center of the buffer, and are guaranteed to have enough space in each direction
143// fo any number of digits an IEEE number may require to represent.
144typedef char RadixBuffer[2180];
145
146// Mapping from integers 0..35 to digit identifying this value, for radix 2..36.
147static const char radixDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
148
149static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radix)
150{
151    ASSERT(std::isfinite(number));
152    ASSERT(radix >= 2 && radix <= 36);
153
154    // Position the decimal point at the center of the string, set
155    // the startOfResultString pointer to point at the decimal point.
156    char* decimalPoint = buffer + sizeof(buffer) / 2;
157    char* startOfResultString = decimalPoint;
158
159    // Extract the sign.
160    bool isNegative = number < 0;
161    if (std::signbit(number))
162        number = -number;
163    double integerPart = floor(number);
164
165    // We use this to test for odd values in odd radix bases.
166    // Where the base is even, (e.g. 10), to determine whether a value is even we need only
167    // consider the least significant digit. For example, 124 in base 10 is even, because '4'
168    // is even. if the radix is odd, then the radix raised to an integer power is also odd.
169    // E.g. in base 5, 124 represents (1 * 125 + 2 * 25 + 4 * 5). Since each digit in the value
170    // is multiplied by an odd number, the result is even if the sum of all digits is even.
171    //
172    // For the integer portion of the result, we only need test whether the integer value is
173    // even or odd. For each digit of the fraction added, we should invert our idea of whether
174    // the number is odd if the new digit is odd.
175    //
176    // Also initialize digit to this value; for even radix values we only need track whether
177    // the last individual digit was odd.
178    bool integerPartIsOdd = integerPart <= static_cast<double>(0x1FFFFFFFFFFFFFull) && static_cast<int64_t>(integerPart) & 1;
179    ASSERT(integerPartIsOdd == static_cast<bool>(fmod(integerPart, 2)));
180    bool isOddInOddRadix = integerPartIsOdd;
181    uint32_t digit = integerPartIsOdd;
182
183    // Check if the value has a fractional part to convert.
184    double fractionPart = number - integerPart;
185    if (fractionPart) {
186        // Write the decimal point now.
187        *decimalPoint = '.';
188
189        // Higher precision representation of the fractional part.
190        Uint16WithFraction fraction(fractionPart);
191
192        bool needsRoundingUp = false;
193        char* endOfResultString = decimalPoint + 1;
194
195        // Calculate the delta from the current number to the next & previous possible IEEE numbers.
196        double nextNumber = nextafter(number, std::numeric_limits<double>::infinity());
197        double lastNumber = nextafter(number, -std::numeric_limits<double>::infinity());
198        ASSERT(std::isfinite(nextNumber) && !std::signbit(nextNumber));
199        ASSERT(std::isfinite(lastNumber) && !std::signbit(lastNumber));
200        double deltaNextDouble = nextNumber - number;
201        double deltaLastDouble = number - lastNumber;
202        ASSERT(std::isfinite(deltaNextDouble) && !std::signbit(deltaNextDouble));
203        ASSERT(std::isfinite(deltaLastDouble) && !std::signbit(deltaLastDouble));
204
205        // We track the delta from the current value to the next, to track how many digits of the
206        // fraction we need to write. For example, if the value we are converting is precisely
207        // 1.2345, so far we have written the digits "1.23" to a string leaving a remainder of
208        // 0.45, and we want to determine whether we can round off, or whether we need to keep
209        // appending digits ('4'). We can stop adding digits provided that then next possible
210        // lower IEEE value is further from 1.23 than the remainder we'd be rounding off (0.45),
211        // which is to say, less than 1.2255. Put another way, the delta between the prior
212        // possible value and this number must be more than 2x the remainder we'd be rounding off
213        // (or more simply half the delta between numbers must be greater than the remainder).
214        //
215        // Similarly we need track the delta to the next possible value, to dertermine whether
216        // to round up. In almost all cases (other than at exponent boundaries) the deltas to
217        // prior and subsequent values are identical, so we don't need track then separately.
218        if (deltaNextDouble != deltaLastDouble) {
219            // Since the deltas are different track them separately. Pre-multiply by 0.5.
220            Uint16WithFraction halfDeltaNext(deltaNextDouble, 1);
221            Uint16WithFraction halfDeltaLast(deltaLastDouble, 1);
222
223            while (true) {
224                // examine the remainder to determine whether we should be considering rounding
225                // up or down. If remainder is precisely 0.5 rounding is to even.
226                int dComparePoint5 = fraction.comparePoint5();
227                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
228                    // Check for rounding up; are we closer to the value we'd round off to than
229                    // the next IEEE value would be?
230                    if (fraction.sumGreaterThanOne(halfDeltaNext)) {
231                        needsRoundingUp = true;
232                        break;
233                    }
234                } else {
235                    // Check for rounding down; are we closer to the value we'd round off to than
236                    // the prior IEEE value would be?
237                    if (fraction < halfDeltaLast)
238                        break;
239                }
240
241                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
242                // Write a digit to the string.
243                fraction *= radix;
244                digit = fraction.floorAndSubtract();
245                *endOfResultString++ = radixDigits[digit];
246                // Keep track whether the portion written is currently even, if the radix is odd.
247                if (digit & 1)
248                    isOddInOddRadix = !isOddInOddRadix;
249
250                // Shift the fractions by radix.
251                halfDeltaNext *= radix;
252                halfDeltaLast *= radix;
253            }
254        } else {
255            // This code is identical to that above, except since deltaNextDouble != deltaLastDouble
256            // we don't need to track these two values separately.
257            Uint16WithFraction halfDelta(deltaNextDouble, 1);
258
259            while (true) {
260                int dComparePoint5 = fraction.comparePoint5();
261                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
262                    if (fraction.sumGreaterThanOne(halfDelta)) {
263                        needsRoundingUp = true;
264                        break;
265                    }
266                } else if (fraction < halfDelta)
267                    break;
268
269                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
270                fraction *= radix;
271                digit = fraction.floorAndSubtract();
272                if (digit & 1)
273                    isOddInOddRadix = !isOddInOddRadix;
274                *endOfResultString++ = radixDigits[digit];
275
276                halfDelta *= radix;
277            }
278        }
279
280        // Check if the fraction needs rounding off (flag set in the loop writing digits, above).
281        if (needsRoundingUp) {
282            // Whilst the last digit is the maximum in the current radix, remove it.
283            // e.g. rounding up the last digit in "12.3999" is the same as rounding up the
284            // last digit in "12.3" - both round up to "12.4".
285            while (endOfResultString[-1] == radixDigits[radix - 1])
286                --endOfResultString;
287
288            // Radix digits are sequential in ascii/unicode, except for '9' and 'a'.
289            // E.g. the first 'if' case handles rounding 67.89 to 67.8a in base 16.
290            // The 'else if' case handles rounding of all other digits.
291            if (endOfResultString[-1] == '9')
292                endOfResultString[-1] = 'a';
293            else if (endOfResultString[-1] != '.')
294                ++endOfResultString[-1];
295            else {
296                // One other possibility - there may be no digits to round up in the fraction
297                // (or all may be been rounded off already), in which case we may need to
298                // round into the integer portion of the number. Remove the decimal point.
299                --endOfResultString;
300                // In order to get here there must have been a non-zero fraction, in which case
301                // there must be at least one bit of the value's mantissa not in use in the
302                // integer part of the number. As such, adding to the integer part should not
303                // be able to lose precision.
304                ASSERT((integerPart + 1) - integerPart == 1);
305                ++integerPart;
306            }
307        } else {
308            // We only need to check for trailing zeros if the value does not get rounded up.
309            while (endOfResultString[-1] == '0')
310                --endOfResultString;
311        }
312
313        *endOfResultString = '\0';
314        ASSERT(endOfResultString < buffer + sizeof(buffer));
315    } else
316        *decimalPoint = '\0';
317
318    BigInteger units(integerPart);
319
320    // Always loop at least once, to emit at least '0'.
321    do {
322        ASSERT(buffer < startOfResultString);
323
324        // Read a single digit and write it to the front of the string.
325        // Divide by radix to remove one digit from the value.
326        digit = units.divide(radix);
327        *--startOfResultString = radixDigits[digit];
328    } while (!!units);
329
330    // If the number is negative, prepend '-'.
331    if (isNegative)
332        *--startOfResultString = '-';
333    ASSERT(buffer <= startOfResultString);
334
335    return startOfResultString;
336}
337
338static String toStringWithRadix(int32_t number, unsigned radix)
339{
340    LChar buf[1 + 32]; // Worst case is radix == 2, which gives us 32 digits + sign.
341    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
342    LChar* p = end;
343
344    bool negative = false;
345    uint32_t positiveNumber = number;
346    if (number < 0) {
347        negative = true;
348        positiveNumber = -number;
349    }
350
351    while (positiveNumber) {
352        uint32_t index = positiveNumber % radix;
353        ASSERT(index < sizeof(radixDigits));
354        *--p = static_cast<LChar>(radixDigits[index]);
355        positiveNumber /= radix;
356    }
357    if (negative)
358        *--p = '-';
359
360    return String(p, static_cast<unsigned>(end - p));
361}
362
363// toExponential converts a number to a string, always formatting as an expoential.
364// This method takes an optional argument specifying a number of *decimal places*
365// to round the significand to (or, put another way, this method optionally rounds
366// to argument-plus-one significant figures).
367EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
368{
369    double x;
370    if (!toThisNumber(exec->thisValue(), x))
371        return throwVMTypeError(exec);
372
373    // Get the argument.
374    int decimalPlacesInExponent;
375    bool isUndefined;
376    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined))
377        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toExponential() argument must be between 0 and 20")));
378
379    // Handle NaN and Infinity.
380    if (!std::isfinite(x))
381        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
382
383    // Round if the argument is not undefined, always format as exponential.
384    char buffer[WTF::NumberToStringBufferLength];
385    DoubleConversionStringBuilder builder(buffer, WTF::NumberToStringBufferLength);
386    const DoubleToStringConverter& converter = DoubleToStringConverter::EcmaScriptConverter();
387    builder.Reset();
388    isUndefined
389        ? converter.ToExponential(x, -1, &builder)
390        : converter.ToExponential(x, decimalPlacesInExponent, &builder);
391    return JSValue::encode(jsString(exec, String(builder.Finalize())));
392}
393
394// toFixed converts a number to a string, always formatting as an a decimal fraction.
395// This method takes an argument specifying a number of decimal places to round the
396// significand to. However when converting large values (1e+21 and above) this
397// method will instead fallback to calling ToString.
398EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
399{
400    double x;
401    if (!toThisNumber(exec->thisValue(), x))
402        return throwVMTypeError(exec);
403
404    // Get the argument.
405    int decimalPlaces;
406    bool isUndefined; // This is ignored; undefined treated as 0.
407    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined))
408        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toFixed() argument must be between 0 and 20")));
409
410    // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
411    // This also covers Ininity, and structure the check so that NaN
412    // values are also handled by numberToString
413    if (!(fabs(x) < 1e+21))
414        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
415
416    // The check above will return false for NaN or Infinity, these will be
417    // handled by numberToString.
418    ASSERT(std::isfinite(x));
419
420    NumberToStringBuffer buffer;
421    return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer))));
422}
423
424// toPrecision converts a number to a string, takeing an argument specifying a
425// number of significant figures to round the significand to. For positive
426// exponent, all values that can be represented using a decimal fraction will
427// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
428// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
429// For negative exponents values >= 1e-6 are formated as decimal fractions,
430// with smaller values converted to exponential representation.
431EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
432{
433    double x;
434    if (!toThisNumber(exec->thisValue(), x))
435        return throwVMTypeError(exec);
436
437    // Get the argument.
438    int significantFigures;
439    bool isUndefined;
440    if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined))
441        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toPrecision() argument must be between 1 and 21")));
442
443    // To precision called with no argument is treated as ToString.
444    if (isUndefined)
445        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
446
447    // Handle NaN and Infinity.
448    if (!std::isfinite(x))
449        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
450
451    NumberToStringBuffer buffer;
452    return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
453}
454
455#if !COMPILER(GCC) && !COMPILER(CLANG)
456static inline int clz(uint32_t number)
457{
458    int zeroCount = 0;
459    for (int i = 31; i >= 0; i--) {
460        if (!(number >> i))
461            zeroCount++;
462        else
463            break;
464    }
465    return zeroCount;
466}
467#endif
468
469EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState* exec)
470{
471    double x;
472    if (!toThisNumber(exec->thisValue(), x))
473        return throwVMTypeError(exec);
474
475    if (!std::isfinite(x))
476        return JSValue::encode(JSValue(x));
477
478    uint32_t number = toUInt32(x);
479#if COMPILER(GCC) || COMPILER(CLANG)
480    int zeroCount = 32;
481    if (number)
482        zeroCount = __builtin_clz(number);
483
484    return JSValue::encode(JSValue(zeroCount));
485#else
486    return JSValue::encode(JSValue(clz(number)));
487#endif
488}
489
490static inline int32_t extractRadixFromArgs(ExecState* exec)
491{
492    JSValue radixValue = exec->argument(0);
493    int32_t radix;
494    if (radixValue.isInt32())
495        radix = radixValue.asInt32();
496    else if (radixValue.isUndefined())
497        radix = 10;
498    else
499        radix = static_cast<int32_t>(radixValue.toInteger(exec)); // nan -> 0
500
501    return radix;
502}
503
504static inline EncodedJSValue integerValueToString(ExecState* exec, int32_t radix, int32_t value)
505{
506    // A negative value casted to unsigned would be bigger than 36 (the max radix).
507    if (static_cast<unsigned>(value) < static_cast<unsigned>(radix)) {
508        ASSERT(value <= 36);
509        ASSERT(value >= 0);
510        VM* vm = &exec->vm();
511        return JSValue::encode(vm->smallStrings.singleCharacterString(radixDigits[value]));
512    }
513
514    if (radix == 10) {
515        VM* vm = &exec->vm();
516        return JSValue::encode(jsString(vm, vm->numericStrings.add(value)));
517    }
518
519    return JSValue::encode(jsString(exec, toStringWithRadix(value, radix)));
520
521}
522
523EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
524{
525    double doubleValue;
526    if (!toThisNumber(exec->thisValue(), doubleValue))
527        return throwVMTypeError(exec);
528
529    int32_t radix = extractRadixFromArgs(exec);
530    if (radix < 2 || radix > 36)
531        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
532
533    int32_t integerValue = static_cast<int32_t>(doubleValue);
534    if (integerValue == doubleValue)
535        return integerValueToString(exec, radix, integerValue);
536
537    if (radix == 10) {
538        VM* vm = &exec->vm();
539        return JSValue::encode(jsString(vm, vm->numericStrings.add(doubleValue)));
540    }
541
542    if (!std::isfinite(doubleValue))
543        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(doubleValue)));
544
545    RadixBuffer s;
546    return JSValue::encode(jsString(exec, toStringWithRadix(s, doubleValue, radix)));
547}
548
549EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec)
550{
551    double x;
552    if (!toThisNumber(exec->thisValue(), x))
553        return throwVMTypeError(exec);
554
555    return JSValue::encode(jsNumber(x).toString(exec));
556}
557
558EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec)
559{
560    double x;
561    if (!toThisNumber(exec->thisValue(), x))
562        return throwVMTypeError(exec);
563    return JSValue::encode(jsNumber(x));
564}
565
566} // namespace JSC
567