11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_cinamespace array { 61cb0ef41Sopenharmony_ciextern builtin ArrayShift(Context, JSFunction, JSAny, int32): JSAny; 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cimacro TryFastArrayShift(implicit context: Context)(receiver: JSAny): JSAny 91cb0ef41Sopenharmony_ci labels Slow, Runtime { 101cb0ef41Sopenharmony_ci const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow; 111cb0ef41Sopenharmony_ci let witness = NewFastJSArrayWitness(array); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci witness.EnsureArrayPushable() otherwise Slow; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci if (array.length == 0) { 161cb0ef41Sopenharmony_ci return Undefined; 171cb0ef41Sopenharmony_ci } 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci const newLength = array.length - 1; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci // Check that we're not supposed to right-trim the backing store, as 221cb0ef41Sopenharmony_ci // implemented in elements.cc:ElementsAccessorBase::SetLengthImpl. 231cb0ef41Sopenharmony_ci if ((newLength + newLength + kMinAddedElementsCapacity) < 241cb0ef41Sopenharmony_ci array.elements.length) { 251cb0ef41Sopenharmony_ci goto Runtime; 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci // Check that we're not supposed to left-trim the backing store, as 291cb0ef41Sopenharmony_ci // implemented in elements.cc:FastElementsAccessor::MoveElements. 301cb0ef41Sopenharmony_ci if (newLength > kMaxCopyElements) goto Runtime; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci const result = witness.LoadElementOrUndefined(0); 331cb0ef41Sopenharmony_ci witness.ChangeLength(newLength); 341cb0ef41Sopenharmony_ci witness.MoveElements(0, 1, Convert<intptr>(newLength)); 351cb0ef41Sopenharmony_ci witness.StoreHole(newLength); 361cb0ef41Sopenharmony_ci return result; 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_citransitioning macro GenericArrayShift(implicit context: Context)( 401cb0ef41Sopenharmony_ci receiver: JSAny): JSAny { 411cb0ef41Sopenharmony_ci // 1. Let O be ? ToObject(this value). 421cb0ef41Sopenharmony_ci const object: JSReceiver = ToObject_Inline(context, receiver); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci // 2. Let len be ? ToLength(? Get(O, "length")). 451cb0ef41Sopenharmony_ci const length: Number = GetLengthProperty(object); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // 3. If len is zero, then 481cb0ef41Sopenharmony_ci if (length == 0) { 491cb0ef41Sopenharmony_ci // a. Perform ? Set(O, "length", 0, true). 501cb0ef41Sopenharmony_ci SetProperty(object, kLengthString, Convert<Smi>(0)); 511cb0ef41Sopenharmony_ci // b. Return undefined. 521cb0ef41Sopenharmony_ci return Undefined; 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci // 4. Let first be ? Get(O, "0"). 561cb0ef41Sopenharmony_ci const first = GetProperty(object, Convert<Smi>(0)); 571cb0ef41Sopenharmony_ci // 5. Let k be 1. 581cb0ef41Sopenharmony_ci let k: Number = 1; 591cb0ef41Sopenharmony_ci // 6. Repeat, while k < len 601cb0ef41Sopenharmony_ci while (k < length) { 611cb0ef41Sopenharmony_ci // a. Let from be ! ToString(k). 621cb0ef41Sopenharmony_ci const from: Number = k; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci // b. Let to be ! ToString(k - 1). 651cb0ef41Sopenharmony_ci const to: Number = k - 1; 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // c. Let fromPresent be ? HasProperty(O, from). 681cb0ef41Sopenharmony_ci const fromPresent: Boolean = HasProperty(object, from); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // d. If fromPresent is true, then 711cb0ef41Sopenharmony_ci if (fromPresent == True) { 721cb0ef41Sopenharmony_ci // i. Let fromVal be ? Get(O, from). 731cb0ef41Sopenharmony_ci const fromValue: JSAny = GetProperty(object, from); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // ii. Perform ? Set(O, to, fromValue, true). 761cb0ef41Sopenharmony_ci SetProperty(object, to, fromValue); 771cb0ef41Sopenharmony_ci } else { 781cb0ef41Sopenharmony_ci // i. Perform ? DeletePropertyOrThrow(O, to). 791cb0ef41Sopenharmony_ci DeleteProperty(object, to, LanguageMode::kStrict); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci // f. Increase k by 1. 831cb0ef41Sopenharmony_ci k++; 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // 7. Perform ? DeletePropertyOrThrow(O, ! ToString(len - 1)). 871cb0ef41Sopenharmony_ci DeleteProperty(object, length - 1, LanguageMode::kStrict); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci // 8. Perform ? Set(O, "length", len - 1, true). 901cb0ef41Sopenharmony_ci SetProperty(object, kLengthString, length - 1); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci // 9. Return first. 931cb0ef41Sopenharmony_ci return first; 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci// https://tc39.github.io/ecma262/#sec-array.prototype.shift 971cb0ef41Sopenharmony_citransitioning javascript builtin ArrayPrototypeShift( 981cb0ef41Sopenharmony_ci js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { 991cb0ef41Sopenharmony_ci try { 1001cb0ef41Sopenharmony_ci return TryFastArrayShift(receiver) otherwise Slow, Runtime; 1011cb0ef41Sopenharmony_ci } label Slow { 1021cb0ef41Sopenharmony_ci return GenericArrayShift(receiver); 1031cb0ef41Sopenharmony_ci } label Runtime { 1041cb0ef41Sopenharmony_ci tail ArrayShift( 1051cb0ef41Sopenharmony_ci context, LoadTargetFromFrame(), Undefined, 1061cb0ef41Sopenharmony_ci Convert<int32>(arguments.actual_count)); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci} 110