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_ciextern enum IterationKind extends uint31 { kKeys, kValues, kEntries } 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciextern class JSArrayIterator extends JSObject { 81cb0ef41Sopenharmony_ci iterated_object: JSReceiver; 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci // [next_index]: The [[ArrayIteratorNextIndex]] inobject property. 111cb0ef41Sopenharmony_ci // The next_index is always a positive integer, and it points to 121cb0ef41Sopenharmony_ci // the next index that is to be returned by this iterator. It's 131cb0ef41Sopenharmony_ci // possible range is fixed depending on the [[iterated_object]]: 141cb0ef41Sopenharmony_ci // 151cb0ef41Sopenharmony_ci // 1. For JSArray's the next_index is always in Unsigned32 161cb0ef41Sopenharmony_ci // range, and when the iterator reaches the end it's set 171cb0ef41Sopenharmony_ci // to kMaxUInt32 to indicate that this iterator should 181cb0ef41Sopenharmony_ci // never produce values anymore even if the "length" 191cb0ef41Sopenharmony_ci // property of the JSArray changes at some later point. 201cb0ef41Sopenharmony_ci // 2. For JSTypedArray's the next_index is always in 211cb0ef41Sopenharmony_ci // UnsignedSmall range, and when the iterator terminates 221cb0ef41Sopenharmony_ci // it's set to Smi::kMaxValue. 231cb0ef41Sopenharmony_ci // 3. For all other JSReceiver's it's always between 0 and 241cb0ef41Sopenharmony_ci // kMaxSafeInteger, and the latter value is used to mark 251cb0ef41Sopenharmony_ci // termination. 261cb0ef41Sopenharmony_ci // 271cb0ef41Sopenharmony_ci // It's important that for 1. and 2. the value fits into the 281cb0ef41Sopenharmony_ci // Unsigned32 range (UnsignedSmall is a subset of Unsigned32), 291cb0ef41Sopenharmony_ci // since we use this knowledge in the fast-path for the array 301cb0ef41Sopenharmony_ci // iterator next calls in TurboFan (in the JSCallReducer) to 311cb0ef41Sopenharmony_ci // keep the index in Word32 representation. This invariant is 321cb0ef41Sopenharmony_ci // checked in JSArrayIterator::JSArrayIteratorVerify(). 331cb0ef41Sopenharmony_ci next_index: Number; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci kind: SmiTagged<IterationKind>; 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci// Perform CreateArrayIterator (ES #sec-createarrayiterator). 391cb0ef41Sopenharmony_ci@export 401cb0ef41Sopenharmony_cimacro CreateArrayIterator(implicit context: NativeContext)( 411cb0ef41Sopenharmony_ci array: JSReceiver, kind: constexpr IterationKind): JSArrayIterator { 421cb0ef41Sopenharmony_ci return new JSArrayIterator{ 431cb0ef41Sopenharmony_ci map: *NativeContextSlot(ContextSlot::INITIAL_ARRAY_ITERATOR_MAP_INDEX), 441cb0ef41Sopenharmony_ci properties_or_hash: kEmptyFixedArray, 451cb0ef41Sopenharmony_ci elements: kEmptyFixedArray, 461cb0ef41Sopenharmony_ci iterated_object: array, 471cb0ef41Sopenharmony_ci next_index: 0, 481cb0ef41Sopenharmony_ci kind: SmiTag<IterationKind>(kind) 491cb0ef41Sopenharmony_ci }; 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciextern class JSArray extends JSObject { 531cb0ef41Sopenharmony_ci macro IsEmpty(): bool { 541cb0ef41Sopenharmony_ci return this.length == 0; 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci length: Number; 571cb0ef41Sopenharmony_ci} 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci@doNotGenerateCast 601cb0ef41Sopenharmony_ciextern class JSArrayConstructor extends JSFunction 611cb0ef41Sopenharmony_ci generates 'TNode<JSFunction>'; 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_cimacro NewJSArray(implicit context: Context)( 641cb0ef41Sopenharmony_ci map: Map, elements: FixedArrayBase): JSArray { 651cb0ef41Sopenharmony_ci return new JSArray{ 661cb0ef41Sopenharmony_ci map, 671cb0ef41Sopenharmony_ci properties_or_hash: kEmptyFixedArray, 681cb0ef41Sopenharmony_ci elements, 691cb0ef41Sopenharmony_ci length: elements.length 701cb0ef41Sopenharmony_ci }; 711cb0ef41Sopenharmony_ci} 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_cimacro NewJSArray(implicit context: Context)(): JSArray { 741cb0ef41Sopenharmony_ci return new JSArray{ 751cb0ef41Sopenharmony_ci map: GetFastPackedSmiElementsJSArrayMap(), 761cb0ef41Sopenharmony_ci properties_or_hash: kEmptyFixedArray, 771cb0ef41Sopenharmony_ci elements: kEmptyFixedArray, 781cb0ef41Sopenharmony_ci length: 0 791cb0ef41Sopenharmony_ci }; 801cb0ef41Sopenharmony_ci} 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci// A HeapObject with a JSArray map, and either fast packed elements, or fast 831cb0ef41Sopenharmony_ci// holey elements when the global NoElementsProtector is not invalidated. 841cb0ef41Sopenharmony_citransient type FastJSArray extends JSArray; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci// A HeapObject with a JSArray map, and either fast packed elements, or fast 871cb0ef41Sopenharmony_ci// holey elements or frozen, sealed elements when the global NoElementsProtector 881cb0ef41Sopenharmony_ci// is not invalidated. 891cb0ef41Sopenharmony_citransient type FastJSArrayForRead extends JSArray; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci// A FastJSArray when the global ArraySpeciesProtector is not invalidated. 921cb0ef41Sopenharmony_citransient type FastJSArrayForCopy extends FastJSArray; 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci// A FastJSArrayForCopy when the global IsConcatSpreadableProtector is not 951cb0ef41Sopenharmony_ci// invalidated. 961cb0ef41Sopenharmony_citransient type FastJSArrayForConcat extends FastJSArrayForCopy; 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci// A FastJSArray when the global ArrayIteratorProtector is not invalidated. 991cb0ef41Sopenharmony_citransient type FastJSArrayWithNoCustomIteration extends FastJSArray; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci// A FastJSArrayForRead when the global ArrayIteratorProtector is not 1021cb0ef41Sopenharmony_ci// invalidated. 1031cb0ef41Sopenharmony_citransient type FastJSArrayForReadWithNoCustomIteration extends 1041cb0ef41Sopenharmony_ci FastJSArrayForRead; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ciextern macro AllocateJSArray( 1071cb0ef41Sopenharmony_ci constexpr ElementsKind, Map, intptr, Smi, 1081cb0ef41Sopenharmony_ci constexpr AllocationFlag): JSArray; 1091cb0ef41Sopenharmony_ciextern macro AllocateJSArray(constexpr ElementsKind, Map, intptr, Smi): JSArray; 1101cb0ef41Sopenharmony_ciextern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray; 1111cb0ef41Sopenharmony_ciextern macro AllocateJSArray(Map, FixedArrayBase, Smi): JSArray; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_cimacro LoadElementNoHole<T : type extends FixedArrayBase>( 1141cb0ef41Sopenharmony_ci a: JSArray, index: Smi): JSAny 1151cb0ef41Sopenharmony_ci labels IfHole; 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciLoadElementNoHole<FixedArray>(implicit context: Context)( 1181cb0ef41Sopenharmony_ci a: JSArray, index: Smi): JSAny 1191cb0ef41Sopenharmony_ci labels IfHole { 1201cb0ef41Sopenharmony_ci const elements: FixedArray = 1211cb0ef41Sopenharmony_ci Cast<FixedArray>(a.elements) otherwise unreachable; 1221cb0ef41Sopenharmony_ci const e = UnsafeCast<(JSAny | TheHole)>(elements.objects[index]); 1231cb0ef41Sopenharmony_ci typeswitch (e) { 1241cb0ef41Sopenharmony_ci case (TheHole): { 1251cb0ef41Sopenharmony_ci goto IfHole; 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci case (e: JSAny): { 1281cb0ef41Sopenharmony_ci return e; 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci} 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ciLoadElementNoHole<FixedDoubleArray>(implicit context: Context)( 1341cb0ef41Sopenharmony_ci a: JSArray, index: Smi): JSAny 1351cb0ef41Sopenharmony_ci labels IfHole { 1361cb0ef41Sopenharmony_ci const elements: FixedDoubleArray = 1371cb0ef41Sopenharmony_ci Cast<FixedDoubleArray>(a.elements) otherwise unreachable; 1381cb0ef41Sopenharmony_ci const e: float64 = elements.floats[index].Value() otherwise IfHole; 1391cb0ef41Sopenharmony_ci return AllocateHeapNumberWithValue(e); 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ciextern builtin ExtractFastJSArray(Context, JSArray, Smi, Smi): JSArray; 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ciextern macro MoveElements( 1451cb0ef41Sopenharmony_ci constexpr ElementsKind, FixedArrayBase, intptr, intptr, intptr): void; 1461cb0ef41Sopenharmony_cimacro TorqueMoveElementsSmi( 1471cb0ef41Sopenharmony_ci elements: FixedArray, dstIndex: intptr, srcIndex: intptr, 1481cb0ef41Sopenharmony_ci count: intptr): void { 1491cb0ef41Sopenharmony_ci MoveElements( 1501cb0ef41Sopenharmony_ci ElementsKind::HOLEY_SMI_ELEMENTS, elements, dstIndex, srcIndex, count); 1511cb0ef41Sopenharmony_ci} 1521cb0ef41Sopenharmony_cimacro TorqueMoveElements( 1531cb0ef41Sopenharmony_ci elements: FixedArray, dstIndex: intptr, srcIndex: intptr, 1541cb0ef41Sopenharmony_ci count: intptr): void { 1551cb0ef41Sopenharmony_ci MoveElements( 1561cb0ef41Sopenharmony_ci ElementsKind::HOLEY_ELEMENTS, elements, dstIndex, srcIndex, count); 1571cb0ef41Sopenharmony_ci} 1581cb0ef41Sopenharmony_cimacro TorqueMoveElements( 1591cb0ef41Sopenharmony_ci elements: FixedDoubleArray, dstIndex: intptr, srcIndex: intptr, 1601cb0ef41Sopenharmony_ci count: intptr): void { 1611cb0ef41Sopenharmony_ci MoveElements( 1621cb0ef41Sopenharmony_ci ElementsKind::HOLEY_DOUBLE_ELEMENTS, elements, dstIndex, srcIndex, count); 1631cb0ef41Sopenharmony_ci} 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ciextern macro CopyElements( 1661cb0ef41Sopenharmony_ci constexpr ElementsKind, FixedArrayBase, intptr, FixedArrayBase, intptr, 1671cb0ef41Sopenharmony_ci intptr): void; 1681cb0ef41Sopenharmony_cimacro TorqueCopyElements( 1691cb0ef41Sopenharmony_ci dstElements: FixedArray, dstIndex: intptr, srcElements: FixedArray, 1701cb0ef41Sopenharmony_ci srcIndex: intptr, count: intptr): void { 1711cb0ef41Sopenharmony_ci CopyElements( 1721cb0ef41Sopenharmony_ci ElementsKind::HOLEY_ELEMENTS, dstElements, dstIndex, srcElements, 1731cb0ef41Sopenharmony_ci srcIndex, count); 1741cb0ef41Sopenharmony_ci} 1751cb0ef41Sopenharmony_cimacro TorqueCopyElements( 1761cb0ef41Sopenharmony_ci dstElements: FixedDoubleArray, dstIndex: intptr, 1771cb0ef41Sopenharmony_ci srcElements: FixedDoubleArray, srcIndex: intptr, count: intptr): void { 1781cb0ef41Sopenharmony_ci CopyElements( 1791cb0ef41Sopenharmony_ci ElementsKind::HOLEY_DOUBLE_ELEMENTS, dstElements, dstIndex, srcElements, 1801cb0ef41Sopenharmony_ci srcIndex, count); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciextern builtin CloneFastJSArray(Context, FastJSArrayForCopy): JSArray; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_cistruct FastJSArrayWitness { 1861cb0ef41Sopenharmony_ci macro Get(): FastJSArray { 1871cb0ef41Sopenharmony_ci return this.unstable; 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci macro Recheck(): void labels CastError { 1911cb0ef41Sopenharmony_ci if (this.stable.map != this.map) goto CastError; 1921cb0ef41Sopenharmony_ci // We don't need to check elements kind or whether the prototype 1931cb0ef41Sopenharmony_ci // has changed away from the default JSArray prototype, because 1941cb0ef41Sopenharmony_ci // if the map remains the same then those properties hold. 1951cb0ef41Sopenharmony_ci // 1961cb0ef41Sopenharmony_ci // However, we have to make sure there are no elements in the 1971cb0ef41Sopenharmony_ci // prototype chain. 1981cb0ef41Sopenharmony_ci if (IsNoElementsProtectorCellInvalid()) goto CastError; 1991cb0ef41Sopenharmony_ci this.unstable = %RawDownCast<FastJSArray>(this.stable); 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci macro LoadElementNoHole(implicit context: Context)(k: Smi): JSAny 2031cb0ef41Sopenharmony_ci labels FoundHole { 2041cb0ef41Sopenharmony_ci if (this.hasDoubles) { 2051cb0ef41Sopenharmony_ci return LoadElementNoHole<FixedDoubleArray>(this.unstable, k) 2061cb0ef41Sopenharmony_ci otherwise FoundHole; 2071cb0ef41Sopenharmony_ci } else { 2081cb0ef41Sopenharmony_ci return LoadElementNoHole<FixedArray>(this.unstable, k) 2091cb0ef41Sopenharmony_ci otherwise FoundHole; 2101cb0ef41Sopenharmony_ci } 2111cb0ef41Sopenharmony_ci } 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci macro StoreHole(k: Smi): void { 2141cb0ef41Sopenharmony_ci if (this.hasDoubles) { 2151cb0ef41Sopenharmony_ci const elements = Cast<FixedDoubleArray>(this.unstable.elements) 2161cb0ef41Sopenharmony_ci otherwise unreachable; 2171cb0ef41Sopenharmony_ci elements.floats[k] = kDoubleHole; 2181cb0ef41Sopenharmony_ci } else { 2191cb0ef41Sopenharmony_ci const elements = Cast<FixedArray>(this.unstable.elements) 2201cb0ef41Sopenharmony_ci otherwise unreachable; 2211cb0ef41Sopenharmony_ci elements.objects[k] = TheHole; 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci } 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci macro LoadElementOrUndefined(implicit context: Context)(k: Smi): JSAny { 2261cb0ef41Sopenharmony_ci try { 2271cb0ef41Sopenharmony_ci return this.LoadElementNoHole(k) otherwise FoundHole; 2281cb0ef41Sopenharmony_ci } label FoundHole { 2291cb0ef41Sopenharmony_ci return Undefined; 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci } 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci macro EnsureArrayPushable(implicit context: Context)(): void labels Failed { 2341cb0ef41Sopenharmony_ci EnsureArrayPushable(this.map) otherwise Failed; 2351cb0ef41Sopenharmony_ci array::EnsureWriteableFastElements(this.unstable); 2361cb0ef41Sopenharmony_ci this.arrayIsPushable = true; 2371cb0ef41Sopenharmony_ci } 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci macro ChangeLength(newLength: Smi): void { 2401cb0ef41Sopenharmony_ci dcheck(this.arrayIsPushable); 2411cb0ef41Sopenharmony_ci this.unstable.length = newLength; 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci macro Push(value: JSAny): void labels Failed { 2451cb0ef41Sopenharmony_ci dcheck(this.arrayIsPushable); 2461cb0ef41Sopenharmony_ci if (this.hasDoubles) { 2471cb0ef41Sopenharmony_ci BuildAppendJSArray( 2481cb0ef41Sopenharmony_ci ElementsKind::HOLEY_DOUBLE_ELEMENTS, this.unstable, value) 2491cb0ef41Sopenharmony_ci otherwise Failed; 2501cb0ef41Sopenharmony_ci } else if (this.hasSmis) { 2511cb0ef41Sopenharmony_ci BuildAppendJSArray(ElementsKind::HOLEY_SMI_ELEMENTS, this.unstable, value) 2521cb0ef41Sopenharmony_ci otherwise Failed; 2531cb0ef41Sopenharmony_ci } else { 2541cb0ef41Sopenharmony_ci dcheck( 2551cb0ef41Sopenharmony_ci this.map.elements_kind == ElementsKind::HOLEY_ELEMENTS || 2561cb0ef41Sopenharmony_ci this.map.elements_kind == ElementsKind::PACKED_ELEMENTS); 2571cb0ef41Sopenharmony_ci BuildAppendJSArray(ElementsKind::HOLEY_ELEMENTS, this.unstable, value) 2581cb0ef41Sopenharmony_ci otherwise Failed; 2591cb0ef41Sopenharmony_ci } 2601cb0ef41Sopenharmony_ci } 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci macro MoveElements(dst: intptr, src: intptr, length: intptr): void { 2631cb0ef41Sopenharmony_ci dcheck(this.arrayIsPushable); 2641cb0ef41Sopenharmony_ci if (this.hasDoubles) { 2651cb0ef41Sopenharmony_ci const elements: FixedDoubleArray = 2661cb0ef41Sopenharmony_ci Cast<FixedDoubleArray>(this.unstable.elements) 2671cb0ef41Sopenharmony_ci otherwise unreachable; 2681cb0ef41Sopenharmony_ci TorqueMoveElements(elements, dst, src, length); 2691cb0ef41Sopenharmony_ci } else { 2701cb0ef41Sopenharmony_ci const elements: FixedArray = Cast<FixedArray>(this.unstable.elements) 2711cb0ef41Sopenharmony_ci otherwise unreachable; 2721cb0ef41Sopenharmony_ci if (this.hasSmis) { 2731cb0ef41Sopenharmony_ci TorqueMoveElementsSmi(elements, dst, src, length); 2741cb0ef41Sopenharmony_ci } else { 2751cb0ef41Sopenharmony_ci TorqueMoveElements(elements, dst, src, length); 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci } 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci const stable: JSArray; 2811cb0ef41Sopenharmony_ci unstable: FastJSArray; 2821cb0ef41Sopenharmony_ci const map: Map; 2831cb0ef41Sopenharmony_ci const hasDoubles: bool; 2841cb0ef41Sopenharmony_ci const hasSmis: bool; 2851cb0ef41Sopenharmony_ci arrayIsPushable: bool; 2861cb0ef41Sopenharmony_ci} 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_cimacro NewFastJSArrayWitness(array: FastJSArray): FastJSArrayWitness { 2891cb0ef41Sopenharmony_ci const kind = array.map.elements_kind; 2901cb0ef41Sopenharmony_ci return FastJSArrayWitness{ 2911cb0ef41Sopenharmony_ci stable: array, 2921cb0ef41Sopenharmony_ci unstable: array, 2931cb0ef41Sopenharmony_ci map: array.map, 2941cb0ef41Sopenharmony_ci hasDoubles: IsDoubleElementsKind(kind), 2951cb0ef41Sopenharmony_ci hasSmis: 2961cb0ef41Sopenharmony_ci IsElementsKindLessThanOrEqual(kind, ElementsKind::HOLEY_SMI_ELEMENTS), 2971cb0ef41Sopenharmony_ci arrayIsPushable: false 2981cb0ef41Sopenharmony_ci }; 2991cb0ef41Sopenharmony_ci} 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_cistruct FastJSArrayForReadWitness { 3021cb0ef41Sopenharmony_ci macro Get(): FastJSArrayForRead { 3031cb0ef41Sopenharmony_ci return this.unstable; 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci macro Recheck(): void labels CastError { 3071cb0ef41Sopenharmony_ci if (this.stable.map != this.map) goto CastError; 3081cb0ef41Sopenharmony_ci // We don't need to check elements kind or whether the prototype 3091cb0ef41Sopenharmony_ci // has changed away from the default JSArray prototype, because 3101cb0ef41Sopenharmony_ci // if the map remains the same then those properties hold. 3111cb0ef41Sopenharmony_ci // 3121cb0ef41Sopenharmony_ci // However, we have to make sure there are no elements in the 3131cb0ef41Sopenharmony_ci // prototype chain. 3141cb0ef41Sopenharmony_ci if (IsNoElementsProtectorCellInvalid()) goto CastError; 3151cb0ef41Sopenharmony_ci this.unstable = %RawDownCast<FastJSArrayForRead>(this.stable); 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci macro LoadElementNoHole(implicit context: Context)(k: Smi): JSAny 3191cb0ef41Sopenharmony_ci labels FoundHole { 3201cb0ef41Sopenharmony_ci if (this.hasDoubles) { 3211cb0ef41Sopenharmony_ci return LoadElementNoHole<FixedDoubleArray>(this.unstable, k) 3221cb0ef41Sopenharmony_ci otherwise FoundHole; 3231cb0ef41Sopenharmony_ci } else { 3241cb0ef41Sopenharmony_ci return LoadElementNoHole<FixedArray>(this.unstable, k) 3251cb0ef41Sopenharmony_ci otherwise FoundHole; 3261cb0ef41Sopenharmony_ci } 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci const stable: JSArray; 3301cb0ef41Sopenharmony_ci unstable: FastJSArrayForRead; 3311cb0ef41Sopenharmony_ci const map: Map; 3321cb0ef41Sopenharmony_ci const hasDoubles: bool; 3331cb0ef41Sopenharmony_ci} 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_cimacro NewFastJSArrayForReadWitness(array: FastJSArrayForRead): 3361cb0ef41Sopenharmony_ci FastJSArrayForReadWitness { 3371cb0ef41Sopenharmony_ci const kind = array.map.elements_kind; 3381cb0ef41Sopenharmony_ci return FastJSArrayForReadWitness{ 3391cb0ef41Sopenharmony_ci stable: array, 3401cb0ef41Sopenharmony_ci unstable: array, 3411cb0ef41Sopenharmony_ci map: array.map, 3421cb0ef41Sopenharmony_ci hasDoubles: IsDoubleElementsKind(kind) 3431cb0ef41Sopenharmony_ci }; 3441cb0ef41Sopenharmony_ci} 345