11cb0ef41Sopenharmony_ci// Copyright 2018 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_cimacro LoadElement<ElementsAccessor : type extends ElementsKind, T: type>( 71cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi): T; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciLoadElement<array::FastPackedSmiElements, Smi>(implicit context: Context)( 101cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi): Smi { 111cb0ef41Sopenharmony_ci const elements: FixedArray = UnsafeCast<FixedArray>(elements); 121cb0ef41Sopenharmony_ci return UnsafeCast<Smi>(elements.objects[index]); 131cb0ef41Sopenharmony_ci} 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciLoadElement<array::FastPackedObjectElements, JSAny>(implicit context: Context)( 161cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi): JSAny { 171cb0ef41Sopenharmony_ci const elements: FixedArray = UnsafeCast<FixedArray>(elements); 181cb0ef41Sopenharmony_ci return UnsafeCast<JSAny>(elements.objects[index]); 191cb0ef41Sopenharmony_ci} 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciLoadElement<array::FastPackedDoubleElements, float64>( 221cb0ef41Sopenharmony_ci implicit context: Context)(elements: FixedArrayBase, index: Smi): float64 { 231cb0ef41Sopenharmony_ci const elements: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); 241cb0ef41Sopenharmony_ci // This macro is only used for PACKED_DOUBLE, loading the hole should 251cb0ef41Sopenharmony_ci // be impossible. 261cb0ef41Sopenharmony_ci return elements.floats[index].Value() otherwise unreachable; 271cb0ef41Sopenharmony_ci} 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cimacro StoreElement<ElementsAccessor : type extends ElementsKind, T: type>( 301cb0ef41Sopenharmony_ci implicit context: Context)( 311cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi, value: T): void; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciStoreElement<array::FastPackedSmiElements, Smi>(implicit context: Context)( 341cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi, value: Smi): void { 351cb0ef41Sopenharmony_ci const elems: FixedArray = UnsafeCast<FixedArray>(elements); 361cb0ef41Sopenharmony_ci StoreFixedArrayElement(elems, index, value); 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciStoreElement<array::FastPackedObjectElements, JSAny>(implicit context: Context)( 401cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi, value: JSAny): void { 411cb0ef41Sopenharmony_ci const elements: FixedArray = UnsafeCast<FixedArray>(elements); 421cb0ef41Sopenharmony_ci elements.objects[index] = value; 431cb0ef41Sopenharmony_ci} 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ciStoreElement<array::FastPackedDoubleElements, float64>( 461cb0ef41Sopenharmony_ci implicit context: Context)( 471cb0ef41Sopenharmony_ci elements: FixedArrayBase, index: Smi, value: float64): void { 481cb0ef41Sopenharmony_ci const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); 491cb0ef41Sopenharmony_ci StoreFixedDoubleArrayElement(elems, index, value); 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci// Fast-path for all PACKED_* elements kinds. These do not need to check 531cb0ef41Sopenharmony_ci// whether a property is present, so we can simply swap them using fast 541cb0ef41Sopenharmony_ci// FixedArray loads/stores. 551cb0ef41Sopenharmony_cimacro FastPackedArrayReverse<Accessor: type, T: type>( 561cb0ef41Sopenharmony_ci implicit context: Context)(elements: FixedArrayBase, length: Smi): void { 571cb0ef41Sopenharmony_ci let lower: Smi = 0; 581cb0ef41Sopenharmony_ci let upper: Smi = length - 1; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci while (lower < upper) { 611cb0ef41Sopenharmony_ci const lowerValue: T = LoadElement<Accessor, T>(elements, lower); 621cb0ef41Sopenharmony_ci const upperValue: T = LoadElement<Accessor, T>(elements, upper); 631cb0ef41Sopenharmony_ci StoreElement<Accessor>(elements, lower, upperValue); 641cb0ef41Sopenharmony_ci StoreElement<Accessor>(elements, upper, lowerValue); 651cb0ef41Sopenharmony_ci ++lower; 661cb0ef41Sopenharmony_ci --upper; 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_citransitioning macro GenericArrayReverse( 711cb0ef41Sopenharmony_ci context: Context, receiver: JSAny): JSAny { 721cb0ef41Sopenharmony_ci // 1. Let O be ? ToObject(this value). 731cb0ef41Sopenharmony_ci const object: JSReceiver = ToObject_Inline(context, receiver); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // 2. Let len be ? ToLength(? Get(O, "length")). 761cb0ef41Sopenharmony_ci const length: Number = GetLengthProperty(object); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci // 3. Let middle be floor(len / 2). 791cb0ef41Sopenharmony_ci // 4. Let lower be 0. 801cb0ef41Sopenharmony_ci // 5. Repeat, while lower != middle. 811cb0ef41Sopenharmony_ci // a. Let upper be len - lower - 1. 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci // Instead of calculating the middle value, we simply initialize upper 841cb0ef41Sopenharmony_ci // with len - 1 and decrement it after each iteration. 851cb0ef41Sopenharmony_ci let lower: Number = 0; 861cb0ef41Sopenharmony_ci let upper: Number = length - 1; 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci while (lower < upper) { 891cb0ef41Sopenharmony_ci let lowerValue: JSAny = Undefined; 901cb0ef41Sopenharmony_ci let upperValue: JSAny = Undefined; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci // b. Let upperP be ! ToString(upper). 931cb0ef41Sopenharmony_ci // c. Let lowerP be ! ToString(lower). 941cb0ef41Sopenharmony_ci // d. Let lowerExists be ? HasProperty(O, lowerP). 951cb0ef41Sopenharmony_ci const lowerExists: Boolean = HasProperty(object, lower); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci // e. If lowerExists is true, then. 981cb0ef41Sopenharmony_ci if (lowerExists == True) { 991cb0ef41Sopenharmony_ci // i. Let lowerValue be ? Get(O, lowerP). 1001cb0ef41Sopenharmony_ci lowerValue = GetProperty(object, lower); 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci // f. Let upperExists be ? HasProperty(O, upperP). 1041cb0ef41Sopenharmony_ci const upperExists: Boolean = HasProperty(object, upper); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci // g. If upperExists is true, then. 1071cb0ef41Sopenharmony_ci if (upperExists == True) { 1081cb0ef41Sopenharmony_ci // i. Let upperValue be ? Get(O, upperP). 1091cb0ef41Sopenharmony_ci upperValue = GetProperty(object, upper); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // h. If lowerExists is true and upperExists is true, then 1131cb0ef41Sopenharmony_ci if (lowerExists == True && upperExists == True) { 1141cb0ef41Sopenharmony_ci // i. Perform ? Set(O, lowerP, upperValue, true). 1151cb0ef41Sopenharmony_ci SetProperty(object, lower, upperValue); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci // ii. Perform ? Set(O, upperP, lowerValue, true). 1181cb0ef41Sopenharmony_ci SetProperty(object, upper, lowerValue); 1191cb0ef41Sopenharmony_ci } else if (lowerExists == False && upperExists == True) { 1201cb0ef41Sopenharmony_ci // i. Perform ? Set(O, lowerP, upperValue, true). 1211cb0ef41Sopenharmony_ci SetProperty(object, lower, upperValue); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci // ii. Perform ? DeletePropertyOrThrow(O, upperP). 1241cb0ef41Sopenharmony_ci DeleteProperty(object, upper, LanguageMode::kStrict); 1251cb0ef41Sopenharmony_ci } else if (lowerExists == True && upperExists == False) { 1261cb0ef41Sopenharmony_ci // i. Perform ? DeletePropertyOrThrow(O, lowerP). 1271cb0ef41Sopenharmony_ci DeleteProperty(object, lower, LanguageMode::kStrict); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci // ii. Perform ? Set(O, upperP, lowerValue, true). 1301cb0ef41Sopenharmony_ci SetProperty(object, upper, lowerValue); 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci // l. Increase lower by 1. 1341cb0ef41Sopenharmony_ci ++lower; 1351cb0ef41Sopenharmony_ci --upper; 1361cb0ef41Sopenharmony_ci } 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci // 6. Return O. 1391cb0ef41Sopenharmony_ci return object; 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_cimacro TryFastPackedArrayReverse(implicit context: Context)(receiver: JSAny): 1431cb0ef41Sopenharmony_ci void labels Slow { 1441cb0ef41Sopenharmony_ci const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci const kind: ElementsKind = array.map.elements_kind; 1471cb0ef41Sopenharmony_ci if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { 1481cb0ef41Sopenharmony_ci array::EnsureWriteableFastElements(array); 1491cb0ef41Sopenharmony_ci FastPackedArrayReverse<array::FastPackedSmiElements, Smi>( 1501cb0ef41Sopenharmony_ci array.elements, array.length); 1511cb0ef41Sopenharmony_ci } else if (kind == ElementsKind::PACKED_ELEMENTS) { 1521cb0ef41Sopenharmony_ci array::EnsureWriteableFastElements(array); 1531cb0ef41Sopenharmony_ci FastPackedArrayReverse<array::FastPackedObjectElements, JSAny>( 1541cb0ef41Sopenharmony_ci array.elements, array.length); 1551cb0ef41Sopenharmony_ci } else if (kind == ElementsKind::PACKED_DOUBLE_ELEMENTS) { 1561cb0ef41Sopenharmony_ci FastPackedArrayReverse<array::FastPackedDoubleElements, float64>( 1571cb0ef41Sopenharmony_ci array.elements, array.length); 1581cb0ef41Sopenharmony_ci } else { 1591cb0ef41Sopenharmony_ci goto Slow; 1601cb0ef41Sopenharmony_ci } 1611cb0ef41Sopenharmony_ci} 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci// https://tc39.github.io/ecma262/#sec-array.prototype.reverse 1641cb0ef41Sopenharmony_citransitioning javascript builtin ArrayPrototypeReverse( 1651cb0ef41Sopenharmony_ci js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { 1661cb0ef41Sopenharmony_ci try { 1671cb0ef41Sopenharmony_ci TryFastPackedArrayReverse(receiver) otherwise Baseline; 1681cb0ef41Sopenharmony_ci return receiver; 1691cb0ef41Sopenharmony_ci } label Baseline { 1701cb0ef41Sopenharmony_ci return GenericArrayReverse(context, receiver); 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci} 174