29 for (
int offset = JSTypedArray::kHeaderSize;
60 if (
FIELD_SIZE(JSArrayBuffer::kOptionalPaddingOffset) != 0) {
63 buffer, JSArrayBuffer::kOptionalPaddingOffset,
Int32Constant(0));
65 int32_t bitfield_value = (1 << JSArrayBuffer::IsExternalBit::kShift) |
66 (1 << JSArrayBuffer::IsDetachableBit::kShift);
78#ifdef V8_COMPRESS_POINTERS
88 for (
int offset = JSArrayBuffer::kHeaderSize;
97 auto context = Parameter<Context>(Descriptor::kContext);
98 ThrowTypeError(context, MessageTemplate::kConstructAbstractClass,
104 auto context = Parameter<Context>(Descriptor::kContext);
105 auto target = Parameter<JSFunction>(Descriptor::kJSTarget);
106 auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
108 UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
117 Label throwtypeerror(
this, Label::kDeferred);
118 GotoIf(IsUndefined(
new_target), &throwtypeerror);
121 CallBuiltin<JSAny>(Builtin::kCreateTypedArray, context, target,
125 BIND(&throwtypeerror);
129 ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, name);
135 const char*
const kMethodName =
"get TypedArray.prototype.byteLength";
136 auto context = Parameter<Context>(Descriptor::kContext);
137 auto receiver = Parameter<Object>(Descriptor::kReceiver);
140 ThrowIfNotInstanceType(context,
receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
144 LoadJSArrayBufferViewBuffer(receiver_array);
146 Label variable_length(
this), normal(
this);
147 Branch(IsVariableLengthJSArrayBufferView(receiver_array), &variable_length,
149 BIND(&variable_length);
151 Return(ChangeUintPtrToTagged(LoadVariableLengthJSTypedArrayByteLength(
152 context, receiver_array, receiver_buffer)));
159 IsDetachedBuffer(receiver_buffer),
160 [=,
this] {
return UintPtrConstant(0); },
161 [=,
this] {
return LoadJSArrayBufferViewByteLength(receiver_array); });
162 Return(ChangeUintPtrToTagged(byte_length));
168 const char*
const kMethodName =
"get TypedArray.prototype.byteOffset";
169 auto context = Parameter<Context>(Descriptor::kContext);
170 auto receiver = Parameter<Object>(Descriptor::kReceiver);
173 ThrowIfNotInstanceType(context,
receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
176 Label detached_or_oob(
this), not_detached_nor_oob(
this);
177 IsJSArrayBufferViewDetachedOrOutOfBounds(
CAST(
receiver), &detached_or_oob,
178 ¬_detached_nor_oob);
179 BIND(&detached_or_oob);
180 Return(ChangeUintPtrToTagged(UintPtrConstant(0)));
182 BIND(¬_detached_nor_oob);
184 ChangeUintPtrToTagged(LoadJSArrayBufferViewByteOffset(
CAST(
receiver))));
189 const char*
const kMethodName =
"get TypedArray.prototype.length";
190 auto context = Parameter<Context>(Descriptor::kContext);
191 auto receiver = Parameter<Object>(Descriptor::kReceiver);
194 ThrowIfNotInstanceType(context,
receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
199 length = LoadJSTypedArrayLengthAndCheckDetached(receiver_array, &detached);
200 Return(ChangeUintPtrToTagged(length.value()));
202 Return(ChangeUintPtrToTagged(UintPtrConstant(0)));
217 static_assert(BIGUINT64_ELEMENTS + 1 == BIGINT64_ELEMENTS);
221 RAB_GSAB_BIGINT64_ELEMENTS));
230 [&](
ElementsKind el_kind,
int size,
int typed_array_fun_index) {
234 return element_size.value();
237TorqueStructTypedArrayElementsInfo
243TorqueStructTypedArrayElementsInfo
257 return TorqueStructTypedArrayElementsInfo{var_size_log2.value(),
268 [&](
ElementsKind el_kind,
int size,
int typed_array_function_index) {
293 Label detached_or_oob(
this), not_detached_nor_oob(
this);
296 Goto(¬_detached_nor_oob);
298 BIND(&detached_or_oob);
299 ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);
301 BIND(¬_detached_nor_oob);
367 ExternalReference::copy_fast_number_jsarray_elements_to_typed_array());
380 ExternalReference::copy_typed_array_elements_to_typed_array());
404 int32_t elements_kinds[] = {
405#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) TYPE##_ELEMENTS,
407#undef TYPED_ARRAY_CASE
410#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) Label if_##type##array(this);
413#undef TYPED_ARRAY_CASE
415 Label* elements_kind_labels[] = {
416#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) &if_##type##array,
418#undef TYPED_ARRAY_CASE
422 Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
425#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
426 BIND(&if_##type##array); \
428 case_function(TYPE##_ELEMENTS, sizeof(ctype), \
429 Context::TYPE##_ARRAY_FUN_INDEX); \
433#undef TYPED_ARRAY_CASE
435#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, NON_RAB_GSAB_TYPE) \
436 BIND(&if_##type##array); \
438 case_function(TYPE##_ELEMENTS, sizeof(ctype), \
439 Context::NON_RAB_GSAB_TYPE##_ARRAY_FUN_INDEX); \
443#undef TYPED_ARRAY_CASE
445 BIND(&if_unknown_type);
470 StoreJSTypedArrayBasePointer(holder,
base);
487 switch (elements_kind) {
489 case UINT8_CLAMPED_ELEMENTS:
491 case UINT16_ELEMENTS:
495 case UINT32_ELEMENTS:
500 case FLOAT16_ELEMENTS:
504 case FLOAT32_ELEMENTS:
508 case FLOAT64_ELEMENTS:
512 case BIGUINT64_ELEMENTS:
513 case BIGINT64_ELEMENTS:
522template <
typename TValue>
527 static_assert(std::is_same_v<TValue, Word32T> ||
528 std::is_same_v<TValue, Float16RawBitsT> ||
529 std::is_same_v<TValue, Float32T> ||
530 std::is_same_v<TValue, Float64T> ||
531 std::is_same_v<TValue, BigInt>,
532 "Only Word32T, Float16T, Float32T, Float64T or BigInt values "
538 typed_array, if_detached_or_out_of_bounds);
539 GotoIf(UintPtrGreaterThanOrEqual(index, length),
540 if_detached_or_out_of_bounds);
543 StoreElement(data_ptr, elements_kind, index, prepared_value);
549 Label* if_detached_or_out_of_bounds) {
550 switch (elements_kind) {
553 case UINT16_ELEMENTS:
555 case UINT32_ELEMENTS:
557 case UINT8_CLAMPED_ELEMENTS: {
559 value, elements_kind, context);
561 prepared_value, elements_kind,
562 if_detached_or_out_of_bounds);
565 case FLOAT16_ELEMENTS: {
567 value, elements_kind, context);
569 prepared_value, elements_kind,
570 if_detached_or_out_of_bounds);
573 case FLOAT32_ELEMENTS: {
575 value, elements_kind, context);
577 prepared_value, elements_kind,
578 if_detached_or_out_of_bounds);
581 case FLOAT64_ELEMENTS: {
583 value, elements_kind, context);
585 prepared_value, elements_kind,
586 if_detached_or_out_of_bounds);
589 case BIGINT64_ELEMENTS:
590 case BIGUINT64_ELEMENTS: {
592 value, elements_kind, context);
594 prepared_value, elements_kind,
595 if_detached_or_out_of_bounds);
605 auto receiver = Parameter<Object>(Descriptor::kReceiver);
606 Label if_receiverisheapobject(
this), return_undefined(
this);
607 Branch(TaggedIsSmi(
receiver), &return_undefined, &if_receiverisheapobject);
613 size_t const kTypedElementsKindCount =
616#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
617 Label return_##type##array(this); \
618 BIND(&return_##type##array); \
619 Return(StringConstant(#Type "Array"));
621#undef TYPED_ARRAY_CASE
624 Label* elements_kind_labels[kTypedElementsKindCount] = {
628#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) &return_##type##array,
631#undef TYPED_ARRAY_CASE
634 int32_t elements_kinds[kTypedElementsKindCount] = {
635#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
636 TYPE##_ELEMENTS - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND,
640#define RAB_GSAB_TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
641 TYPE##_ELEMENTS - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND,
644#undef TYPED_ARRAY_CASE
645#undef RAB_GSAB_TYPED_ARRAY_CASE
651 BIND(&if_receiverisheapobject);
654 Int32Sub(LoadElementsKind(receiver_heap_object),
656 Switch(elements_kind, &return_undefined, elements_kinds, elements_kind_labels,
657 kTypedElementsKindCount);
659 BIND(&return_undefined);
660 Return(UndefinedConstant());
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
#define CSA_DCHECK(csa,...)
#define RAB_GSAB_TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
#define TF_BUILTIN(Name, AssemblerBase)
TNode< BoolT > IsElementsKindInRange(TNode< Int32T > target_kind, ElementsKind lower_reference_kind, ElementsKind higher_reference_kind)
TNode< UintPtrT > LoadJSTypedArrayLengthAndCheckDetached(TNode< JSTypedArray > typed_array, Label *detached)
TNode< Float16RawBitsT > TruncateFloat64ToFloat16(TNode< Float64T > value)
void StoreSandboxedPointerToObject(TNode< HeapObject > object, int offset, TNode< RawPtrT > pointer)
TNode< Int32T > TruncateIntPtrToInt32(TNode< IntPtrT > value)
void ThrowIfNotInstanceType(TNode< Context > context, TNode< Object > value, InstanceType instance_type, char const *method_name)
TNode< RawPtrT > EmptyBackingStoreBufferConstant()
void ThrowTypeError(TNode< Context > context, MessageTemplate message, char const *arg0=nullptr, char const *arg1=nullptr)
TNode< HeapObject > Allocate(TNode< IntPtrT > size, AllocationFlags flags=AllocationFlag::kNone)
void ThrowIfArrayBufferViewBufferIsDetached(TNode< Context > context, TNode< JSArrayBufferView > array_buffer_view, const char *method_name)
void InitializeJSAPIObjectWithEmbedderSlotsCppHeapWrapperPtr(TNode< JSAPIObjectWithEmbedderSlots > holder)
TNode< RawPtrT > LoadJSTypedArrayDataPtr(TNode< JSTypedArray > typed_array)
void StoreElement(TNode< RawPtrT > elements, ElementsKind kind, TNode< TIndex > index, TNode< TValue > value)
void StoreJSTypedArrayExternalPointerPtr(TNode< JSTypedArray > holder, TNode< RawPtrT > value)
TNode< Int32T > LoadElementsKind(TNode< HeapObject > object)
TNode< Word32T > TruncateTaggedToWord32(TNode< Context > context, TNode< Object > value)
void StoreObjectFieldNoWriteBarrier(TNode< HeapObject > object, TNode< IntPtrT > offset, TNode< T > value)
TNode< NativeContext > LoadNativeContext(TNode< Context > context)
TNode< T > PrepareValueForWriteToTypedArray(TNode< Object > input, ElementsKind elements_kind, TNode< Context > context)
TNode< Float64T > LoadHeapNumberValue(TNode< HeapObject > object)
void StoreBoundedSizeToObject(TNode< HeapObject > object, int offset, TNode< UintPtrT > value)
TNode< Map > LoadMap(TNode< HeapObject > object)
TNode< Int32T > SmiToInt32(TNode< Smi > value)
TNode< Int32T > LoadMapElementsKind(TNode< Map > map)
void StoreObjectField(TNode< HeapObject > object, int offset, TNode< Smi > value)
void StoreMapNoWriteBarrier(TNode< HeapObject > object, RootIndex map_root_index)
static constexpr int kSizeWithEmbedderFields
static Address ExternalPointerCompensationForOnHeapArray(PtrComprCageBase cage_base)
static constexpr int kSizeWithEmbedderFields
static constexpr MachineType Pointer()
static constexpr MachineType AnyTagged()
static constexpr MachineType UintPtr()
static constexpr MachineType IntPtr()
void StoreJSTypedArrayElementFromPreparedValue(TNode< Context > context, TNode< JSTypedArray > typed_array, TNode< UintPtrT > index_node, TNode< TValue > value, ElementsKind elements_kind, Label *if_detached_or_out_of_bounds)
TNode< JSFunction > GetDefaultConstructor(TNode< Context > context, TNode< JSTypedArray > exemplar)
ElementsInfo GetTypedArrayElementsInfo(TNode< JSTypedArray > typed_array)
void SetJSTypedArrayOffHeapDataPtr(TNode< JSTypedArray > holder, TNode< RawPtrT > base, TNode< UintPtrT > offset)
void CallCMemset(TNode< RawPtrT > dest_ptr, TNode< IntPtrT > value, TNode< UintPtrT > length)
TNode< UintPtrT > ValidateTypedArrayAndGetLength(TNode< Context > context, TNode< Object > obj, const char *method_name)
void CallCRelaxedMemcpy(TNode< RawPtrT > dest_ptr, TNode< RawPtrT > src_ptr, TNode< UintPtrT > byte_length)
std::function< void(ElementsKind, int, int)> TypedArraySwitchCase
void CallCCopyTypedArrayElementsSlice(TNode< JSTypedArray > source, TNode< JSTypedArray > dest, TNode< UintPtrT > start, TNode< UintPtrT > end)
void CallCCopyFastNumberJSArrayElementsToTypedArray(TNode< Context > context, TNode< JSArray > source, TNode< JSTypedArray > dest, TNode< UintPtrT > source_length, TNode< UintPtrT > offset)
void CallCRelaxedMemmove(TNode< RawPtrT > dest_ptr, TNode< RawPtrT > src_ptr, TNode< UintPtrT > byte_length)
void CallCMemcpy(TNode< RawPtrT > dest_ptr, TNode< RawPtrT > src_ptr, TNode< UintPtrT > byte_length)
void CallCCopyTypedArrayElementsToTypedArray(TNode< JSTypedArray > source, TNode< JSTypedArray > dest, TNode< UintPtrT > source_length, TNode< UintPtrT > offset)
void StoreJSTypedArrayElementFromTagged(TNode< Context > context, TNode< JSTypedArray > typed_array, TNode< UintPtrT > index_node, TNode< Object > value, ElementsKind elements_kind, Label *if_detached_or_out_of_bounds)
void DispatchTypedArrayByElementsKind(TNode< Word32T > elements_kind, const TypedArraySwitchCase &case_function)
void StoreJSTypedArrayElementFromNumeric(TNode< Context > context, TNode< JSTypedArray > typed_array, TNode< UintPtrT > index_node, TNode< Numeric > value, ElementsKind elements_kind)
TNode< JSArrayBuffer > AllocateEmptyOnHeapBuffer(TNode< Context > context)
void CallCMemmove(TNode< RawPtrT > dest_ptr, TNode< RawPtrT > src_ptr, TNode< UintPtrT > byte_length)
TNode< IntPtrT > GetTypedArrayElementSize(TNode< Int32T > elements_kind)
void SetJSTypedArrayOnHeapDataPtr(TNode< JSTypedArray > holder, TNode< ByteArray > base, TNode< UintPtrT > offset)
TNode< JSTypedArray > ValidateTypedArray(TNode< Context > context, TNode< Object > obj, const char *method_name)
TNode< BoolT > IsUint8ElementsKind(TNode< Int32T > kind)
TNode< BoolT > IsBigInt64ElementsKind(TNode< Int32T > kind)
void SetupTypedArrayEmbedderFields(TNode< JSTypedArray > holder)
TNode< IntPtrT > IntPtrAdd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< Int32T > Signed(TNode< Word32T > x)
TNode< IntPtrT > IntPtrConstant(intptr_t value)
TNode< UintPtrT > ChangeUint32ToWord(TNode< Word32T > value)
TNode< T > UncheckedCast(Node *value)
Isolate * isolate() const
TNode< Uint32T > Unsigned(TNode< Word32T > x)
TNode< T > ReinterpretCast(Node *value)
TNode< IntPtrT > BitcastTaggedToWord(TNode< Smi > node)
TNode< Smi > SmiConstant(Tagged< Smi > value)
void GotoIf(TNode< IntegralT > condition, Label *true_label, GotoHint goto_hint=GotoHint::kNone)
TNode< Int32T > Word32Or(TNode< Int32T > left, TNode< Int32T > right)
void Switch(Node *index, Label *default_label, const int32_t *case_values, Label **case_labels, size_t case_count)
TNode< ExternalPointerHandleT > ExternalPointerHandleNullConstant()
TNode< IntPtrT > IntPtrSub(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< ExternalReference > ExternalConstant(ExternalReference address)
TNode< Int32T > Int32Constant(int32_t value)
Node * CallCFunction(Node *function, std::optional< MachineType > return_type, CArgs... cargs)
TNode< BoolT > Word32Equal(TNode< Word32T > left, TNode< Word32T > right)
TNode< UintPtrT > UintPtrConstant(uintptr_t value)
TNode< RawPtrT > RawPtrAdd(TNode< RawPtrT > left, TNode< IntPtrT > right)
TNode< UintPtrT > UintPtrAdd(TNode< UintPtrT > left, TNode< UintPtrT > right)
#define COMPRESS_POINTERS_BOOL
#define RAB_GSAB_TYPED_ARRAYS_WITH_NON_RAB_GSAB_ELEMENTS_KIND(V)
#define RAB_GSAB_TYPED_ARRAYS(V)
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
ZoneVector< RpoNumber > & result
constexpr int kTaggedSize
@ FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND
@ LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND
@ FIRST_RAB_GSAB_FIXED_TYPED_ARRAY_ELEMENTS_KIND
@ LAST_RAB_GSAB_FIXED_TYPED_ARRAY_ELEMENTS_KIND
constexpr int ElementsKindToShiftSize(ElementsKind elements_kind)
void relaxed_memcpy(volatile base::Atomic8 *dest, volatile const base::Atomic8 *src, size_t n)
!IsContextMap !IsContextMap native_context
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define OFFSET_OF_DATA_START(Type)