blob: 7afeeb06271643b81b22d4a578b7d5bae869bcb7 [file] [log] [blame]
// 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.
namespace array {
extern builtin ArrayUnshift(Context, JSFunction, JSAny, int32): JSAny;
transitioning macro GenericArrayUnshift(
context: Context, receiver: JSAny, arguments: Arguments): Number {
// 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(object);
// 3. Let argCount be the number of actual arguments.
const argCount: Smi = Convert<Smi>(arguments.length);
// 4. If argCount > 0, then.
if (argCount > 0) {
// a. If len + argCount > 2**53 - 1, throw a TypeError exception.
if (length + argCount > kMaxSafeInteger) {
ThrowTypeError(MessageTemplate::kInvalidArrayLength);
}
// b. Let k be len.
let k: Number = length;
// c. Repeat, while k > 0.
while (k > 0) {
// i. Let from be ! ToString(k - 1).
const from: Number = k - 1;
// ii. Let to be ! ToString(k + argCount - 1).
const to: Number = k + argCount - 1;
// iii. Let fromPresent be ? HasProperty(O, from).
const fromPresent: Boolean = HasProperty(object, from);
// iv. If fromPresent is true, then
if (fromPresent == True) {
// 1. Let fromValue be ? Get(O, from).
const fromValue: JSAny = GetProperty(object, from);
// 2. Perform ? Set(O, to, fromValue, true).
SetProperty(object, to, fromValue);
} else {
// 1. Perform ? DeletePropertyOrThrow(O, to).
DeleteProperty(object, to, LanguageMode::kStrict);
}
// vi. Decrease k by 1.
--k;
}
// d. Let j be 0.
let j: Smi = 0;
// e. Let items be a List whose elements are, in left to right order,
// the arguments that were passed to this function invocation.
// f. Repeat, while items is not empty
while (j < argCount) {
// ii .Perform ? Set(O, ! ToString(j), E, true).
SetProperty(object, j, arguments[Convert<intptr>(j)]);
// iii. Increase j by 1.
++j;
}
}
// 5. Perform ? Set(O, "length", len + argCount, true).
const newLength: Number = length + argCount;
SetProperty(object, kLengthString, newLength);
// 6. Return length + argCount.
return newLength;
}
// https://tc39.github.io/ecma262/#sec-array.prototype.unshift
transitioning javascript builtin ArrayPrototypeUnshift(
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
try {
const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
array::EnsureWriteableFastElements(array);
const map: Map = array.map;
if (!IsExtensibleMap(map)) goto Slow;
EnsureArrayLengthWritable(map) otherwise Slow;
tail ArrayUnshift(
context, LoadTargetFromFrame(), Undefined,
Convert<int32>(arguments.length));
} label Slow {
return GenericArrayUnshift(context, receiver, arguments);
}
}
}