diff options
Diffstat (limited to 'deps/v8/src/builtins/array-copywithin.tq')
-rw-r--r-- | deps/v8/src/builtins/array-copywithin.tq | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/deps/v8/src/builtins/array-copywithin.tq b/deps/v8/src/builtins/array-copywithin.tq new file mode 100644 index 00000000000..8406123b202 --- /dev/null +++ b/deps/v8/src/builtins/array-copywithin.tq @@ -0,0 +1,93 @@ +// 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<to and to<from+count, then. + let direction: Number = 1; + + if (from < to && to < (from + count)) { + // a. Let direction be -1. + direction = -1; + + // b. Let from be from + count - 1. + from = from + count - 1; + + // c. Let to be to + count - 1. + to = to + count - 1; + } + + // 12. Repeat, while count > 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; + } +} |