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 5#include 'src/builtins/builtins-array-gen.h' 6 7namespace array { 8// Naming convention from elements.cc. We have a similar intent but implement 9// fastpaths using generics instead of using a class hierarchy for elements 10// kinds specific implementations. 11type GenericElementsAccessor extends ElementsKind; 12type FastPackedSmiElements extends ElementsKind; 13type FastPackedObjectElements extends ElementsKind; 14type FastPackedDoubleElements extends ElementsKind; 15type FastSmiOrObjectElements extends ElementsKind; 16type FastDoubleElements extends ElementsKind; 17type DictionaryElements extends ElementsKind; 18 19macro EnsureWriteableFastElements(implicit context: Context)(array: JSArray): 20 void { 21 dcheck(IsFastElementsKind(array.map.elements_kind)); 22 23 const elements: FixedArrayBase = array.elements; 24 if (elements.map != kCOWMap) return; 25 26 // There are no COW *_DOUBLE_ELEMENTS arrays, so we are allowed to always 27 // extract FixedArrays and don't have to worry about FixedDoubleArrays. 28 dcheck(IsFastSmiOrTaggedElementsKind(array.map.elements_kind)); 29 30 const length = Convert<intptr>(Cast<Smi>(array.length) otherwise unreachable); 31 array.elements = 32 ExtractFixedArray(UnsafeCast<FixedArray>(elements), 0, length, length); 33 dcheck(array.elements.map != kCOWMap); 34} 35 36macro LoadElementOrUndefined(implicit context: Context)( 37 a: FixedArray, i: Smi): JSAny { 38 const e = UnsafeCast<(JSAny | TheHole)>(a.objects[i]); 39 return ReplaceTheHoleWithUndefined(e); 40} 41 42macro LoadElementOrUndefined(a: FixedDoubleArray, i: Smi): NumberOrUndefined { 43 const f: float64 = a.floats[i].Value() otherwise return Undefined; 44 return AllocateHeapNumberWithValue(f); 45} 46 47macro StoreArrayHole(elements: FixedDoubleArray, k: Smi): void { 48 elements.floats[k] = kDoubleHole; 49} 50 51macro StoreArrayHole(elements: FixedArray, k: Smi): void { 52 elements.objects[k] = TheHole; 53} 54 55extern macro SetPropertyLength(implicit context: Context)(JSAny, Number): void; 56 57const kLengthDescriptorIndex: 58 constexpr int31 generates 'JSArray::kLengthDescriptorIndex'; 59const kAttributesReadOnlyMask: constexpr int31 60 generates 'PropertyDetails::kAttributesReadOnlyMask'; 61 62@export 63macro EnsureArrayLengthWritable(implicit context: Context)(map: Map): 64 void labels Bailout { 65 // Don't support arrays in dictionary named property mode. 66 if (IsDictionaryMap(map)) { 67 goto Bailout; 68 } 69 70 // Check whether the length property is writable. The length property is the 71 // only default named property on arrays. It's nonconfigurable, hence is 72 // guaranteed to stay the first property. 73 const descriptors: DescriptorArray = map.instance_descriptors; 74 const descriptor:&DescriptorEntry = 75 &descriptors.descriptors[kLengthDescriptorIndex]; 76 dcheck(TaggedEqual(descriptor->key, LengthStringConstant())); 77 const details: Smi = UnsafeCast<Smi>(descriptor->details); 78 if ((details & kAttributesReadOnlyMask) != 0) { 79 goto Bailout; 80 } 81} 82 83macro CreateJSArrayWithElements(implicit context: Context)(array: FixedArray): 84 JSArray { 85 const nativeContext: NativeContext = LoadNativeContext(context); 86 const map: Map = 87 LoadJSArrayElementsMap(ElementsKind::PACKED_ELEMENTS, nativeContext); 88 return AllocateJSArray(map, array, array.length); 89} 90} 91