1// Copyright 2019 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5namespace string { 6const kBuiltinName: constexpr string = 'String.prototype.repeat'; 7 8builtin StringRepeat(implicit context: Context)( 9 string: String, count: Smi): String { 10 dcheck(count >= 0); 11 dcheck(string != kEmptyString); 12 13 let result: String = kEmptyString; 14 let powerOfTwoRepeats: String = string; 15 let n: intptr = Convert<intptr>(count); 16 17 while (true) { 18 if ((n & 1) == 1) result = result + powerOfTwoRepeats; 19 20 n = n >> 1; 21 if (n == 0) break; 22 23 powerOfTwoRepeats = powerOfTwoRepeats + powerOfTwoRepeats; 24 } 25 26 return result; 27} 28 29// https://tc39.github.io/ecma262/#sec-string.prototype.repeat 30transitioning javascript builtin StringPrototypeRepeat( 31 js-implicit context: NativeContext, receiver: JSAny)(count: JSAny): String { 32 // 1. Let O be ? RequireObjectCoercible(this value). 33 // 2. Let S be ? ToString(O). 34 const s: String = ToThisString(receiver, kBuiltinName); 35 36 try { 37 // 3. Let n be ? ToInteger(count). 38 typeswitch (ToInteger_Inline(count)) { 39 case (n: Smi): { 40 // 4. If n < 0, throw a RangeError exception. 41 if (n < 0) goto InvalidCount; 42 43 // 6. If n is 0, return the empty String. 44 if (n == 0 || s.length_uint32 == 0) goto EmptyString; 45 46 if (n > kStringMaxLength) goto InvalidStringLength; 47 48 // 7. Return the String value that is made from n copies of S appended 49 // together. 50 return StringRepeat(s, n); 51 } 52 case (heapNum: HeapNumber): deferred { 53 dcheck(IsNumberNormalized(heapNum)); 54 const n = LoadHeapNumberValue(heapNum); 55 56 // 4. If n < 0, throw a RangeError exception. 57 // 5. If n is +∞, throw a RangeError exception. 58 if (n == V8_INFINITY || n < 0) goto InvalidCount; 59 60 // 6. If n is 0, return the empty String. 61 if (s.length_uint32 == 0) goto EmptyString; 62 63 goto InvalidStringLength; 64 } 65 } 66 } label EmptyString { 67 return kEmptyString; 68 } label InvalidCount deferred { 69 ThrowRangeError(MessageTemplate::kInvalidCountValue, count); 70 } label InvalidStringLength deferred { 71 ThrowInvalidStringLength(context); 72 } 73} 74} 75