/*
 *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
 *  Copyright (C) 2007-2019 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 *
 */

#include "config.h"
#include "NumberPrototype.h"

#include "BigInteger.h"
#include "Error.h"
#include "IntlNumberFormat.h"
#include "IntlObject.h"
#include "JSCInlines.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
#include "ParseInt.h"
#include "Uint16WithFraction.h"
#include <wtf/dtoa.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/dtoa/double-conversion.h>

using DoubleToStringConverter = WTF::double_conversion::DoubleToStringConverter;

// To avoid conflict with WTF::StringBuilder.
typedef WTF::double_conversion::StringBuilder DoubleConversionStringBuilder;

namespace JSC {

static EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(JSGlobalObject*, CallFrame*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(JSGlobalObject*, CallFrame*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(JSGlobalObject*, CallFrame*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(JSGlobalObject*, CallFrame*);

}

#include "NumberPrototype.lut.h"

namespace JSC {

const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, &numberPrototypeTable, nullptr, CREATE_METHOD_TABLE(NumberPrototype) };

/* Source for NumberPrototype.lut.h
@begin numberPrototypeTable
  toLocaleString    numberProtoFuncToLocaleString   DontEnum|Function 0
  valueOf           numberProtoFuncValueOf          DontEnum|Function 0
  toFixed           numberProtoFuncToFixed          DontEnum|Function 1
  toExponential     numberProtoFuncToExponential    DontEnum|Function 1
  toPrecision       numberProtoFuncToPrecision      DontEnum|Function 1
@end
*/

STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NumberPrototype);

NumberPrototype::NumberPrototype(VM& vm, Structure* structure)
    : NumberObject(vm, structure)
{
}

void NumberPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
{
    Base::finishCreation(vm);
    setInternalValue(vm, jsNumber(0));
    putDirectWithoutTransition(vm, vm.propertyNames->toString, globalObject->numberProtoToStringFunction(), static_cast<unsigned>(PropertyAttribute::DontEnum));
    ASSERT(inherits(vm, info()));
    globalObject->installNumberPrototypeWatchpoint(this);
}

// ------------------------------ Functions ---------------------------

static ALWAYS_INLINE bool toThisNumber(VM& vm, JSValue thisValue, double& x)
{
    if (thisValue.isInt32()) {
        x = thisValue.asInt32();
        return true;
    }

    if (thisValue.isDouble()) {
        x = thisValue.asDouble();
        return true;
    }

    if (auto* numberObject = jsDynamicCast<NumberObject*>(vm, thisValue)) {
        x = numberObject->internalValue().asNumber();
        return true;
    }

    return false;
}

static ALWAYS_INLINE EncodedJSValue throwVMToThisNumberError(JSGlobalObject* globalObject, ThrowScope& scope, JSValue thisValue)
{
    auto typeString = asString(jsTypeStringForValue(globalObject->vm(), globalObject, thisValue))->value(globalObject);
    scope.assertNoException();
    return throwVMTypeError(globalObject, scope, WTF::makeString("thisNumberValue called on incompatible ", typeString));
}

// The largest finite floating point number is 1.mantissa * 2^(0x7fe-0x3ff).
// Since 2^N in binary is a one bit followed by N zero bits. 1 * 2^3ff requires
// at most 1024 characters to the left of a decimal point, in base 2 (1025 if
// we include a minus sign). For the fraction, a value with an exponent of 0
// has up to 52 bits to the right of the decimal point. Each decrement of the
// exponent down to a minimum of -0x3fe adds an additional digit to the length
// of the fraction. As such the maximum fraction size is 1075 (1076 including
// a point). We pick a buffer size such that can simply place the point in the
// center of the buffer, and are guaranteed to have enough space in each direction
// fo any number of digits an IEEE number may require to represent.
typedef char RadixBuffer[2180];

static inline char* int52ToStringWithRadix(char* startOfResultString, int64_t int52Value, unsigned radix)
{
    bool negative = false;
    uint64_t positiveNumber = int52Value;
    if (int52Value < 0) {
        negative = true;
        positiveNumber = -int52Value;
    }

    do {
        uint64_t index = positiveNumber % radix;
        ASSERT(index < sizeof(radixDigits));
        *--startOfResultString = radixDigits[index];
        positiveNumber /= radix;
    } while (positiveNumber);
    if (negative)
        *--startOfResultString = '-';

    return startOfResultString;
}

static char* toStringWithRadixInternal(RadixBuffer& buffer, double originalNumber, unsigned radix)
{
    ASSERT(std::isfinite(originalNumber));
    ASSERT(radix >= 2 && radix <= 36);

    // Position the decimal point at the center of the string, set
    // the startOfResultString pointer to point at the decimal point.
    char* decimalPoint = buffer + sizeof(buffer) / 2;
    char* startOfResultString = decimalPoint;

    // Extract the sign.
    bool isNegative = originalNumber < 0;
    double number = originalNumber;
    if (std::signbit(originalNumber))
        number = -originalNumber;
    double integerPart = floor(number);

    // Check if the value has a fractional part to convert.
    double fractionPart = number - integerPart;
    if (!fractionPart) {
        *decimalPoint = '\0';
        // We do not need to care the negative zero (-0) since it is also converted to "0" in all the radix.
        if (integerPart < (static_cast<int64_t>(1) << (JSValue::numberOfInt52Bits - 1)))
            return int52ToStringWithRadix(startOfResultString, static_cast<int64_t>(originalNumber), radix);
    } else {
        // We use this to test for odd values in odd radix bases.
        // Where the base is even, (e.g. 10), to determine whether a value is even we need only
        // consider the least significant digit. For example, 124 in base 10 is even, because '4'
        // is even. if the radix is odd, then the radix raised to an integer power is also odd.
        // E.g. in base 5, 124 represents (1 * 125 + 2 * 25 + 4 * 5). Since each digit in the value
        // is multiplied by an odd number, the result is even if the sum of all digits is even.
        //
        // For the integer portion of the result, we only need test whether the integer value is
        // even or odd. For each digit of the fraction added, we should invert our idea of whether
        // the number is odd if the new digit is odd.
        //
        // Also initialize digit to this value; for even radix values we only need track whether
        // the last individual digit was odd.
        bool integerPartIsOdd = integerPart <= static_cast<double>(0x1FFFFFFFFFFFFFull) && static_cast<int64_t>(integerPart) & 1;
        ASSERT(integerPartIsOdd == static_cast<bool>(fmod(integerPart, 2)));
        bool isOddInOddRadix = integerPartIsOdd;
        uint32_t digit = integerPartIsOdd;

        // Write the decimal point now.
        *decimalPoint = '.';

        // Higher precision representation of the fractional part.
        Uint16WithFraction fraction(fractionPart);

        bool needsRoundingUp = false;
        char* endOfResultString = decimalPoint + 1;

        // Calculate the delta from the current number to the next & previous possible IEEE numbers.
        double nextNumber = nextafter(number, std::numeric_limits<double>::infinity());
        double lastNumber = nextafter(number, -std::numeric_limits<double>::infinity());
        ASSERT(std::isfinite(nextNumber) && !std::signbit(nextNumber));
        ASSERT(std::isfinite(lastNumber) && !std::signbit(lastNumber));
        double deltaNextDouble = nextNumber - number;
        double deltaLastDouble = number - lastNumber;
        ASSERT(std::isfinite(deltaNextDouble) && !std::signbit(deltaNextDouble));
        ASSERT(std::isfinite(deltaLastDouble) && !std::signbit(deltaLastDouble));

        // We track the delta from the current value to the next, to track how many digits of the
        // fraction we need to write. For example, if the value we are converting is precisely
        // 1.2345, so far we have written the digits "1.23" to a string leaving a remainder of
        // 0.45, and we want to determine whether we can round off, or whether we need to keep
        // appending digits ('4'). We can stop adding digits provided that then next possible
        // lower IEEE value is further from 1.23 than the remainder we'd be rounding off (0.45),
        // which is to say, less than 1.2255. Put another way, the delta between the prior
        // possible value and this number must be more than 2x the remainder we'd be rounding off
        // (or more simply half the delta between numbers must be greater than the remainder).
        //
        // Similarly we need track the delta to the next possible value, to dertermine whether
        // to round up. In almost all cases (other than at exponent boundaries) the deltas to
        // prior and subsequent values are identical, so we don't need track then separately.
        if (deltaNextDouble != deltaLastDouble) {
            // Since the deltas are different track them separately. Pre-multiply by 0.5.
            Uint16WithFraction halfDeltaNext(deltaNextDouble, 1);
            Uint16WithFraction halfDeltaLast(deltaLastDouble, 1);

            while (true) {
                // examine the remainder to determine whether we should be considering rounding
                // up or down. If remainder is precisely 0.5 rounding is to even.
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    // Check for rounding up; are we closer to the value we'd round off to than
                    // the next IEEE value would be?
                    if (fraction.sumGreaterThanOne(halfDeltaNext)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else {
                    // Check for rounding down; are we closer to the value we'd round off to than
                    // the prior IEEE value would be?
                    if (fraction < halfDeltaLast)
                        break;
                }

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                // Write a digit to the string.
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                *endOfResultString++ = radixDigits[digit];
                // Keep track whether the portion written is currently even, if the radix is odd.
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;

                // Shift the fractions by radix.
                halfDeltaNext *= radix;
                halfDeltaLast *= radix;
            }
        } else {
            // This code is identical to that above, except since deltaNextDouble != deltaLastDouble
            // we don't need to track these two values separately.
            Uint16WithFraction halfDelta(deltaNextDouble, 1);

            while (true) {
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    if (fraction.sumGreaterThanOne(halfDelta)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else if (fraction < halfDelta)
                    break;

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;
                *endOfResultString++ = radixDigits[digit];

                halfDelta *= radix;
            }
        }

        // Check if the fraction needs rounding off (flag set in the loop writing digits, above).
        if (needsRoundingUp) {
            // Whilst the last digit is the maximum in the current radix, remove it.
            // e.g. rounding up the last digit in "12.3999" is the same as rounding up the
            // last digit in "12.3" - both round up to "12.4".
            while (endOfResultString[-1] == radixDigits[radix - 1])
                --endOfResultString;

            // Radix digits are sequential in ascii/unicode, except for '9' and 'a'.
            // E.g. the first 'if' case handles rounding 67.89 to 67.8a in base 16.
            // The 'else if' case handles rounding of all other digits.
            if (endOfResultString[-1] == '9')
                endOfResultString[-1] = 'a';
            else if (endOfResultString[-1] != '.')
                ++endOfResultString[-1];
            else {
                // One other possibility - there may be no digits to round up in the fraction
                // (or all may be been rounded off already), in which case we may need to
                // round into the integer portion of the number. Remove the decimal point.
                --endOfResultString;
                // In order to get here there must have been a non-zero fraction, in which case
                // there must be at least one bit of the value's mantissa not in use in the
                // integer part of the number. As such, adding to the integer part should not
                // be able to lose precision.
                ASSERT((integerPart + 1) - integerPart == 1);
                ++integerPart;
            }
        } else {
            // We only need to check for trailing zeros if the value does not get rounded up.
            while (endOfResultString[-1] == '0')
                --endOfResultString;
        }

        *endOfResultString = '\0';
        ASSERT(endOfResultString < buffer + sizeof(buffer));
    }

    BigInteger units(integerPart);

    // Always loop at least once, to emit at least '0'.
    do {
        ASSERT(buffer < startOfResultString);

        // Read a single digit and write it to the front of the string.
        // Divide by radix to remove one digit from the value.
        uint32_t digit = units.divide(radix);
        *--startOfResultString = radixDigits[digit];
    } while (!!units);

    // If the number is negative, prepend '-'.
    if (isNegative)
        *--startOfResultString = '-';
    ASSERT(buffer <= startOfResultString);

    return startOfResultString;
}

static String toStringWithRadixInternal(int32_t number, unsigned radix)
{
    LChar buf[1 + 32]; // Worst case is radix == 2, which gives us 32 digits + sign.
    LChar* end = std::end(buf);
    LChar* p = end;

    bool negative = false;
    uint32_t positiveNumber = number;
    if (number < 0) {
        negative = true;
        positiveNumber = static_cast<uint32_t>(-static_cast<int64_t>(number));
    }

    // Always loop at least once, to emit at least '0'.
    do {
        uint32_t index = positiveNumber % radix;
        ASSERT(index < sizeof(radixDigits));
        *--p = static_cast<LChar>(radixDigits[index]);
        positiveNumber /= radix;
    } while (positiveNumber);

    if (negative)
        *--p = '-';

    return String(p, static_cast<unsigned>(end - p));
}

String toStringWithRadix(double doubleValue, int32_t radix)
{
    ASSERT(2 <= radix && radix <= 36);

    int32_t integerValue = static_cast<int32_t>(doubleValue);
    if (integerValue == doubleValue)
        return toStringWithRadixInternal(integerValue, radix);

    if (radix == 10 || !std::isfinite(doubleValue))
        return String::number(doubleValue);

    RadixBuffer buffer;
    return toStringWithRadixInternal(buffer, doubleValue, radix);
}

// toExponential converts a number to a string, always formatting as an exponential.
// This method takes an optional argument specifying a number of *decimal places*
// to round the significand to (or, put another way, this method optionally rounds
// to argument-plus-one significant figures).
EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double x;
    if (!toThisNumber(vm, callFrame->thisValue(), x))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());

    JSValue arg = callFrame->argument(0);
    // Perform ToInteger on the argument before remaining steps.
    int decimalPlaces = static_cast<int>(arg.toInteger(globalObject));
    RETURN_IF_EXCEPTION(scope, { });

    // Handle NaN and Infinity.
    if (!std::isfinite(x))
        return JSValue::encode(jsNontrivialString(vm, String::number(x)));

    if (decimalPlaces < 0 || decimalPlaces > 100)
        return throwVMRangeError(globalObject, scope, "toExponential() argument must be between 0 and 100"_s);

    // Round if the argument is not undefined, always format as exponential.
    NumberToStringBuffer buffer;
    DoubleConversionStringBuilder builder { &buffer[0], sizeof(buffer) };
    const DoubleToStringConverter& converter = DoubleToStringConverter::EcmaScriptConverter();
    builder.Reset();
    if (arg.isUndefined())
        converter.ToExponential(x, -1, &builder);
    else
        converter.ToExponential(x, decimalPlaces, &builder);
    return JSValue::encode(jsString(vm, builder.Finalize()));
}

// toFixed converts a number to a string, always formatting as an a decimal fraction.
// This method takes an argument specifying a number of decimal places to round the
// significand to. However when converting large values (1e+21 and above) this
// method will instead fallback to calling ToString. 
EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double x;
    if (!toThisNumber(vm, callFrame->thisValue(), x))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());

    int decimalPlaces = static_cast<int>(callFrame->argument(0).toInteger(globalObject));
    RETURN_IF_EXCEPTION(scope, { });
    if (decimalPlaces < 0 || decimalPlaces > 100)
        return throwVMRangeError(globalObject, scope, "toFixed() argument must be between 0 and 100"_s);

    // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
    // This also covers Ininity, and structure the check so that NaN
    // values are also handled by numberToString
    if (!(fabs(x) < 1e+21))
        return JSValue::encode(jsString(vm, String::number(x)));

    // The check above will return false for NaN or Infinity, these will be
    // handled by numberToString.
    ASSERT(std::isfinite(x));

    return JSValue::encode(jsString(vm, String::numberToStringFixedWidth(x, decimalPlaces)));
}

// toPrecision converts a number to a string, taking an argument specifying a
// number of significant figures to round the significand to. For positive
// exponent, all values that can be represented using a decimal fraction will
// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
// For negative exponents values >= 1e-6 are formated as decimal fractions,
// with smaller values converted to exponential representation.
EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double x;
    if (!toThisNumber(vm, callFrame->thisValue(), x))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());

    JSValue arg = callFrame->argument(0);
    // To precision called with no argument is treated as ToString.
    if (arg.isUndefined())
        return JSValue::encode(jsString(vm, String::number(x)));

    // Perform ToInteger on the argument before remaining steps.
    int significantFigures = static_cast<int>(arg.toInteger(globalObject));
    RETURN_IF_EXCEPTION(scope, { });

    // Handle NaN and Infinity.
    if (!std::isfinite(x))
        return JSValue::encode(jsNontrivialString(vm, String::number(x)));

    if (significantFigures < 1 || significantFigures > 100)
        return throwVMRangeError(globalObject, scope, "toPrecision() argument must be between 1 and 100"_s);

    return JSValue::encode(jsString(vm, String::numberToStringFixedPrecision(x, significantFigures, KeepTrailingZeros)));
}

static ALWAYS_INLINE JSString* int32ToStringInternal(VM& vm, int32_t value, int32_t radix)
{
    ASSERT(!(radix < 2 || radix > 36));
    // A negative value casted to unsigned would be bigger than 36 (the max radix).
    if (static_cast<unsigned>(value) < static_cast<unsigned>(radix)) {
        ASSERT(value <= 36);
        ASSERT(value >= 0);
        return vm.smallStrings.singleCharacterString(radixDigits[value]);
    }

    if (radix == 10)
        return jsNontrivialString(vm, vm.numericStrings.add(value));

    return jsNontrivialString(vm, toStringWithRadixInternal(value, radix));

}

static ALWAYS_INLINE JSString* numberToStringInternal(VM& vm, double doubleValue, int32_t radix)
{
    ASSERT(!(radix < 2 || radix > 36));

    int32_t integerValue = static_cast<int32_t>(doubleValue);
    if (integerValue == doubleValue)
        return int32ToStringInternal(vm, integerValue, radix);

    if (radix == 10)
        return jsString(vm, vm.numericStrings.add(doubleValue));

    if (!std::isfinite(doubleValue))
        return jsNontrivialString(vm, String::number(doubleValue));

    RadixBuffer buffer;
    return jsString(vm, toStringWithRadixInternal(buffer, doubleValue, radix));
}

JSString* int32ToString(VM& vm, int32_t value, int32_t radix)
{
    return int32ToStringInternal(vm, value, radix);
}

JSString* int52ToString(VM& vm, int64_t value, int32_t radix)
{
    ASSERT(!(radix < 2 || radix > 36));
    // A negative value casted to unsigned would be bigger than 36 (the max radix).
    if (static_cast<uint64_t>(value) < static_cast<uint64_t>(radix)) {
        ASSERT(value <= 36);
        ASSERT(value >= 0);
        return vm.smallStrings.singleCharacterString(radixDigits[value]);
    }

    if (radix == 10)
        return jsNontrivialString(vm, vm.numericStrings.add(static_cast<double>(value)));

    // Position the decimal point at the center of the string, set
    // the startOfResultString pointer to point at the decimal point.
    RadixBuffer buffer;
    char* decimalPoint = buffer + sizeof(buffer) / 2;
    char* startOfResultString = decimalPoint;
    *decimalPoint = '\0';

    return jsNontrivialString(vm, int52ToStringWithRadix(startOfResultString, value, radix));
}

JSString* numberToString(VM& vm, double doubleValue, int32_t radix)
{
    return numberToStringInternal(vm, doubleValue, radix);
}

EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double doubleValue;
    if (!toThisNumber(vm, callFrame->thisValue(), doubleValue))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());

    auto radix = extractToStringRadixArgument(globalObject, callFrame->argument(0), scope);
    RETURN_IF_EXCEPTION(scope, encodedJSValue());

    return JSValue::encode(numberToStringInternal(vm, doubleValue, radix));
}

EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double x;
    if (!toThisNumber(vm, callFrame->thisValue(), x))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());

#if ENABLE(INTL)
    IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, globalObject->numberFormatStructure());
    numberFormat->initializeNumberFormat(globalObject, callFrame->argument(0), callFrame->argument(1));
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatNumber(globalObject, x)));
#else
    return JSValue::encode(jsNumber(x).toString(globalObject));
#endif
}

EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    double x;
    JSValue thisValue = callFrame->thisValue();
    if (!toThisNumber(vm, thisValue, x))
        return throwVMToThisNumberError(globalObject, scope, callFrame->thisValue());
    return JSValue::encode(jsNumber(x));
}

int32_t extractToStringRadixArgument(JSGlobalObject* globalObject, JSValue radixValue, ThrowScope& throwScope)
{
    if (radixValue.isUndefined())
        return 10;

    if (radixValue.isInt32()) {
        int32_t radix = radixValue.asInt32();
        if (radix >= 2 && radix <= 36)
            return radix;
    } else {
        double radixDouble = radixValue.toInteger(globalObject);
        RETURN_IF_EXCEPTION(throwScope, 0);
        if (radixDouble >= 2 && radixDouble <= 36)
            return static_cast<int32_t>(radixDouble);   
    }

    throwRangeError(globalObject, throwScope, "toString() radix argument must be between 2 and 36"_s);
    return 0;
}

} // namespace JSC
