5 #include "src/builtins/builtins-typed-array-gen.h" 7 #include "src/builtins/builtins-constructor-gen.h" 8 #include "src/builtins/builtins-utils-gen.h" 9 #include "src/builtins/builtins.h" 10 #include "src/builtins/growable-fixed-array-gen.h" 11 #include "src/handles-inl.h" 12 #include "src/heap/factory-inl.h" 19 using TNode = compiler::TNode<T>;
23 #ifndef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 24 #define V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 64 30 TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
31 TNode<JSTypedArray> array) {
32 TVARIABLE(Map, var_typed_map);
33 TNode<Map> array_map = LoadMap(array);
34 TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);
35 ReadOnlyRoots roots(isolate());
37 DispatchTypedArrayByElementsKind(
39 [&](ElementsKind kind,
int size,
int typed_array_fun_index) {
40 Handle<Map> map(roots.MapForFixedTypedArray(kind), isolate());
41 var_typed_map = HeapConstant(map);
44 return var_typed_map.value();
54 TNode<UintPtrT> TypedArrayBuiltinsAssembler::CalculateExternalPointer(
55 TNode<UintPtrT> backing_store, TNode<Number> byte_offset) {
57 IntPtrAdd(backing_store, ChangeNonnegativeNumberToUintPtr(byte_offset)));
65 void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
67 TNode<UintPtrT> byte_offset,
68 TNode<UintPtrT> byte_length) {
69 StoreObjectField(holder, JSTypedArray::kLengthOffset, length);
70 StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
72 MachineType::PointerRepresentation());
73 StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteLengthOffset,
75 MachineType::PointerRepresentation());
76 for (
int offset = JSTypedArray::kHeaderSize;
77 offset < JSTypedArray::kSizeWithEmbedderFields; offset += kPointerSize) {
78 StoreObjectField(holder, offset, SmiConstant(0));
83 void TypedArrayBuiltinsAssembler::AttachBuffer(TNode<JSTypedArray> holder,
84 TNode<JSArrayBuffer> buffer,
87 TNode<Number> byte_offset) {
88 StoreObjectField(holder, JSArrayBufferView::kBufferOffset, buffer);
90 Node* elements = Allocate(FixedTypedArrayBase::kHeaderSize);
91 StoreMapNoWriteBarrier(elements, map);
92 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
93 StoreObjectFieldNoWriteBarrier(
94 elements, FixedTypedArrayBase::kBasePointerOffset, SmiConstant(0));
96 TNode<UintPtrT> backing_store =
97 LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kBackingStoreOffset);
99 TNode<UintPtrT> external_pointer =
100 CalculateExternalPointer(backing_store, byte_offset);
101 StoreObjectFieldNoWriteBarrier(
102 elements, FixedTypedArrayBase::kExternalPointerOffset, external_pointer,
103 MachineType::PointerRepresentation());
105 StoreObjectField(holder, JSObject::kElementsOffset, elements);
108 TF_BUILTIN(TypedArrayInitializeWithBuffer, TypedArrayBuiltinsAssembler) {
109 TNode<JSTypedArray> holder = CAST(Parameter(Descriptor::kHolder));
110 TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
111 TNode<JSArrayBuffer> buffer = CAST(Parameter(Descriptor::kBuffer));
112 TNode<Smi> element_size = CAST(Parameter(Descriptor::kElementSize));
113 TNode<Number> byte_offset = CAST(Parameter(Descriptor::kByteOffset));
115 TNode<Map> fixed_typed_map = LoadMapForType(holder);
118 TNode<Number> byte_length = SmiMul(length, element_size);
120 SetupTypedArray(holder, length, ChangeNonnegativeNumberToUintPtr(byte_offset),
121 ChangeNonnegativeNumberToUintPtr(byte_length));
122 AttachBuffer(holder, buffer, fixed_typed_map, length, byte_offset);
123 Return(UndefinedConstant());
126 TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
127 TNode<JSTypedArray> holder = CAST(Parameter(Descriptor::kHolder));
128 TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
129 TNode<Smi> element_size = CAST(Parameter(Descriptor::kElementSize));
130 Node* initialize = Parameter(Descriptor::kInitialize);
131 TNode<JSReceiver> buffer_constructor =
132 CAST(Parameter(Descriptor::kBufferConstructor));
133 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
135 CSA_ASSERT(
this, TaggedIsPositiveSmi(length));
136 CSA_ASSERT(
this, TaggedIsPositiveSmi(element_size));
137 CSA_ASSERT(
this, IsBoolean(initialize));
139 TNode<Smi> byte_offset = SmiConstant(0);
141 static const int32_t fta_base_data_offset =
142 FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
144 Label setup_holder(
this), allocate_on_heap(
this), aligned(
this),
145 allocate_elements(
this), allocate_off_heap(
this),
146 allocate_off_heap_custom_constructor(
this),
147 allocate_off_heap_no_init(
this), attach_buffer(
this), done(
this);
148 TVARIABLE(IntPtrT, var_total_size);
151 TNode<Number> byte_length = SmiMul(length, element_size);
153 TNode<Map> fixed_typed_map = LoadMapForType(holder);
156 TNode<JSFunction> default_constructor = CAST(LoadContextElement(
157 LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
158 GotoIfNot(WordEqual(buffer_constructor, default_constructor),
159 &allocate_off_heap_custom_constructor);
162 GotoIf(TaggedIsNotSmi(byte_length), &allocate_off_heap);
163 TNode<Smi> smi_byte_length = CAST(byte_length);
164 GotoIf(SmiGreaterThan(smi_byte_length,
165 SmiConstant(V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP)),
167 TNode<IntPtrT> word_byte_length = SmiToIntPtr(smi_byte_length);
168 Goto(&allocate_on_heap);
170 BIND(&allocate_on_heap);
172 CSA_ASSERT(
this, TaggedIsPositiveSmi(byte_length));
175 Node* native_context = LoadNativeContext(context);
177 LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX);
178 Node* empty_fixed_array = LoadRoot(RootIndex::kEmptyFixedArray);
180 Node* buffer = Allocate(JSArrayBuffer::kSizeWithEmbedderFields);
181 StoreMapNoWriteBarrier(buffer, map);
182 StoreObjectFieldNoWriteBarrier(buffer, JSArray::kPropertiesOrHashOffset,
184 StoreObjectFieldNoWriteBarrier(buffer, JSArray::kElementsOffset,
192 if (FIELD_SIZE(JSArrayBuffer::kOptionalPaddingOffset)) {
193 DCHECK_EQ(4, FIELD_SIZE(JSArrayBuffer::kOptionalPaddingOffset));
194 StoreObjectFieldNoWriteBarrier(
195 buffer, JSArrayBuffer::kOptionalPaddingOffset, Int32Constant(0),
196 MachineRepresentation::kWord32);
198 int32_t bitfield_value = (1 << JSArrayBuffer::IsExternalBit::kShift) |
199 (1 << JSArrayBuffer::IsNeuterableBit::kShift);
200 StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldOffset,
201 Int32Constant(bitfield_value),
202 MachineRepresentation::kWord32);
204 StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
205 SmiToIntPtr(CAST(byte_length)),
206 MachineType::PointerRepresentation());
207 StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
209 for (
int offset = JSArrayBuffer::kHeaderSize;
210 offset < JSArrayBuffer::kSizeWithEmbedderFields;
211 offset += kTaggedSize) {
212 StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(0));
215 StoreObjectField(holder, JSArrayBufferView::kBufferOffset, buffer);
219 GotoIf(WordEqual<Object, Object>(
220 SmiMod(element_size, SmiConstant(kObjectAlignment)),
225 DCHECK_EQ(0, FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask);
226 TNode<IntPtrT> aligned_header_size =
227 IntPtrConstant(FixedTypedArrayBase::kHeaderSize + kObjectAlignmentMask);
228 TNode<IntPtrT> size = IntPtrAdd(word_byte_length, aligned_header_size);
229 var_total_size = WordAnd(size, IntPtrConstant(~kObjectAlignmentMask));
230 Goto(&allocate_elements);
235 TNode<IntPtrT> header_size =
236 IntPtrConstant(FixedTypedArrayBase::kHeaderSize);
237 var_total_size = IntPtrAdd(word_byte_length, header_size);
238 Goto(&allocate_elements);
241 BIND(&allocate_elements);
245 CSA_ASSERT(
this, IsRegularHeapObjectSize(var_total_size.value()));
249 if (UnalignedLoadSupported(MachineRepresentation::kFloat64) &&
250 UnalignedStoreSupported(MachineRepresentation::kFloat64)) {
251 elements = AllocateInNewSpace(var_total_size.value());
253 elements = AllocateInNewSpace(var_total_size.value(), kDoubleAlignment);
256 StoreMapNoWriteBarrier(elements, fixed_typed_map);
257 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
258 StoreObjectFieldNoWriteBarrier(
259 elements, FixedTypedArrayBase::kBasePointerOffset, elements);
260 StoreObjectFieldNoWriteBarrier(elements,
261 FixedTypedArrayBase::kExternalPointerOffset,
262 IntPtrConstant(fta_base_data_offset),
263 MachineType::PointerRepresentation());
265 StoreObjectField(holder, JSObject::kElementsOffset, elements);
267 GotoIf(IsFalse(initialize), &done);
269 Node* backing_store = IntPtrAdd(BitcastTaggedToWord(elements),
270 IntPtrConstant(fta_base_data_offset));
272 Node* memset = ExternalConstant(ExternalReference::libc_memset_function());
273 CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
274 MachineType::IntPtr(), MachineType::UintPtr(), memset,
275 backing_store, IntPtrConstant(0), word_byte_length);
279 TVARIABLE(JSArrayBuffer, var_buffer);
281 BIND(&allocate_off_heap);
283 GotoIf(IsFalse(initialize), &allocate_off_heap_no_init);
284 var_buffer = CAST(Construct(context, default_constructor, byte_length));
285 Goto(&attach_buffer);
288 BIND(&allocate_off_heap_custom_constructor);
291 CAST(CallStub(CodeFactory::Construct(isolate()), context,
292 default_constructor, buffer_constructor, Int32Constant(1),
293 UndefinedConstant(), byte_length));
294 Goto(&attach_buffer);
297 BIND(&allocate_off_heap_no_init);
299 Node* buffer_constructor_noinit = LoadContextElement(
300 LoadNativeContext(context), Context::ARRAY_BUFFER_NOINIT_FUN_INDEX);
301 var_buffer = CAST(CallJS(CodeFactory::Call(isolate()), context,
302 buffer_constructor_noinit, UndefinedConstant(),
304 Goto(&attach_buffer);
307 BIND(&attach_buffer);
309 AttachBuffer(holder, var_buffer.value(), fixed_typed_map, length,
315 SetupTypedArray(holder, length, ChangeNonnegativeNumberToUintPtr(byte_offset),
316 ChangeNonnegativeNumberToUintPtr(byte_length));
317 Return(UndefinedConstant());
321 void TypedArrayBuiltinsAssembler::ConstructByLength(TNode<Context> context,
322 TNode<JSTypedArray> holder,
323 TNode<Object> length,
324 TNode<Smi> element_size) {
326 CSA_ASSERT(
this, TaggedIsPositiveSmi(element_size));
328 Label invalid_length(
this, Label::kDeferred), done(
this);
330 TNode<Number> converted_length =
331 ToInteger_Inline(context, length, CodeStubAssembler::kTruncateMinusZero);
337 GotoIf(TaggedIsNotSmi(converted_length), &invalid_length);
339 TNode<Smi> smi_converted_length = CAST(converted_length);
340 GotoIf(SmiLessThan(smi_converted_length, SmiConstant(0)), &invalid_length);
342 Node* initialize = TrueConstant();
343 TNode<JSFunction> default_constructor = CAST(LoadContextElement(
344 LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
345 CallBuiltin(Builtins::kTypedArrayInitialize, context, holder,
346 converted_length, element_size, initialize, default_constructor);
349 BIND(&invalid_length);
351 ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength,
359 void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
360 TNode<Context> context, TNode<JSTypedArray> holder,
361 TNode<JSArrayBuffer> buffer, TNode<Object> byte_offset,
362 TNode<Object> length, TNode<Smi> element_size) {
363 CSA_ASSERT(
this, TaggedIsPositiveSmi(element_size));
365 VARIABLE(new_byte_length, MachineRepresentation::kTagged, SmiConstant(0));
366 VARIABLE(offset, MachineRepresentation::kTagged, SmiConstant(0));
368 Label start_offset_error(
this, Label::kDeferred),
369 byte_length_error(
this, Label::kDeferred),
370 invalid_offset_error(
this, Label::kDeferred);
371 Label offset_is_smi(
this), offset_not_smi(
this, Label::kDeferred),
372 check_length(
this), call_init(
this), invalid_length(
this),
373 length_undefined(
this), length_defined(
this), done(
this);
375 GotoIf(IsUndefined(byte_offset), &check_length);
377 offset.Bind(ToInteger_Inline(context, byte_offset,
378 CodeStubAssembler::kTruncateMinusZero));
379 Branch(TaggedIsSmi(offset.value()), &offset_is_smi, &offset_not_smi);
382 BIND(&offset_is_smi);
384 TNode<Smi> smi_offset = CAST(offset.value());
385 GotoIf(SmiEqual(smi_offset, SmiConstant(0)), &check_length);
386 GotoIf(SmiLessThan(smi_offset, SmiConstant(0)), &invalid_length);
387 TNode<Number> remainder = SmiMod(smi_offset, element_size);
389 Branch(WordEqual<Object, Object>(remainder, SmiConstant(0)), &check_length,
390 &start_offset_error);
392 BIND(&offset_not_smi);
394 GotoIf(IsTrue(CallBuiltin(Builtins::kLessThan, context, offset.value(),
398 CallBuiltin(Builtins::kModulus, context, offset.value(), element_size);
400 Branch(IsTrue(CallBuiltin(Builtins::kEqual, context, remainder,
402 &check_length, &start_offset_error);
406 Branch(IsUndefined(length), &length_undefined, &length_defined);
408 BIND(&length_undefined);
410 ThrowIfArrayBufferIsDetached(context, buffer,
"Construct");
411 TNode<Number> buffer_byte_length = ChangeUintPtrToTagged(
412 LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kByteLengthOffset));
414 Node* remainder = CallBuiltin(Builtins::kModulus, context,
415 buffer_byte_length, element_size);
417 GotoIf(IsFalse(CallBuiltin(Builtins::kEqual, context, remainder,
421 new_byte_length.Bind(CallBuiltin(Builtins::kSubtract, context,
422 buffer_byte_length, offset.value()));
424 Branch(IsTrue(CallBuiltin(Builtins::kLessThan, context,
425 new_byte_length.value(), SmiConstant(0))),
426 &invalid_offset_error, &call_init);
429 BIND(&length_defined);
431 TNode<Smi> new_length = ToSmiIndex(length, context, &invalid_length);
432 ThrowIfArrayBufferIsDetached(context, buffer,
"Construct");
433 new_byte_length.Bind(SmiMul(new_length, element_size));
436 TNode<Number> buffer_byte_length = ChangeUintPtrToTagged(
437 LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kByteLengthOffset));
439 Node* end = CallBuiltin(Builtins::kAdd, context, offset.value(),
440 new_byte_length.value());
442 Branch(IsTrue(CallBuiltin(Builtins::kGreaterThan, context, end,
443 buffer_byte_length)),
444 &invalid_length, &call_init);
449 TNode<Object> raw_length = CallBuiltin(
450 Builtins::kDivide, context, new_byte_length.value(), element_size);
452 TNode<Smi> new_length = ToSmiIndex(raw_length, context, &invalid_length);
454 CallBuiltin(Builtins::kTypedArrayInitializeWithBuffer, context, holder,
455 new_length, buffer, element_size, offset.value());
459 BIND(&invalid_offset_error);
460 { ThrowRangeError(context, MessageTemplate::kInvalidOffset, byte_offset); }
462 BIND(&start_offset_error);
464 Node* holder_map = LoadMap(holder);
465 Node* problem_string = StringConstant(
"start offset");
466 CallRuntime(Runtime::kThrowInvalidTypedArrayAlignment, context, holder_map,
472 BIND(&byte_length_error);
474 Node* holder_map = LoadMap(holder);
475 Node* problem_string = StringConstant(
"byte length");
476 CallRuntime(Runtime::kThrowInvalidTypedArrayAlignment, context, holder_map,
482 BIND(&invalid_length);
484 ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength, length);
490 void TypedArrayBuiltinsAssembler::ConstructByTypedArray(
491 TNode<Context> context, TNode<JSTypedArray> holder,
492 TNode<JSTypedArray> typed_array, TNode<Smi> element_size) {
493 CSA_ASSERT(
this, TaggedIsPositiveSmi(element_size));
495 TNode<JSFunction>
const default_constructor = CAST(LoadContextElement(
496 LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
498 Label construct(
this), if_detached(
this), if_notdetached(
this),
499 check_for_sab(
this), if_buffernotshared(
this), check_prototype(
this),
501 TVARIABLE(JSReceiver, buffer_constructor, default_constructor);
503 TNode<JSArrayBuffer> source_buffer = LoadObjectField<JSArrayBuffer>(
504 typed_array, JSArrayBufferView::kBufferOffset);
505 Branch(IsDetachedBuffer(source_buffer), &if_detached, &if_notdetached);
508 TVARIABLE(Smi, source_length);
510 source_length = SmiConstant(0);
511 Goto(&check_for_sab);
513 BIND(&if_notdetached);
514 source_length = LoadJSTypedArrayLength(typed_array);
515 Goto(&check_for_sab);
520 BIND(&check_for_sab);
521 TNode<Uint32T> bitfield =
522 LoadObjectField<Uint32T>(source_buffer, JSArrayBuffer::kBitFieldOffset);
523 Branch(IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield), &construct,
524 &if_buffernotshared);
526 BIND(&if_buffernotshared);
529 SpeciesConstructor(context, source_buffer, default_constructor);
531 GotoIfNot(IsDetachedBuffer(source_buffer), &construct);
532 source_length = SmiConstant(0);
538 ConstructByArrayLike(context, holder, typed_array, source_length.value(),
539 element_size, buffer_constructor.value());
546 Node* TypedArrayBuiltinsAssembler::LoadDataPtr(Node* typed_array) {
547 CSA_ASSERT(
this, IsJSTypedArray(typed_array));
548 Node* elements = LoadElements(typed_array);
549 CSA_ASSERT(
this, IsFixedTypedArray(elements));
550 return LoadFixedTypedArrayBackingStore(CAST(elements));
553 TNode<BoolT> TypedArrayBuiltinsAssembler::ByteLengthIsValid(
554 TNode<Number> byte_length) {
555 Label smi(
this), done(
this);
556 TVARIABLE(BoolT, is_valid);
557 GotoIf(TaggedIsSmi(byte_length), &smi);
559 TNode<Float64T> float_value = LoadHeapNumberValue(CAST(byte_length));
560 TNode<Float64T> max_byte_length_double =
561 Float64Constant(FixedTypedArrayBase::kMaxByteLength);
562 is_valid = Float64LessThanOrEqual(float_value, max_byte_length_double);
566 TNode<IntPtrT> max_byte_length =
567 IntPtrConstant(FixedTypedArrayBase::kMaxByteLength);
569 UintPtrLessThanOrEqual(SmiUntag(CAST(byte_length)), max_byte_length);
573 return is_valid.value();
576 void TypedArrayBuiltinsAssembler::ConstructByArrayLike(
577 TNode<Context> context, TNode<JSTypedArray> holder,
578 TNode<HeapObject> array_like, TNode<Object> initial_length,
579 TNode<Smi> element_size, TNode<JSReceiver> buffer_constructor) {
580 Label invalid_length(
this, Label::kDeferred), fill(
this), fast_copy(
this),
581 detached_check(
this), done(
this);
584 TNode<Smi> length = ToSmiLength(initial_length, context, &invalid_length);
586 Node* initialize = FalseConstant();
587 CallBuiltin(Builtins::kTypedArrayInitialize, context, holder, length,
588 element_size, initialize, buffer_constructor);
590 GotoIf(IsJSTypedArray(array_like), &detached_check);
593 BIND(&detached_check);
594 ThrowIfArrayBufferViewBufferIsDetached(context, CAST(array_like),
599 GotoIf(SmiEqual(length, SmiConstant(0)), &done);
600 TNode<Int32T> holder_kind = LoadElementsKind(holder);
601 TNode<Int32T> source_kind = LoadElementsKind(array_like);
602 GotoIf(Word32Equal(holder_kind, source_kind), &fast_copy);
605 CallRuntime(Runtime::kTypedArrayCopyElements, context, holder, array_like,
611 Node* holder_data_ptr = LoadDataPtr(holder);
612 Node* source_data_ptr = LoadDataPtr(array_like);
616 CSA_ASSERT(
this, SmiNotEqual(length, SmiConstant(0)));
617 CSA_ASSERT(
this, Word32Equal(IsDetachedBuffer(LoadObjectField(
618 array_like, JSTypedArray::kBufferOffset)),
621 TNode<Number> byte_length = SmiMul(length, element_size);
622 CSA_ASSERT(
this, ByteLengthIsValid(byte_length));
623 TNode<UintPtrT> byte_length_intptr =
624 ChangeNonnegativeNumberToUintPtr(byte_length);
625 CSA_ASSERT(
this, UintPtrLessThanOrEqual(
627 IntPtrConstant(FixedTypedArrayBase::kMaxByteLength)));
629 Node* memcpy = ExternalConstant(ExternalReference::libc_memcpy_function());
630 CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
631 MachineType::Pointer(), MachineType::UintPtr(), memcpy,
632 holder_data_ptr, source_data_ptr, byte_length_intptr);
636 BIND(&invalid_length);
638 ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength,
645 void TypedArrayBuiltinsAssembler::ConstructByIterable(
646 TNode<Context> context, TNode<JSTypedArray> holder,
647 TNode<JSReceiver> iterable, TNode<JSReceiver> iterator_fn,
648 TNode<Smi> element_size) {
649 Label fast_path(
this), slow_path(
this), done(
this);
650 CSA_ASSERT(
this, IsCallable(iterator_fn));
652 TNode<JSArray> array_like =
653 CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
654 iterable, iterator_fn));
655 TNode<Object> initial_length = LoadJSArrayLength(array_like);
657 TNode<JSFunction> default_constructor = CAST(LoadContextElement(
658 LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
659 ConstructByArrayLike(context, holder, array_like, initial_length,
660 element_size, default_constructor);
663 TF_BUILTIN(TypedArrayBaseConstructor, TypedArrayBuiltinsAssembler) {
664 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
665 ThrowTypeError(context, MessageTemplate::kConstructAbstractClass,
670 TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
671 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
672 TNode<JSFunction> target = CAST(Parameter(Descriptor::kTarget));
673 TNode<JSReceiver> new_target = CAST(Parameter(Descriptor::kNewTarget));
674 TNode<Object> arg1 = CAST(Parameter(Descriptor::kArg1));
675 TNode<Object> arg2 = CAST(Parameter(Descriptor::kArg2));
676 TNode<Object> arg3 = CAST(Parameter(Descriptor::kArg3));
678 CSA_ASSERT(
this, IsConstructor(target));
679 CSA_ASSERT(
this, IsJSReceiver(new_target));
681 Label if_arg1isbuffer(
this), if_arg1istypedarray(
this),
682 if_arg1isreceiver(
this), if_arg1isnumber(
this), return_result(
this);
684 ConstructorBuiltinsAssembler constructor_assembler(this->state());
685 TNode<JSTypedArray> result = CAST(
686 constructor_assembler.EmitFastNewObject(context, target, new_target));
692 StoreObjectFieldNoWriteBarrier(result, JSTypedArray::kByteOffsetOffset,
694 MachineType::PointerRepresentation());
695 StoreObjectFieldNoWriteBarrier(result, JSTypedArray::kByteLengthOffset,
697 MachineType::PointerRepresentation());
699 TNode<Smi> element_size =
700 SmiTag(GetTypedArrayElementSize(LoadElementsKind(result)));
702 GotoIf(TaggedIsSmi(arg1), &if_arg1isnumber);
703 TNode<HeapObject> arg1_heap_object = UncheckedCast<HeapObject>(arg1);
704 GotoIf(IsJSArrayBuffer(arg1_heap_object), &if_arg1isbuffer);
705 GotoIf(IsJSTypedArray(arg1_heap_object), &if_arg1istypedarray);
706 GotoIf(IsJSReceiver(arg1_heap_object), &if_arg1isreceiver);
707 Goto(&if_arg1isnumber);
710 BIND(&if_arg1isbuffer);
712 ConstructByArrayBuffer(context, result, CAST(arg1), arg2, arg3,
714 Goto(&return_result);
718 BIND(&if_arg1istypedarray);
720 TNode<JSTypedArray> typed_array = CAST(arg1_heap_object);
721 ConstructByTypedArray(context, result, typed_array, element_size);
722 Goto(&return_result);
726 BIND(&if_arg1isreceiver);
728 Label if_iteratorundefined(
this), if_iteratornotcallable(
this);
730 TNode<Object> iteratorFn = CAST(GetMethod(
731 context, arg1_heap_object, isolate()->factory()->iterator_symbol(),
732 &if_iteratorundefined));
733 GotoIf(TaggedIsSmi(iteratorFn), &if_iteratornotcallable);
734 GotoIfNot(IsCallable(CAST(iteratorFn)), &if_iteratornotcallable);
736 ConstructByIterable(context, result, CAST(arg1_heap_object),
737 CAST(iteratorFn), element_size);
738 Goto(&return_result);
740 BIND(&if_iteratorundefined);
742 TNode<HeapObject> array_like = arg1_heap_object;
743 TNode<Object> initial_length =
744 GetProperty(context, arg1, LengthStringConstant());
746 TNode<JSFunction> default_constructor = CAST(LoadContextElement(
747 LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));
748 ConstructByArrayLike(context, result, array_like, initial_length,
749 element_size, default_constructor);
750 Goto(&return_result);
753 BIND(&if_iteratornotcallable);
754 { ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable); }
759 BIND(&if_arg1isnumber);
761 ConstructByLength(context, result, arg1, element_size);
762 Goto(&return_result);
765 BIND(&return_result);
770 TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
771 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
772 TNode<JSFunction> target = CAST(Parameter(Descriptor::kJSTarget));
773 TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
775 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
776 CodeStubArguments args(
this, argc);
777 Node* arg1 = args.GetOptionalArgumentValue(0);
778 Node* arg2 = args.GetOptionalArgumentValue(1);
779 Node* arg3 = args.GetOptionalArgumentValue(2);
784 Label throwtypeerror(
this, Label::kDeferred);
785 GotoIf(IsUndefined(new_target), &throwtypeerror);
787 Node* result = CallBuiltin(Builtins::kCreateTypedArray, context, target,
788 new_target, arg1, arg2, arg3);
789 args.PopAndReturn(result);
791 BIND(&throwtypeerror);
794 CAST(CallRuntime(Runtime::kGetFunctionName, context, target));
795 ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, name);
800 TF_BUILTIN(TypedArrayPrototypeByteLength, TypedArrayBuiltinsAssembler) {
801 const char*
const kMethodName =
"get TypedArray.prototype.byteLength";
802 Node* context = Parameter(Descriptor::kContext);
803 Node* receiver = Parameter(Descriptor::kReceiver);
806 ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
809 TNode<JSArrayBuffer> receiver_buffer =
810 LoadJSArrayBufferViewBuffer(CAST(receiver));
811 TNode<UintPtrT> byte_length = Select<UintPtrT>(
812 IsDetachedBuffer(receiver_buffer), [=] {
return UintPtrConstant(0); },
813 [=] {
return LoadJSArrayBufferViewByteLength(CAST(receiver)); });
814 Return(ChangeUintPtrToTagged(byte_length));
818 TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) {
819 const char*
const kMethodName =
"get TypedArray.prototype.byteOffset";
820 Node* context = Parameter(Descriptor::kContext);
821 Node* receiver = Parameter(Descriptor::kReceiver);
824 ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
827 TNode<JSArrayBuffer> receiver_buffer =
828 LoadJSArrayBufferViewBuffer(CAST(receiver));
829 TNode<UintPtrT> byte_offset = Select<UintPtrT>(
830 IsDetachedBuffer(receiver_buffer), [=] {
return UintPtrConstant(0); },
831 [=] {
return LoadJSArrayBufferViewByteOffset(CAST(receiver)); });
832 Return(ChangeUintPtrToTagged(byte_offset));
836 TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) {
837 const char*
const kMethodName =
"get TypedArray.prototype.length";
838 Node* context = Parameter(Descriptor::kContext);
839 Node* receiver = Parameter(Descriptor::kReceiver);
842 ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
845 TNode<JSArrayBuffer> receiver_buffer =
846 LoadJSArrayBufferViewBuffer(CAST(receiver));
847 TNode<Smi> length = Select<Smi>(
848 IsDetachedBuffer(receiver_buffer), [=] {
return SmiConstant(0); },
849 [=] {
return LoadJSTypedArrayLength(CAST(receiver)); });
853 TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
854 TNode<Word32T> kind) {
855 return Word32Or(Word32Equal(kind, Int32Constant(UINT8_ELEMENTS)),
856 Word32Equal(kind, Int32Constant(UINT8_CLAMPED_ELEMENTS)));
859 TNode<Word32T> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
860 TNode<Word32T> kind) {
861 return Word32Or(Word32Equal(kind, Int32Constant(BIGINT64_ELEMENTS)),
862 Word32Equal(kind, Int32Constant(BIGUINT64_ELEMENTS)));
865 TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize(
866 TNode<Word32T> elements_kind) {
867 TVARIABLE(IntPtrT, element_size);
869 DispatchTypedArrayByElementsKind(
871 [&](ElementsKind el_kind,
int size,
int typed_array_fun_index) {
872 element_size = IntPtrConstant(size);
875 return element_size.value();
878 TNode<JSFunction> TypedArrayBuiltinsAssembler::GetDefaultConstructor(
879 TNode<Context> context, TNode<JSTypedArray> exemplar) {
880 TVARIABLE(IntPtrT, context_slot);
881 TNode<Word32T> elements_kind = LoadElementsKind(exemplar);
883 DispatchTypedArrayByElementsKind(
885 [&](ElementsKind el_kind,
int size,
int typed_array_function_index) {
886 context_slot = IntPtrConstant(typed_array_function_index);
890 LoadContextElement(LoadNativeContext(context), context_slot.value()));
893 template <
class... TArgs>
894 TNode<JSTypedArray> TypedArrayBuiltinsAssembler::TypedArraySpeciesCreate(
895 const char* method_name, TNode<Context> context,
896 TNode<JSTypedArray> exemplar, TArgs... args) {
897 TVARIABLE(JSTypedArray, var_new_typed_array);
898 Label slow(
this, Label::kDeferred), done(
this);
902 TNode<JSFunction> default_constructor =
903 GetDefaultConstructor(context, exemplar);
905 TNode<Map> map = LoadMap(exemplar);
906 GotoIfNot(IsPrototypeTypedArrayPrototype(context, map), &slow);
907 GotoIf(IsTypedArraySpeciesProtectorCellInvalid(), &slow);
909 const size_t argc =
sizeof...(args);
910 static_assert(argc >= 1 && argc <= 3,
911 "TypedArraySpeciesCreate called with unexpected arguments");
912 TNode<Object> arg_list[argc] = {args...};
913 TNode<Object> arg0 = argc < 1 ? UndefinedConstant() : arg_list[0];
914 TNode<Object> arg1 = argc < 2 ? UndefinedConstant() : arg_list[1];
915 TNode<Object> arg2 = argc < 3 ? UndefinedConstant() : arg_list[2];
916 var_new_typed_array = UncheckedCast<JSTypedArray>(
917 CallBuiltin(Builtins::kCreateTypedArray, context, default_constructor,
918 default_constructor, arg0, arg1, arg2));
922 TNode<JSArrayBuffer> buffer =
923 LoadJSArrayBufferViewBuffer(var_new_typed_array.value());
924 CSA_ASSERT(
this, Word32BinaryNot(IsDetachedBuffer(buffer)));
931 TNode<JSReceiver> constructor =
932 SpeciesConstructor(context, exemplar, default_constructor);
935 TNode<JSReceiver> new_object = Construct(context, constructor, args...);
938 var_new_typed_array = ValidateTypedArray(context, new_object, method_name);
943 return var_new_typed_array.value();
947 TypedArrayBuiltinsAssembler::TypedArraySpeciesCreateByLength(
948 TNode<Context> context, TNode<JSTypedArray> exemplar, TNode<Smi> len,
949 const char* method_name) {
950 CSA_ASSERT(
this, TaggedIsPositiveSmi(len));
952 TNode<JSTypedArray> new_typed_array =
953 TypedArraySpeciesCreate(method_name, context, exemplar, len);
955 ThrowIfLengthLessThan(context, new_typed_array, len);
956 return new_typed_array;
959 TNode<JSTypedArray> TypedArrayBuiltinsAssembler::TypedArrayCreateByLength(
960 TNode<Context> context, TNode<Object> constructor, TNode<Smi> len,
961 const char* method_name) {
962 CSA_ASSERT(
this, TaggedIsPositiveSmi(len));
965 TNode<Object> new_object = CAST(ConstructJS(CodeFactory::Construct(isolate()),
966 context, constructor, len));
969 TNode<JSTypedArray> new_typed_array =
970 ValidateTypedArray(context, new_object, method_name);
972 ThrowIfLengthLessThan(context, new_typed_array, len);
973 return new_typed_array;
976 void TypedArrayBuiltinsAssembler::ThrowIfLengthLessThan(
977 TNode<Context> context, TNode<JSTypedArray> typed_array,
978 TNode<Smi> min_length) {
980 Label if_length_is_not_short(
this);
981 TNode<Smi> new_length = LoadJSTypedArrayLength(typed_array);
982 GotoIfNot(SmiLessThan(new_length, min_length), &if_length_is_not_short);
983 ThrowTypeError(context, MessageTemplate::kTypedArrayTooShort);
985 BIND(&if_length_is_not_short);
988 TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::GetBuffer(
989 TNode<Context> context, TNode<JSTypedArray> array) {
990 Label call_runtime(
this), done(
this);
991 TVARIABLE(Object, var_result);
993 TNode<Object> buffer = LoadObjectField(array, JSTypedArray::kBufferOffset);
994 GotoIf(IsDetachedBuffer(buffer), &call_runtime);
995 TNode<UintPtrT> backing_store = LoadObjectField<UintPtrT>(
996 CAST(buffer), JSArrayBuffer::kBackingStoreOffset);
997 GotoIf(WordEqual(backing_store, IntPtrConstant(0)), &call_runtime);
1001 BIND(&call_runtime);
1003 var_result = CallRuntime(Runtime::kTypedArrayGetBuffer, context, array);
1008 return CAST(var_result.value());
1011 TNode<JSTypedArray> TypedArrayBuiltinsAssembler::ValidateTypedArray(
1012 TNode<Context> context, TNode<Object> obj,
const char* method_name) {
1014 ThrowIfNotInstanceType(context, obj, JS_TYPED_ARRAY_TYPE, method_name);
1017 ThrowIfArrayBufferViewBufferIsDetached(context, CAST(obj), method_name);
1022 void TypedArrayBuiltinsAssembler::SetTypedArraySource(
1023 TNode<Context> context, TNode<JSTypedArray> source,
1024 TNode<JSTypedArray> target, TNode<IntPtrT> offset, Label* call_runtime,
1025 Label* if_source_too_large) {
1026 CSA_ASSERT(
this, Word32BinaryNot(IsDetachedBuffer(
1027 LoadObjectField(source, JSTypedArray::kBufferOffset))));
1028 CSA_ASSERT(
this, Word32BinaryNot(IsDetachedBuffer(
1029 LoadObjectField(target, JSTypedArray::kBufferOffset))));
1030 CSA_ASSERT(
this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0)));
1032 IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
1036 TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
1037 TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
1038 TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset);
1040 GotoIf(IntPtrGreaterThan(required_target_length, target_length),
1041 if_source_too_large);
1045 TNode<IntPtrT> target_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(target));
1046 TNode<IntPtrT> source_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(source));
1048 TNode<Word32T> source_el_kind = LoadElementsKind(source);
1049 TNode<Word32T> target_el_kind = LoadElementsKind(target);
1051 TNode<IntPtrT> source_el_size = GetTypedArrayElementSize(source_el_kind);
1052 TNode<IntPtrT> target_el_size = GetTypedArrayElementSize(target_el_kind);
1057 TNode<IntPtrT> source_byte_length = IntPtrMul(source_length, source_el_size);
1059 UintPtrGreaterThanOrEqual(source_byte_length, IntPtrConstant(0)));
1061 Label call_memmove(
this), fast_c_call(
this), out(
this), exception(
this);
1065 GotoIf(Word32Equal(source_el_kind, target_el_kind), &call_memmove);
1066 GotoIfNot(IsUint8ElementsKind(source_el_kind), &fast_c_call);
1067 Branch(IsUint8ElementsKind(target_el_kind), &call_memmove, &fast_c_call);
1069 BIND(&call_memmove);
1071 TNode<IntPtrT> target_start =
1072 IntPtrAdd(target_data_ptr, IntPtrMul(offset, target_el_size));
1073 CallCMemmove(target_start, source_data_ptr, source_byte_length);
1080 this, UintPtrGreaterThanOrEqual(
1081 IntPtrMul(target_length, target_el_size), IntPtrConstant(0)));
1083 GotoIf(Word32NotEqual(IsBigInt64ElementsKind(source_el_kind),
1084 IsBigInt64ElementsKind(target_el_kind)),
1087 TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
1088 CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
1094 ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
1099 void TypedArrayBuiltinsAssembler::SetJSArraySource(
1100 TNode<Context> context, TNode<JSArray> source, TNode<JSTypedArray> target,
1101 TNode<IntPtrT> offset, Label* call_runtime, Label* if_source_too_large) {
1102 CSA_ASSERT(
this, IsFastJSArray(source, context));
1103 CSA_ASSERT(
this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0)));
1105 IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
1107 TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source));
1108 TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
1111 GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length),
1112 if_source_too_large);
1115 Label out(
this), fast_c_call(
this);
1116 GotoIf(IntPtrEqual(source_length, IntPtrConstant(0)), &out);
1121 int32_t values[] = {
1122 PACKED_SMI_ELEMENTS, HOLEY_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS,
1123 HOLEY_DOUBLE_ELEMENTS,
1126 &fast_c_call, &fast_c_call, &fast_c_call, &fast_c_call,
1128 STATIC_ASSERT(arraysize(values) == arraysize(labels));
1130 TNode<Int32T> source_elements_kind = LoadElementsKind(source);
1131 Switch(source_elements_kind, call_runtime, values, labels,
1136 GotoIf(IsBigInt64ElementsKind(LoadElementsKind(target)), call_runtime);
1137 CallCCopyFastNumberJSArrayElementsToTypedArray(context, source, target,
1138 source_length, offset);
1143 void TypedArrayBuiltinsAssembler::CallCMemmove(TNode<IntPtrT> dest_ptr,
1144 TNode<IntPtrT> src_ptr,
1145 TNode<IntPtrT> byte_length) {
1146 TNode<ExternalReference> memmove =
1147 ExternalConstant(ExternalReference::libc_memmove_function());
1148 CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
1149 MachineType::Pointer(), MachineType::UintPtr(), memmove,
1150 dest_ptr, src_ptr, byte_length);
1153 void TypedArrayBuiltinsAssembler::
1154 CallCCopyFastNumberJSArrayElementsToTypedArray(TNode<Context> context,
1155 TNode<JSArray> source,
1156 TNode<JSTypedArray> dest,
1157 TNode<IntPtrT> source_length,
1158 TNode<IntPtrT> offset) {
1160 Word32BinaryNot(IsBigInt64ElementsKind(LoadElementsKind(dest))));
1161 TNode<ExternalReference> f = ExternalConstant(
1162 ExternalReference::copy_fast_number_jsarray_elements_to_typed_array());
1163 CallCFunction5(MachineType::AnyTagged(), MachineType::AnyTagged(),
1164 MachineType::AnyTagged(), MachineType::AnyTagged(),
1165 MachineType::UintPtr(), MachineType::UintPtr(), f, context,
1166 source, dest, source_length, offset);
1169 void TypedArrayBuiltinsAssembler::CallCCopyTypedArrayElementsToTypedArray(
1170 TNode<JSTypedArray> source, TNode<JSTypedArray> dest,
1171 TNode<IntPtrT> source_length, TNode<IntPtrT> offset) {
1172 TNode<ExternalReference> f = ExternalConstant(
1173 ExternalReference::copy_typed_array_elements_to_typed_array());
1174 CallCFunction4(MachineType::AnyTagged(), MachineType::AnyTagged(),
1175 MachineType::AnyTagged(), MachineType::UintPtr(),
1176 MachineType::UintPtr(), f, source, dest, source_length,
1180 void TypedArrayBuiltinsAssembler::CallCCopyTypedArrayElementsSlice(
1181 TNode<JSTypedArray> source, TNode<JSTypedArray> dest, TNode<IntPtrT> start,
1182 TNode<IntPtrT> end) {
1183 TNode<ExternalReference> f =
1184 ExternalConstant(ExternalReference::copy_typed_array_elements_slice());
1185 CallCFunction4(MachineType::AnyTagged(), MachineType::AnyTagged(),
1186 MachineType::AnyTagged(), MachineType::UintPtr(),
1187 MachineType::UintPtr(), f, source, dest, start, end);
1190 void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
1191 TNode<Word32T> elements_kind,
const TypedArraySwitchCase& case_function) {
1192 Label next(
this), if_unknown_type(
this, Label::kDeferred);
1194 int32_t elements_kinds[] = {
1195 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) TYPE##_ELEMENTS, 1196 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1197 #undef TYPED_ARRAY_CASE 1200 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) Label if_##type##array(this); 1201 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1202 #undef TYPED_ARRAY_CASE 1204 Label* elements_kind_labels[] = {
1205 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) &if_##type##array, 1206 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1207 #undef TYPED_ARRAY_CASE 1209 STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels));
1211 Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
1212 arraysize(elements_kinds));
1214 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \ 1215 BIND(&if_##type##array); \ 1217 case_function(TYPE##_ELEMENTS, sizeof(ctype), \ 1218 Context::TYPE##_ARRAY_FUN_INDEX); \ 1221 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1222 #undef TYPED_ARRAY_CASE 1224 BIND(&if_unknown_type);
1231 TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
1232 const char* method_name =
"%TypedArray%.prototype.set";
1233 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1234 CodeStubArguments args(
1236 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
1238 Label if_source_is_typed_array(
this), if_source_is_fast_jsarray(
this),
1239 if_offset_is_out_of_bounds(
this, Label::kDeferred),
1240 if_source_too_large(
this, Label::kDeferred),
1241 if_receiver_is_not_typedarray(
this, Label::kDeferred);
1244 TNode<Object> receiver = args.GetReceiver();
1245 GotoIf(TaggedIsSmi(receiver), &if_receiver_is_not_typedarray);
1246 GotoIfNot(IsJSTypedArray(CAST(receiver)), &if_receiver_is_not_typedarray);
1249 TNode<Object> offset = args.GetOptionalArgumentValue(1, SmiConstant(0));
1250 TNode<Number> offset_num =
1251 ToInteger_Inline(context, offset, kTruncateMinusZero);
1260 GotoIfNot(TaggedIsPositiveSmi(offset_num), &if_offset_is_out_of_bounds);
1261 TNode<Smi> offset_smi = CAST(offset_num);
1264 ThrowIfArrayBufferViewBufferIsDetached(context, CAST(receiver), method_name);
1267 Label call_runtime(
this);
1268 TNode<Object> source = args.GetOptionalArgumentValue(0);
1269 GotoIf(TaggedIsSmi(source), &call_runtime);
1270 GotoIf(IsJSTypedArray(CAST(source)), &if_source_is_typed_array);
1271 BranchIfFastJSArray(source, context, &if_source_is_fast_jsarray,
1275 BIND(&if_source_is_typed_array);
1278 ThrowIfArrayBufferViewBufferIsDetached(context, CAST(source), method_name);
1280 SetTypedArraySource(context, CAST(source), CAST(receiver),
1281 SmiUntag(offset_smi), &call_runtime,
1282 &if_source_too_large);
1283 args.PopAndReturn(UndefinedConstant());
1287 BIND(&if_source_is_fast_jsarray);
1289 SetJSArraySource(context, CAST(source), CAST(receiver),
1290 SmiUntag(offset_smi), &call_runtime, &if_source_too_large);
1291 args.PopAndReturn(UndefinedConstant());
1294 BIND(&call_runtime);
1295 args.PopAndReturn(CallRuntime(Runtime::kTypedArraySet, context, receiver,
1296 source, offset_smi));
1298 BIND(&if_offset_is_out_of_bounds);
1299 ThrowRangeError(context, MessageTemplate::kTypedArraySetOffsetOutOfBounds);
1301 BIND(&if_source_too_large);
1302 ThrowRangeError(context, MessageTemplate::kTypedArraySetSourceTooLarge);
1304 BIND(&if_receiver_is_not_typedarray);
1305 ThrowTypeError(context, MessageTemplate::kNotTypedArray);
1309 TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
1310 const char* method_name =
"%TypedArray%.prototype.slice";
1311 Label call_c(
this), call_memmove(
this), if_count_is_not_zero(
this),
1312 if_bigint_mixed_types(
this, Label::kDeferred);
1314 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1315 CodeStubArguments args(
1317 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
1319 TNode<Object> receiver = args.GetReceiver();
1320 TNode<JSTypedArray> source =
1321 ValidateTypedArray(context, receiver, method_name);
1323 TNode<Smi> source_length = LoadJSTypedArrayLength(source);
1326 TNode<Object> start = args.GetOptionalArgumentValue(0, SmiConstant(0));
1327 TNode<Smi> start_index =
1328 SmiTag(ConvertToRelativeIndex(context, start, SmiUntag(source_length)));
1333 TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
1334 TNode<Smi> end_index =
1335 Select<Smi>(IsUndefined(end), [=] {
return source_length; },
1337 return SmiTag(ConvertToRelativeIndex(
1338 context, end, SmiUntag(source_length)));
1342 TNode<Smi> count = SmiMax(SmiSub(end_index, start_index), SmiConstant(0));
1343 TNode<JSTypedArray> result_array =
1344 TypedArraySpeciesCreateByLength(context, source, count, method_name);
1347 GotoIf(SmiGreaterThan(count, SmiConstant(0)), &if_count_is_not_zero);
1348 args.PopAndReturn(result_array);
1350 BIND(&if_count_is_not_zero);
1353 CSA_ASSERT(
this, Word32BinaryNot(IsDetachedBuffer(LoadObjectField(
1354 result_array, JSTypedArray::kBufferOffset))));
1355 TNode<JSArrayBuffer> receiver_buffer =
1356 LoadJSArrayBufferViewBuffer(CAST(receiver));
1357 ThrowIfArrayBufferIsDetached(context, receiver_buffer, method_name);
1363 TNode<Word32T> source_el_kind = LoadElementsKind(source);
1364 TNode<Word32T> target_el_kind = LoadElementsKind(result_array);
1365 GotoIfNot(Word32Equal(source_el_kind, target_el_kind), &call_c);
1367 TNode<Object> target_buffer =
1368 LoadObjectField(result_array, JSTypedArray::kBufferOffset);
1369 Branch(WordEqual(receiver_buffer, target_buffer), &call_c, &call_memmove);
1371 BIND(&call_memmove);
1373 GotoIfForceSlowPath(&call_c);
1375 TNode<IntPtrT> target_data_ptr =
1376 UncheckedCast<IntPtrT>(LoadDataPtr(result_array));
1377 TNode<IntPtrT> source_data_ptr =
1378 UncheckedCast<IntPtrT>(LoadDataPtr(source));
1380 TNode<IntPtrT> source_el_size = GetTypedArrayElementSize(source_el_kind);
1381 TNode<IntPtrT> source_start_bytes =
1382 IntPtrMul(SmiToIntPtr(start_index), source_el_size);
1383 TNode<IntPtrT> source_start =
1384 IntPtrAdd(source_data_ptr, source_start_bytes);
1386 TNode<IntPtrT> count_bytes = IntPtrMul(SmiToIntPtr(count), source_el_size);
1389 TNode<UintPtrT> target_byte_length =
1390 LoadJSArrayBufferViewByteLength(result_array);
1391 CSA_ASSERT(
this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
1392 target_byte_length));
1393 TNode<UintPtrT> source_byte_length =
1394 LoadJSArrayBufferViewByteLength(source);
1395 TNode<UintPtrT> source_size_in_bytes =
1396 UintPtrSub(source_byte_length, Unsigned(source_start_bytes));
1397 CSA_ASSERT(
this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
1398 source_size_in_bytes));
1401 CallCMemmove(target_data_ptr, source_start, count_bytes);
1402 args.PopAndReturn(result_array);
1407 GotoIf(Word32NotEqual(IsBigInt64ElementsKind(source_el_kind),
1408 IsBigInt64ElementsKind(target_el_kind)),
1409 &if_bigint_mixed_types);
1411 CallCCopyTypedArrayElementsSlice(
1412 source, result_array, SmiToIntPtr(start_index), SmiToIntPtr(end_index));
1413 args.PopAndReturn(result_array);
1416 BIND(&if_bigint_mixed_types);
1417 ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
1421 TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
1422 const char* method_name =
"%TypedArray%.prototype.subarray";
1423 Label offset_done(
this);
1425 TVARIABLE(Smi, var_begin);
1426 TVARIABLE(Smi, var_end);
1428 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1429 CodeStubArguments args(
1431 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
1436 TNode<Object> receiver = args.GetReceiver();
1437 ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, method_name);
1439 TNode<JSTypedArray> source = CAST(receiver);
1442 TNode<JSArrayBuffer> buffer = GetBuffer(context, source);
1444 TNode<Smi> source_length = LoadJSTypedArrayLength(source);
1449 TNode<Object> begin = args.GetOptionalArgumentValue(0, SmiConstant(0));
1451 SmiTag(ConvertToRelativeIndex(context, begin, SmiUntag(source_length)));
1453 TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
1455 var_end = source_length;
1456 GotoIf(IsUndefined(end), &offset_done);
1462 SmiTag(ConvertToRelativeIndex(context, end, SmiUntag(source_length)));
1468 TNode<Smi> new_length =
1469 SmiMax(SmiSub(var_end.value(), var_begin.value()), SmiConstant(0));
1474 TNode<Word32T> element_kind = LoadElementsKind(source);
1475 TNode<IntPtrT> element_size = GetTypedArrayElementSize(element_kind);
1478 TNode<Number> source_byte_offset =
1479 ChangeUintPtrToTagged(LoadJSArrayBufferViewByteOffset(source));
1482 TNode<Number> offset = SmiMul(var_begin.value(), SmiFromIntPtr(element_size));
1483 TNode<Number> begin_byte_offset = NumberAdd(source_byte_offset, offset);
1487 args.PopAndReturn(TypedArraySpeciesCreate(
1488 method_name, context, source, buffer, begin_byte_offset, new_length));
1492 TF_BUILTIN(TypedArrayPrototypeToStringTag, TypedArrayBuiltinsAssembler) {
1493 Node* receiver = Parameter(Descriptor::kReceiver);
1494 Label if_receiverisheapobject(
this), return_undefined(
this);
1495 Branch(TaggedIsSmi(receiver), &return_undefined, &if_receiverisheapobject);
1499 size_t const kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
1500 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
1502 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \ 1503 Label return_##type##array(this); \ 1504 BIND(&return_##type##array); \ 1505 Return(StringConstant(#Type "Array")); 1506 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1507 #undef TYPED_ARRAY_CASE 1508 Label* elements_kind_labels[kTypedElementsKindCount] = {
1509 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) &return_##type##array, 1510 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1511 #undef TYPED_ARRAY_CASE 1513 int32_t elements_kinds[kTypedElementsKindCount] = {
1514 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \ 1515 TYPE##_ELEMENTS - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, 1516 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1517 #undef TYPED_ARRAY_CASE 1523 BIND(&if_receiverisheapobject);
1524 Node* elements_kind =
1525 Int32Sub(LoadElementsKind(receiver),
1526 Int32Constant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND));
1527 Switch(elements_kind, &return_undefined, elements_kinds, elements_kind_labels,
1528 kTypedElementsKindCount);
1530 BIND(&return_undefined);
1531 Return(UndefinedConstant());
1534 void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeIterationMethod(
1535 TNode<Context> context, TNode<Object> receiver,
const char* method_name,
1536 IterationKind kind) {
1537 Label throw_bad_receiver(
this, Label::kDeferred);
1539 GotoIf(TaggedIsSmi(receiver), &throw_bad_receiver);
1540 GotoIfNot(IsJSTypedArray(CAST(receiver)), &throw_bad_receiver);
1543 ThrowIfArrayBufferViewBufferIsDetached(context, CAST(receiver), method_name);
1545 Return(CreateArrayIterator(context, receiver, kind));
1547 BIND(&throw_bad_receiver);
1548 ThrowTypeError(context, MessageTemplate::kNotTypedArray, method_name);
1552 TF_BUILTIN(TypedArrayPrototypeValues, TypedArrayBuiltinsAssembler) {
1553 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1554 TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
1555 GenerateTypedArrayPrototypeIterationMethod(context, receiver,
1556 "%TypedArray%.prototype.values()",
1557 IterationKind::kValues);
1561 TF_BUILTIN(TypedArrayPrototypeEntries, TypedArrayBuiltinsAssembler) {
1562 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1563 TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
1564 GenerateTypedArrayPrototypeIterationMethod(context, receiver,
1565 "%TypedArray%.prototype.entries()",
1566 IterationKind::kEntries);
1570 TF_BUILTIN(TypedArrayPrototypeKeys, TypedArrayBuiltinsAssembler) {
1571 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1572 TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
1573 GenerateTypedArrayPrototypeIterationMethod(
1574 context, receiver,
"%TypedArray%.prototype.keys()", IterationKind::kKeys);
1578 TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
1579 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1582 TNode<IntPtrT> length = ChangeInt32ToIntPtr(
1583 UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)));
1585 CodeStubArguments args(
this, length,
nullptr, INTPTR_PARAMETERS,
1586 CodeStubArguments::ReceiverMode::kHasReceiver);
1588 Label if_not_constructor(
this, Label::kDeferred),
1589 if_neutered(
this, Label::kDeferred);
1593 TNode<Object> receiver = args.GetReceiver();
1594 GotoIf(TaggedIsSmi(receiver), &if_not_constructor);
1595 GotoIfNot(IsConstructor(CAST(receiver)), &if_not_constructor);
1598 TNode<JSTypedArray> new_typed_array = TypedArrayCreateByLength(
1599 context, receiver, SmiTag(length),
"%TypedArray%.of");
1601 TNode<Word32T> elements_kind = LoadElementsKind(new_typed_array);
1609 DispatchTypedArrayByElementsKind(
1611 [&](ElementsKind kind,
int size,
int typed_array_fun_index) {
1612 TNode<FixedTypedArrayBase> elements =
1613 CAST(LoadElements(new_typed_array));
1615 IntPtrConstant(0), length,
1617 TNode<Object> item = args.AtIndex(index, INTPTR_PARAMETERS);
1618 TNode<IntPtrT> intptr_index = UncheckedCast<IntPtrT>(index);
1619 if (kind == BIGINT64_ELEMENTS || kind == BIGUINT64_ELEMENTS) {
1620 EmitBigTypedArrayElementStore(new_typed_array, elements,
1621 intptr_index, item, context,
1625 PrepareValueForWriteToTypedArray(item, kind, context);
1629 Node* buffer = LoadObjectField(new_typed_array,
1630 JSTypedArray::kBufferOffset);
1631 GotoIf(IsDetachedBuffer(buffer), &if_neutered);
1635 TNode<RawPtrT> backing_store =
1636 LoadFixedTypedArrayBackingStore(elements);
1637 StoreElement(backing_store, kind, index, value,
1641 1, ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
1645 args.PopAndReturn(new_typed_array);
1647 BIND(&if_not_constructor);
1648 ThrowTypeError(context, MessageTemplate::kNotConstructor, receiver);
1651 ThrowTypeError(context, MessageTemplate::kDetachedOperation,
1656 TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
1657 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1659 Label check_iterator(
this), from_array_like(
this), fast_path(
this),
1660 slow_path(
this), create_typed_array(
this), check_typedarray(
this),
1661 if_not_constructor(
this, Label::kDeferred),
1662 if_map_fn_not_callable(
this, Label::kDeferred),
1663 if_iterator_fn_not_callable(
this, Label::kDeferred),
1664 if_neutered(
this, Label::kDeferred);
1666 CodeStubArguments args(
1668 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
1669 TNode<Object> source = args.GetOptionalArgumentValue(0);
1672 TNode<Object> this_arg = args.GetOptionalArgumentValue(2);
1676 TNode<Object> receiver = args.GetReceiver();
1677 GotoIf(TaggedIsSmi(receiver), &if_not_constructor);
1678 GotoIfNot(IsConstructor(CAST(receiver)), &if_not_constructor);
1681 TNode<Object> map_fn = args.GetOptionalArgumentValue(1);
1682 TVARIABLE(BoolT, mapping, Int32FalseConstant());
1683 GotoIf(IsUndefined(map_fn), &check_typedarray);
1688 GotoIf(TaggedIsSmi(map_fn), &if_map_fn_not_callable);
1689 GotoIfNot(IsCallable(CAST(map_fn)), &if_map_fn_not_callable);
1690 mapping = Int32TrueConstant();
1691 Goto(&check_typedarray);
1693 TVARIABLE(Object, final_source);
1694 TVARIABLE(Smi, final_length);
1706 BIND(&check_typedarray);
1707 TNode<Object> iterator_fn =
1708 CAST(GetMethod(context, source, isolate()->factory()->iterator_symbol(),
1710 GotoIf(TaggedIsSmi(iterator_fn), &if_iterator_fn_not_callable);
1730 GotoIf(TaggedIsSmi(source), &check_iterator);
1731 GotoIfNot(IsJSTypedArray(CAST(source)), &check_iterator);
1732 TNode<JSArrayBuffer> source_buffer =
1733 LoadJSArrayBufferViewBuffer(CAST(source));
1734 GotoIf(IsDetachedBuffer(source_buffer), &check_iterator);
1737 GotoIfNot(IsJSFunction(CAST(iterator_fn)), &check_iterator);
1738 TNode<SharedFunctionInfo> shared_info = LoadObjectField<SharedFunctionInfo>(
1739 CAST(iterator_fn), JSFunction::kSharedFunctionInfoOffset);
1741 WordEqual(LoadObjectField(shared_info,
1742 SharedFunctionInfo::kFunctionDataOffset),
1743 SmiConstant(Builtins::kTypedArrayPrototypeValues)),
1747 TNode<PropertyCell> protector_cell =
1748 CAST(LoadRoot(RootIndex::kArrayIteratorProtector));
1750 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
1751 SmiConstant(Isolate::kProtectorValid)),
1757 final_length = LoadJSTypedArrayLength(CAST(source));
1758 final_source = source;
1759 Goto(&create_typed_array);
1762 BIND(&check_iterator);
1765 GotoIfNot(IsCallable(CAST(iterator_fn)), &if_iterator_fn_not_callable);
1768 Label if_length_not_smi(
this, Label::kDeferred);
1772 TNode<JSArray> values = CAST(
1773 CallBuiltin(Builtins::kIterableToList, context, source, iterator_fn));
1777 TNode<Object> raw_length = LoadJSArrayLength(values);
1778 GotoIfNot(TaggedIsSmi(raw_length), &if_length_not_smi);
1780 final_length = CAST(raw_length);
1781 final_source = values;
1782 Goto(&create_typed_array);
1784 BIND(&if_length_not_smi);
1785 ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength,
1789 BIND(&from_array_like);
1792 Label if_length_not_smi(
this, Label::kDeferred);
1793 final_source = source;
1796 TNode<Object> raw_length =
1797 GetProperty(context, final_source.value(), LengthStringConstant());
1798 final_length = ToSmiLength(raw_length, context, &if_length_not_smi);
1799 Goto(&create_typed_array);
1801 BIND(&if_length_not_smi);
1802 ThrowRangeError(context, MessageTemplate::kInvalidTypedArrayLength,
1806 TVARIABLE(JSTypedArray, target_obj);
1808 BIND(&create_typed_array);
1811 target_obj = TypedArrayCreateByLength(
1812 context, receiver, final_length.value(),
"%TypedArray%.from");
1814 Branch(mapping.value(), &slow_path, &fast_path);
1820 GotoIf(SmiEqual(final_length.value(), SmiConstant(0)), &done);
1822 CallRuntime(Runtime::kTypedArrayCopyElements, context, target_obj.value(),
1823 final_source.value(), final_length.value());
1827 args.PopAndReturn(target_obj.value());
1831 TNode<Word32T> elements_kind = LoadElementsKind(target_obj.value());
1834 TNode<FixedTypedArrayBase> elements = CAST(LoadElements(target_obj.value()));
1836 SmiConstant(0), final_length.value(),
1838 TNode<Object>
const k_value =
1839 GetProperty(context, final_source.value(), index);
1841 TNode<Object>
const mapped_value =
1842 CAST(CallJS(CodeFactory::Call(isolate()), context, map_fn, this_arg,
1845 TNode<IntPtrT> intptr_index = SmiUntag(index);
1846 DispatchTypedArrayByElementsKind(
1848 [&](ElementsKind kind,
int size,
int typed_array_fun_index) {
1849 if (kind == BIGINT64_ELEMENTS || kind == BIGUINT64_ELEMENTS) {
1850 EmitBigTypedArrayElementStore(target_obj.value(), elements,
1851 intptr_index, mapped_value,
1852 context, &if_neutered);
1854 Node*
const final_value = PrepareValueForWriteToTypedArray(
1855 mapped_value, kind, context);
1859 Node* buffer = LoadObjectField(target_obj.value(),
1860 JSTypedArray::kBufferOffset);
1861 GotoIf(IsDetachedBuffer(buffer), &if_neutered);
1865 TNode<RawPtrT> backing_store =
1866 LoadFixedTypedArrayBackingStore(elements);
1867 StoreElement(backing_store, kind, index, final_value,
1872 1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
1874 args.PopAndReturn(target_obj.value());
1876 BIND(&if_not_constructor);
1877 ThrowTypeError(context, MessageTemplate::kNotConstructor, receiver);
1879 BIND(&if_map_fn_not_callable);
1880 ThrowTypeError(context, MessageTemplate::kCalledNonCallable, map_fn);
1882 BIND(&if_iterator_fn_not_callable);
1883 ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable);
1886 ThrowTypeError(context, MessageTemplate::kDetachedOperation,
1887 "%TypedArray%.from");
1891 TF_BUILTIN(TypedArrayPrototypeFilter, TypedArrayBuiltinsAssembler) {
1892 const char* method_name =
"%TypedArray%.prototype.filter";
1894 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
1895 CodeStubArguments args(
1897 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
1899 Label if_callback_not_callable(
this, Label::kDeferred),
1900 detached(
this, Label::kDeferred);
1904 TNode<Object> receiver = args.GetReceiver();
1905 TNode<JSTypedArray> source =
1906 ValidateTypedArray(context, receiver, method_name);
1909 TNode<Smi> length = LoadJSTypedArrayLength(source);
1912 TNode<Object> callbackfn = args.GetOptionalArgumentValue(0);
1913 GotoIf(TaggedIsSmi(callbackfn), &if_callback_not_callable);
1914 GotoIfNot(IsCallable(CAST(callbackfn)), &if_callback_not_callable);
1917 TNode<Object> this_arg = args.GetOptionalArgumentValue(1);
1919 TNode<JSArrayBuffer> source_buffer =
1920 LoadObjectField<JSArrayBuffer>(source, JSArrayBufferView::kBufferOffset);
1921 TNode<Word32T> elements_kind = LoadElementsKind(source);
1922 GrowableFixedArray values(state());
1924 {values.var_array(), values.var_length(), values.var_capacity()}, zone());
1931 vars, SmiConstant(0), length,
1933 GotoIf(IsDetachedBuffer(source_buffer), &detached);
1935 TVARIABLE(Numeric, value);
1938 DispatchTypedArrayByElementsKind(
1940 [&](ElementsKind kind,
int size,
int typed_array_fun_index) {
1941 TNode<IntPtrT> backing_store =
1942 UncheckedCast<IntPtrT>(LoadDataPtr(source));
1943 value = CAST(LoadFixedTypedArrayElementAsTagged(
1944 backing_store, index, kind, ParameterMode::SMI_PARAMETERS));
1949 CallJS(CodeFactory::Call(isolate()), context, callbackfn, this_arg,
1950 value.value(), index, source);
1952 Label true_continue(
this), false_continue(
this);
1953 BranchIfToBooleanIsTrue(selected, &true_continue, &false_continue);
1955 BIND(&true_continue);
1959 values.Push(value.value());
1960 Goto(&false_continue);
1962 BIND(&false_continue);
1964 1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
1966 TNode<JSArray> values_array = values.ToJSArray(context);
1967 TNode<Smi> captured = LoadFastJSArrayLength(values_array);
1970 TNode<JSTypedArray> result_array =
1971 TypedArraySpeciesCreateByLength(context, source, captured, method_name);
1977 CallRuntime(Runtime::kTypedArrayCopyElements, context, result_array,
1978 values_array, captured);
1981 args.PopAndReturn(result_array);
1983 BIND(&if_callback_not_callable);
1984 ThrowTypeError(context, MessageTemplate::kCalledNonCallable, callbackfn);
1987 ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);
1990 #undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP