1// Copyright 2018 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 array { 6macro ConvertToRelativeIndex(index: Number, length: Number): Number { 7 return index < 0 ? Max(index + length, 0) : Min(index, length); 8} 9 10// https://tc39.github.io/ecma262/#sec-array.prototype.copyWithin 11transitioning javascript builtin ArrayPrototypeCopyWithin( 12 js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { 13 // 1. Let O be ? ToObject(this value). 14 const object: JSReceiver = ToObject_Inline(context, receiver); 15 16 // 2. Let len be ? ToLength(? Get(O, "length")). 17 const length: Number = GetLengthProperty(object); 18 19 // 3. Let relativeTarget be ? ToInteger(target). 20 const relativeTarget: Number = ToInteger_Inline(arguments[0]); 21 22 // 4. If relativeTarget < 0, let to be max((len + relativeTarget), 0); 23 // else let to be min(relativeTarget, len). 24 let to: Number = ConvertToRelativeIndex(relativeTarget, length); 25 26 // 5. Let relativeStart be ? ToInteger(start). 27 const relativeStart: Number = ToInteger_Inline(arguments[1]); 28 29 // 6. If relativeStart < 0, let from be max((len + relativeStart), 0); 30 // else let from be min(relativeStart, len). 31 let from: Number = ConvertToRelativeIndex(relativeStart, length); 32 33 // 7. If end is undefined, let relativeEnd be len; 34 // else let relativeEnd be ? ToInteger(end). 35 let relativeEnd: Number = length; 36 if (arguments[2] != Undefined) { 37 relativeEnd = ToInteger_Inline(arguments[2]); 38 } 39 40 // 8. If relativeEnd < 0, let final be max((len + relativeEnd), 0); 41 // else let final be min(relativeEnd, len). 42 const final: Number = ConvertToRelativeIndex(relativeEnd, length); 43 44 // 9. Let count be min(final-from, len-to). 45 let count: Number = Min(final - from, length - to); 46 47 // 10. If from<to and to<from+count, then. 48 let direction: Number = 1; 49 50 if (from < to && to < (from + count)) { 51 // a. Let direction be -1. 52 direction = -1; 53 54 // b. Let from be from + count - 1. 55 from = from + count - 1; 56 57 // c. Let to be to + count - 1. 58 to = to + count - 1; 59 } 60 61 // 12. Repeat, while count > 0. 62 while (count > 0) { 63 // a. Let fromKey be ! ToString(from). 64 // b. Let toKey be ! ToString(to). 65 // c. Let fromPresent be ? HasProperty(O, fromKey). 66 const fromPresent: Boolean = HasProperty(object, from); 67 68 // d. If fromPresent is true, then. 69 if (fromPresent == True) { 70 // i. Let fromVal be ? Get(O, fromKey). 71 const fromVal: JSAny = GetProperty(object, from); 72 73 // ii. Perform ? Set(O, toKey, fromVal, true). 74 SetProperty(object, to, fromVal); 75 } else { 76 // i. Perform ? DeletePropertyOrThrow(O, toKey). 77 DeleteProperty(object, to, LanguageMode::kStrict); 78 } 79 80 // f. Let from be from + direction. 81 from = from + direction; 82 83 // g. Let to be to + direction. 84 to = to + direction; 85 86 // h. Let count be count - 1. 87 --count; 88 } 89 90 // 13. Return O. 91 return object; 92} 93} 94