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 { 6extern builtin ArrayUnshift(Context, JSFunction, JSAny, int32): JSAny; 7 8transitioning macro GenericArrayUnshift( 9 context: Context, receiver: JSAny, arguments: Arguments): Number { 10 // 1. Let O be ? ToObject(this value). 11 const object: JSReceiver = ToObject_Inline(context, receiver); 12 13 // 2. Let len be ? ToLength(? Get(O, "length")). 14 const length: Number = GetLengthProperty(object); 15 16 // 3. Let argCount be the number of actual arguments. 17 const argCount: Smi = Convert<Smi>(arguments.length); 18 19 // 4. If argCount > 0, then. 20 if (argCount > 0) { 21 // a. If len + argCount > 2**53 - 1, throw a TypeError exception. 22 if (length + argCount > kMaxSafeInteger) { 23 ThrowTypeError(MessageTemplate::kInvalidArrayLength); 24 } 25 26 // b. Let k be len. 27 let k: Number = length; 28 29 // c. Repeat, while k > 0. 30 while (k > 0) { 31 // i. Let from be ! ToString(k - 1). 32 const from: Number = k - 1; 33 34 // ii. Let to be ! ToString(k + argCount - 1). 35 const to: Number = k + argCount - 1; 36 37 // iii. Let fromPresent be ? HasProperty(O, from). 38 const fromPresent: Boolean = HasProperty(object, from); 39 40 // iv. If fromPresent is true, then 41 if (fromPresent == True) { 42 // 1. Let fromValue be ? Get(O, from). 43 const fromValue: JSAny = GetProperty(object, from); 44 45 // 2. Perform ? Set(O, to, fromValue, true). 46 SetProperty(object, to, fromValue); 47 } else { 48 // 1. Perform ? DeletePropertyOrThrow(O, to). 49 DeleteProperty(object, to, LanguageMode::kStrict); 50 } 51 52 // vi. Decrease k by 1. 53 --k; 54 } 55 56 // d. Let j be 0. 57 let j: Smi = 0; 58 59 // e. Let items be a List whose elements are, in left to right order, 60 // the arguments that were passed to this function invocation. 61 // f. Repeat, while items is not empty 62 while (j < argCount) { 63 // ii .Perform ? Set(O, ! ToString(j), E, true). 64 SetProperty(object, j, arguments[Convert<intptr>(j)]); 65 66 // iii. Increase j by 1. 67 ++j; 68 } 69 } 70 71 // 5. Perform ? Set(O, "length", len + argCount, true). 72 const newLength: Number = length + argCount; 73 SetProperty(object, kLengthString, newLength); 74 75 // 6. Return length + argCount. 76 return newLength; 77} 78 79// https://tc39.github.io/ecma262/#sec-array.prototype.unshift 80transitioning javascript builtin ArrayPrototypeUnshift( 81 js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { 82 try { 83 const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow; 84 array::EnsureWriteableFastElements(array); 85 86 const map: Map = array.map; 87 if (!IsExtensibleMap(map)) goto Slow; 88 EnsureArrayLengthWritable(map) otherwise Slow; 89 90 tail ArrayUnshift( 91 context, LoadTargetFromFrame(), Undefined, 92 Convert<int32>(arguments.actual_count)); 93 } label Slow { 94 return GenericArrayUnshift(context, receiver, arguments); 95 } 96} 97} 98