1// Copyright 2019 the V8 project authors. All rights reserved. Use of this 2// source code is governed by a BSD-style license that can be found in the 3// LICENSE file. 4 5namespace runtime { 6 extern transitioning runtime 7 DoubleToStringWithRadix(implicit context: Context)(Number, Number): String; 8} // namespace runtime 9 10namespace number { 11 extern macro NaNStringConstant(): String; 12 extern macro ZeroStringConstant(): String; 13 extern macro InfinityStringConstant(): String; 14 extern macro MinusInfinityStringConstant(): String; 15 16 const kAsciiZero: constexpr int32 = 48; // '0' (ascii) 17 const kAsciiLowerCaseA: constexpr int32 = 97; // 'a' (ascii) 18 19 transitioning macro ThisNumberValue(implicit context: Context)( 20 receiver: JSAny, method: constexpr string): Number { 21 return UnsafeCast<Number>( 22 ToThisValue(receiver, PrimitiveType::kNumber, method)); 23 } 24 25 // https://tc39.github.io/ecma262/#sec-number.prototype.tostring 26 transitioning javascript builtin NumberPrototypeToString( 27 js-implicit context: NativeContext, 28 receiver: JSAny)(...arguments): String { 29 // 1. Let x be ? thisNumberValue(this value). 30 const x = ThisNumberValue(receiver, 'Number.prototype.toString'); 31 32 // 2. If radix is not present, let radixNumber be 10. 33 // 3. Else if radix is undefined, let radixNumber be 10. 34 // 4. Else, let radixNumber be ? ToInteger(radix). 35 const radix: JSAny = arguments[0]; 36 const radixNumber: Number = 37 radix == Undefined ? 10 : ToInteger_Inline(radix); 38 39 // 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception. 40 if (radixNumber < 2 || radixNumber > 36) { 41 ThrowRangeError(MessageTemplate::kToRadixFormatRange); 42 } 43 44 // 6. If radixNumber = 10, return ! ToString(x). 45 if (radixNumber == 10) { 46 return NumberToString(x); 47 } 48 49 // 7. Return the String representation of this Number 50 // value using the radix specified by radixNumber. 51 52 // Fast case where the result is a one character string. 53 if (TaggedIsPositiveSmi(x) && x < radixNumber) { 54 let charCode = Convert<int32>(UnsafeCast<Smi>(x)); 55 if (charCode < 10) { 56 charCode += kAsciiZero; 57 } else { 58 charCode = charCode - 10 + kAsciiLowerCaseA; 59 } 60 return StringFromSingleCharCode(charCode); 61 } 62 63 if (x == -0) { 64 return ZeroStringConstant(); 65 } else if (NumberIsNaN(x)) { 66 return NaNStringConstant(); 67 } else if (x == V8_INFINITY) { 68 return InfinityStringConstant(); 69 } else if (x == MINUS_V8_INFINITY) { 70 return MinusInfinityStringConstant(); 71 } 72 73 return runtime::DoubleToStringWithRadix(x, radixNumber); 74 } 75} 76