// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. module array { macro ConvertToRelativeIndex(index: Number, length: Number): Number { return index < 0 ? max(index + length, 0) : min(index, length); } // https://tc39.github.io/ecma262/#sec-array.prototype.copyWithin javascript builtin ArrayPrototypeCopyWithin( context: Context, receiver: Object, ...arguments): Object { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); // 2. Let len be ? ToLength(? Get(O, "length")). const length: Number = GetLengthProperty(context, object); // 3. Let relativeTarget be ? ToInteger(target). const relative_target: Number = ToInteger_Inline(context, arguments[0]); // 4. If relativeTarget < 0, let to be max((len + relativeTarget), 0); // else let to be min(relativeTarget, len). let to: Number = ConvertToRelativeIndex(relative_target, length); // 5. Let relativeStart be ? ToInteger(start). const relative_start: Number = ToInteger_Inline(context, arguments[1]); // 6. If relativeStart < 0, let from be max((len + relativeStart), 0); // else let from be min(relativeStart, len). let from: Number = ConvertToRelativeIndex(relative_start, length); // 7. If end is undefined, let relativeEnd be len; // else let relativeEnd be ? ToInteger(end). let relative_end: Number = length; if (arguments[2] != Undefined) { relative_end = ToInteger_Inline(context, arguments[2]); } // 8. If relativeEnd < 0, let final be max((len + relativeEnd), 0); // else let final be min(relativeEnd, len). const final: Number = ConvertToRelativeIndex(relative_end, length); // 9. Let count be min(final-from, len-to). let count: Number = min(final - from, length - to); // 10. If from 0. while (count > 0) { // a. Let fromKey be ! ToString(from). // b. Let toKey be ! ToString(to). // c. Let fromPresent be ? HasProperty(O, fromKey). const from_present: Boolean = HasProperty(context, object, from); // d. If fromPresent is true, then. if (from_present == True) { // i. Let fromVal be ? Get(O, fromKey). const from_val: Object = GetProperty(context, object, from); // ii. Perform ? Set(O, toKey, fromVal, true). SetProperty(context, object, to, from_val); } else { // i. Perform ? DeletePropertyOrThrow(O, toKey). DeleteProperty(context, object, to, kStrict); } // f. Let from be from + direction. from = from + direction; // g. Let to be to + direction. to = to + direction; // h. Let count be count - 1. --count; } // 13. Return O. return object; } }