Commit f0234f75 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[typedarray] Change JSTypedArray::length field to uintptr_t.

This is a mostly mechanical change that updates the JSTypedArray::length
field to have uintptr_t storage. It doesn't change the allowed ranges
for this field yet, that will be done separately later on.

Bug: v8:4153, v8:7881
Change-Id: Ia4b6f5455bd97b82a4b980d77bda0b09cfa845f5
Doc: http://doc/1Z-wM2qwvAuxH46e9ivtkYvKzzwYZg8ymm0x0wJaomow
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1607647
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61485}
parent f0e054c2
...@@ -624,7 +624,7 @@ namespace array_join { ...@@ -624,7 +624,7 @@ namespace array_join {
// the algorithm. // the algorithm.
const typedArray: JSTypedArray = typed_array::ValidateTypedArray( const typedArray: JSTypedArray = typed_array::ValidateTypedArray(
context, receiver, '%TypedArray%.prototype.join'); context, receiver, '%TypedArray%.prototype.join');
const length: Smi = typedArray.length; const length = Convert<Number>(typedArray.length);
return CycleProtectedArrayJoin<JSTypedArray>( return CycleProtectedArrayJoin<JSTypedArray>(
false, typedArray, length, separator, Undefined, Undefined); false, typedArray, length, separator, Undefined, Undefined);
...@@ -640,7 +640,7 @@ namespace array_join { ...@@ -640,7 +640,7 @@ namespace array_join {
// the algorithm. // the algorithm.
const typedArray: JSTypedArray = typed_array::ValidateTypedArray( const typedArray: JSTypedArray = typed_array::ValidateTypedArray(
context, receiver, '%TypedArray%.prototype.toLocaleString'); context, receiver, '%TypedArray%.prototype.toLocaleString');
const length: Smi = typedArray.length; const length = Convert<Number>(typedArray.length);
return CycleProtectedArrayJoin<JSTypedArray>( return CycleProtectedArrayJoin<JSTypedArray>(
true, typedArray, length, ',', locales, options); true, typedArray, length, ',', locales, options);
......
...@@ -526,7 +526,7 @@ extern class JSTypedArray extends JSArrayBufferView { ...@@ -526,7 +526,7 @@ extern class JSTypedArray extends JSArrayBufferView {
}; };
} }
length: Smi; length: uintptr;
} }
@noVerifier @noVerifier
......
...@@ -42,7 +42,8 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler( ...@@ -42,7 +42,8 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler(
context(), method_name, original_array, length); context(), method_name, original_array, length);
// In the Spec and our current implementation, the length check is already // In the Spec and our current implementation, the length check is already
// performed in TypedArraySpeciesCreate. // performed in TypedArraySpeciesCreate.
CSA_ASSERT(this, SmiLessThanOrEqual(CAST(len_), LoadJSTypedArrayLength(a))); CSA_ASSERT(this, UintPtrLessThanOrEqual(SmiUntag(CAST(len_)),
LoadJSTypedArrayLength(a)));
fast_typed_array_target_ = fast_typed_array_target_ =
Word32Equal(LoadInstanceType(LoadElements(original_array)), Word32Equal(LoadInstanceType(LoadElements(original_array)),
LoadInstanceType(LoadElements(a))); LoadInstanceType(LoadElements(a)));
...@@ -159,7 +160,7 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler( ...@@ -159,7 +160,7 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler(
LoadJSArrayBufferViewBuffer(typed_array); LoadJSArrayBufferViewBuffer(typed_array);
ThrowIfArrayBufferIsDetached(context_, array_buffer, name_); ThrowIfArrayBufferIsDetached(context_, array_buffer, name_);
len_ = LoadJSTypedArrayLength(typed_array); len_ = ChangeUintPtrToTagged(LoadJSTypedArrayLength(typed_array));
Label throw_not_callable(this, Label::kDeferred); Label throw_not_callable(this, Label::kDeferred);
Label distinguish_types(this); Label distinguish_types(this);
...@@ -1641,6 +1642,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { ...@@ -1641,6 +1642,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
BIND(&if_typedarray); BIND(&if_typedarray);
{ {
// If {array} is a JSTypedArray, the {index} must always be a Smi. // If {array} is a JSTypedArray, the {index} must always be a Smi.
// TODO(v8:4153): Update this and the relevant TurboFan code.
CSA_ASSERT(this, TaggedIsSmi(index)); CSA_ASSERT(this, TaggedIsSmi(index));
// Check that the {array}s buffer wasn't detached. // Check that the {array}s buffer wasn't detached.
...@@ -1650,8 +1652,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { ...@@ -1650,8 +1652,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
// [[ArrayIteratorNextIndex]] anymore, since a JSTypedArray's // [[ArrayIteratorNextIndex]] anymore, since a JSTypedArray's
// length cannot change anymore, so this {iterator} will never // length cannot change anymore, so this {iterator} will never
// produce values again anyways. // produce values again anyways.
TNode<Smi> length = LoadJSTypedArrayLength(CAST(array)); TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(array));
GotoIfNot(SmiBelow(CAST(index), length), &allocate_iterator_result); GotoIfNot(UintPtrLessThan(SmiUntag(CAST(index)), length),
&allocate_iterator_result);
StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset, StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
SmiInc(CAST(index))); SmiInc(CAST(index)));
......
...@@ -116,13 +116,14 @@ Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32( ...@@ -116,13 +116,14 @@ Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
} }
void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array, void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array,
Node* index_word, Node* index,
Node* context) { Node* context) {
// Check if the index is in bounds. If not, throw RangeError. // Check if the index is in bounds. If not, throw RangeError.
Label check_passed(this); Label check_passed(this);
Node* array_length_word32 = TNode<UintPtrT> array_length = LoadJSTypedArrayLength(CAST(array));
TruncateTaggedToWord32(context, LoadJSTypedArrayLength(CAST(array))); // TODO(v8:4153): Use UintPtr for the {index} as well.
GotoIf(Uint32LessThan(index_word, array_length_word32), &check_passed); GotoIf(UintPtrLessThan(ChangeUint32ToWord(index), array_length),
&check_passed);
ThrowRangeError(context, MessageTemplate::kInvalidAtomicAccessIndex); ThrowRangeError(context, MessageTemplate::kInvalidAtomicAccessIndex);
...@@ -136,10 +137,8 @@ void SharedArrayBufferBuiltinsAssembler::DebugSanityCheckAtomicIndex( ...@@ -136,10 +137,8 @@ void SharedArrayBufferBuiltinsAssembler::DebugSanityCheckAtomicIndex(
// ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be // ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be
// detached and the TypedArray length can't change either, so skipping this // detached and the TypedArray length can't change either, so skipping this
// check in Release mode is safe. // check in Release mode is safe.
CSA_ASSERT(this, CSA_ASSERT(this, UintPtrLessThan(ChangeUint32ToWord(index_word),
Uint32LessThan(index_word, LoadJSTypedArrayLength(CAST(array))));
TruncateTaggedToWord32(
context, LoadJSTypedArrayLength(CAST(array)))));
} }
#endif #endif
......
...@@ -51,11 +51,11 @@ TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType( ...@@ -51,11 +51,11 @@ TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
// - Set the byte_length. // - Set the byte_length.
// - Set EmbedderFields to 0. // - Set EmbedderFields to 0.
void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder, void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
TNode<Smi> length, TNode<UintPtrT> length,
TNode<UintPtrT> byte_offset, TNode<UintPtrT> byte_offset,
TNode<UintPtrT> byte_length) { TNode<UintPtrT> byte_length) {
CSA_ASSERT(this, TaggedIsPositiveSmi(length)); StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kLengthOffset, length,
StoreObjectField(holder, JSTypedArray::kLengthOffset, length); MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset, StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
byte_offset, byte_offset,
MachineType::PointerRepresentation()); MachineType::PointerRepresentation());
...@@ -238,10 +238,10 @@ TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) { ...@@ -238,10 +238,10 @@ TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) {
// Default to zero if the {receiver}s buffer was detached. // Default to zero if the {receiver}s buffer was detached.
TNode<JSArrayBuffer> receiver_buffer = TNode<JSArrayBuffer> receiver_buffer =
LoadJSArrayBufferViewBuffer(CAST(receiver)); LoadJSArrayBufferViewBuffer(CAST(receiver));
TNode<Smi> length = Select<Smi>( TNode<UintPtrT> length = Select<UintPtrT>(
IsDetachedBuffer(receiver_buffer), [=] { return SmiConstant(0); }, IsDetachedBuffer(receiver_buffer), [=] { return UintPtrConstant(0); },
[=] { return LoadJSTypedArrayLength(CAST(receiver)); }); [=] { return LoadJSTypedArrayLength(CAST(receiver)); });
Return(length); Return(ChangeUintPtrToTagged(length));
} }
TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind( TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
...@@ -328,8 +328,9 @@ void TypedArrayBuiltinsAssembler::ThrowIfLengthLessThan( ...@@ -328,8 +328,9 @@ void TypedArrayBuiltinsAssembler::ThrowIfLengthLessThan(
TNode<Smi> min_length) { TNode<Smi> min_length) {
// If typed_array.[[ArrayLength]] < min_length, throw a TypeError exception. // If typed_array.[[ArrayLength]] < min_length, throw a TypeError exception.
Label if_length_is_not_short(this); Label if_length_is_not_short(this);
TNode<Smi> new_length = LoadJSTypedArrayLength(typed_array); TNode<UintPtrT> new_length = LoadJSTypedArrayLength(typed_array);
GotoIfNot(SmiLessThan(new_length, min_length), &if_length_is_not_short); GotoIfNot(UintPtrLessThan(new_length, SmiUntag(min_length)),
&if_length_is_not_short);
ThrowTypeError(context, MessageTemplate::kTypedArrayTooShort); ThrowTypeError(context, MessageTemplate::kTypedArrayTooShort);
BIND(&if_length_is_not_short); BIND(&if_length_is_not_short);
...@@ -383,8 +384,8 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource( ...@@ -383,8 +384,8 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
// Check for possible range errors. // Check for possible range errors.
TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source)); TNode<IntPtrT> source_length = Signed(LoadJSTypedArrayLength(source));
TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target)); TNode<IntPtrT> target_length = Signed(LoadJSTypedArrayLength(target));
TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset); TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset);
GotoIf(IntPtrGreaterThan(required_target_length, target_length), GotoIf(IntPtrGreaterThan(required_target_length, target_length),
...@@ -434,7 +435,7 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource( ...@@ -434,7 +435,7 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
IsBigInt64ElementsKind(target_el_kind)), IsBigInt64ElementsKind(target_el_kind)),
&exception); &exception);
TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source)); TNode<IntPtrT> source_length = Signed(LoadJSTypedArrayLength(source));
CallCCopyTypedArrayElementsToTypedArray(source, target, source_length, CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
offset); offset);
Goto(&out); Goto(&out);
...@@ -455,7 +456,7 @@ void TypedArrayBuiltinsAssembler::SetJSArraySource( ...@@ -455,7 +456,7 @@ void TypedArrayBuiltinsAssembler::SetJSArraySource(
IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue))); IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source)); TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source));
TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target)); TNode<IntPtrT> target_length = Signed(LoadJSTypedArrayLength(target));
// Maybe out of bounds? // Maybe out of bounds?
GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length), GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length),
...@@ -956,7 +957,8 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { ...@@ -956,7 +957,8 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
// Source is a TypedArray with unmodified iterator behavior. Use the // Source is a TypedArray with unmodified iterator behavior. Use the
// source object directly, taking advantage of the special-case code in // source object directly, taking advantage of the special-case code in
// TypedArrayCopyElements // TypedArrayCopyElements
final_length = LoadJSTypedArrayLength(CAST(source)); // TODO(v8:4153): This needs to be handle to huge TypedArrays.
final_length = SmiTag(Signed(LoadJSTypedArrayLength(CAST(source))));
final_source = source; final_source = source;
Goto(&create_typed_array); Goto(&create_typed_array);
} }
......
...@@ -29,7 +29,7 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { ...@@ -29,7 +29,7 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
const char* method_name, const char* method_name,
IterationKind iteration_kind); IterationKind iteration_kind);
void SetupTypedArray(TNode<JSTypedArray> holder, TNode<Smi> length, void SetupTypedArray(TNode<JSTypedArray> holder, TNode<UintPtrT> length,
TNode<UintPtrT> byte_offset, TNode<UintPtrT> byte_offset,
TNode<UintPtrT> byte_length); TNode<UintPtrT> byte_length);
void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer, void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer,
......
...@@ -19,7 +19,7 @@ namespace typed_array_createtypedarray { ...@@ -19,7 +19,7 @@ namespace typed_array_createtypedarray {
extern macro TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(JSArrayBuffer): extern macro TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(JSArrayBuffer):
bool; bool;
extern macro TypedArrayBuiltinsAssembler::SetupTypedArray( extern macro TypedArrayBuiltinsAssembler::SetupTypedArray(
JSTypedArray, Smi, uintptr, uintptr): void; JSTypedArray, uintptr, uintptr, uintptr): void;
extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)( extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)(
Map, String): never; Map, String): never;
...@@ -77,7 +77,8 @@ namespace typed_array_createtypedarray { ...@@ -77,7 +77,8 @@ namespace typed_array_createtypedarray {
} }
const byteOffset: uintptr = 0; const byteOffset: uintptr = 0;
SetupTypedArray(typedArray, length, byteOffset, byteLength); SetupTypedArray(
typedArray, Convert<uintptr>(length), byteOffset, byteLength);
return byteLength; return byteLength;
} }
...@@ -156,7 +157,9 @@ namespace typed_array_createtypedarray { ...@@ -156,7 +157,9 @@ namespace typed_array_createtypedarray {
let bufferConstructor: JSReceiver = GetArrayBufferFunction(); let bufferConstructor: JSReceiver = GetArrayBufferFunction();
const srcBuffer: JSArrayBuffer = srcTypedArray.buffer; const srcBuffer: JSArrayBuffer = srcTypedArray.buffer;
// TODO(petermarshall): Throw on detached typedArray. // TODO(petermarshall): Throw on detached typedArray.
let length: Smi = IsDetachedBuffer(srcBuffer) ? 0 : srcTypedArray.length; // TODO(v8:4156): Update this to support huge TypedArrays.
let length =
IsDetachedBuffer(srcBuffer) ? 0 : Convert<Number>(srcTypedArray.length);
// The spec requires that constructing a typed array using a SAB-backed // The spec requires that constructing a typed array using a SAB-backed
// typed array use the ArrayBuffer constructor, not the species constructor. // typed array use the ArrayBuffer constructor, not the species constructor.
...@@ -235,7 +238,8 @@ namespace typed_array_createtypedarray { ...@@ -235,7 +238,8 @@ namespace typed_array_createtypedarray {
goto IfInvalidLength; goto IfInvalidLength;
} }
SetupTypedArray(typedArray, newLength, offset, newByteLength); SetupTypedArray(
typedArray, Convert<uintptr>(newLength), offset, newByteLength);
typedArray.AttachOffHeapBuffer(buffer, elementsInfo.map, offset); typedArray.AttachOffHeapBuffer(buffer, elementsInfo.map, offset);
} }
label IfInvalidAlignment(problemString: String) deferred { label IfInvalidAlignment(problemString: String) deferred {
...@@ -291,6 +295,7 @@ namespace typed_array_createtypedarray { ...@@ -291,6 +295,7 @@ namespace typed_array_createtypedarray {
// the object even though that doesn't make any sense for these fields. // the object even though that doesn't make any sense for these fields.
array.byte_offset = 0; array.byte_offset = 0;
array.byte_length = 0; array.byte_length = 0;
array.length = 0;
// 5. Let elementSize be the Number value of the Element Size value in Table // 5. Let elementSize be the Number value of the Element Size value in Table
// 56 for constructorName. // 56 for constructorName.
...@@ -372,12 +377,11 @@ namespace typed_array_createtypedarray { ...@@ -372,12 +377,11 @@ namespace typed_array_createtypedarray {
transitioning macro TypedArraySpeciesCreateByLength(implicit context: transitioning macro TypedArraySpeciesCreateByLength(implicit context:
Context)( Context)(
methodName: constexpr string, exemplar: JSTypedArray, methodName: constexpr string, exemplar: JSTypedArray,
length: Smi): JSTypedArray { length: PositiveSmi): JSTypedArray {
assert(Is<PositiveSmi>(length));
const numArgs: constexpr int31 = 1; const numArgs: constexpr int31 = 1;
const typedArray: JSTypedArray = TypedArraySpeciesCreate( const typedArray: JSTypedArray = TypedArraySpeciesCreate(
methodName, numArgs, exemplar, length, Undefined, Undefined); methodName, numArgs, exemplar, length, Undefined, Undefined);
if (typedArray.length < length) deferred { if (typedArray.length < Convert<uintptr>(length)) deferred {
ThrowTypeError(kTypedArrayTooShort); ThrowTypeError(kTypedArrayTooShort);
} }
......
...@@ -11,7 +11,9 @@ namespace typed_array_every { ...@@ -11,7 +11,9 @@ namespace typed_array_every {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
thisArg: Object): Boolean { thisArg: Object): Boolean {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(witness.Get().length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
witness.Recheck() otherwise break; witness.Recheck() otherwise break;
......
...@@ -21,7 +21,8 @@ namespace typed_array_filter { ...@@ -21,7 +21,8 @@ namespace typed_array_filter {
const src = typed_array::EnsureAttached(array) otherwise IsDetached; const src = typed_array::EnsureAttached(array) otherwise IsDetached;
// 3. Let len be O.[[ArrayLength]]. // 3. Let len be O.[[ArrayLength]].
const len: Smi = src.length; // TODO(v8:4153): Support huge TypedArrays here.
const len = Cast<Smi>(Convert<Number>(src.length)) otherwise unreachable;
// 4. If IsCallable(callbackfn) is false, throw a TypeError exception. // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
const callbackfn = Cast<Callable>(arguments[0]) const callbackfn = Cast<Callable>(arguments[0])
...@@ -58,7 +59,7 @@ namespace typed_array_filter { ...@@ -58,7 +59,7 @@ namespace typed_array_filter {
} }
// 10. Let A be ? TypedArraySpeciesCreate(O, captured). // 10. Let A be ? TypedArraySpeciesCreate(O, captured).
const lengthSmi: Smi = Convert<Smi>(kept.length); const lengthSmi = Convert<PositiveSmi>(kept.length);
const typedArray: JSTypedArray = const typedArray: JSTypedArray =
typed_array_createtypedarray::TypedArraySpeciesCreateByLength( typed_array_createtypedarray::TypedArraySpeciesCreateByLength(
kBuiltinName, array, lengthSmi); kBuiltinName, array, lengthSmi);
......
...@@ -11,7 +11,9 @@ namespace typed_array_find { ...@@ -11,7 +11,9 @@ namespace typed_array_find {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
thisArg: Object): Object { thisArg: Object): Object {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(witness.Get().length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
witness.Recheck() otherwise break; witness.Recheck() otherwise break;
......
...@@ -11,7 +11,9 @@ namespace typed_array_findindex { ...@@ -11,7 +11,9 @@ namespace typed_array_findindex {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
thisArg: Object): Number { thisArg: Object): Number {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(witness.Get().length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
witness.Recheck() otherwise break; witness.Recheck() otherwise break;
......
...@@ -11,7 +11,9 @@ namespace typed_array_foreach { ...@@ -11,7 +11,9 @@ namespace typed_array_foreach {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
thisArg: Object): Object { thisArg: Object): Object {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(array.length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
witness.Recheck() otherwise break; witness.Recheck() otherwise break;
......
...@@ -11,7 +11,9 @@ namespace typed_array_reduce { ...@@ -11,7 +11,9 @@ namespace typed_array_reduce {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
initialValue: Object): Object { initialValue: Object): Object {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(witness.Get().length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
let accumulator = initialValue; let accumulator = initialValue;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
......
...@@ -11,7 +11,9 @@ namespace typed_array_reduceright { ...@@ -11,7 +11,9 @@ namespace typed_array_reduceright {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
initialValue: Object): Object { initialValue: Object): Object {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(array.length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
let accumulator = initialValue; let accumulator = initialValue;
for (let k: Smi = length - 1; k >= 0; k--) { for (let k: Smi = length - 1; k >= 0; k--) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
......
...@@ -11,7 +11,9 @@ namespace typed_array_some { ...@@ -11,7 +11,9 @@ namespace typed_array_some {
array: typed_array::AttachedJSTypedArray, callbackfn: Callable, array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
thisArg: Object): Boolean { thisArg: Object): Boolean {
let witness = typed_array::NewAttachedJSTypedArrayWitness(array); let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
const length: Smi = Convert<Smi>(witness.Get().length); // TODO(v8:4153): Support huge TypedArrays here.
const length =
Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
for (let k: Smi = 0; k < length; k++) { for (let k: Smi = 0; k < length; k++) {
// BUG(4895): We should throw on detached buffers rather than simply exit. // BUG(4895): We should throw on detached buffers rather than simply exit.
witness.Recheck() otherwise break; witness.Recheck() otherwise break;
......
...@@ -298,7 +298,8 @@ namespace typed_array { ...@@ -298,7 +298,8 @@ namespace typed_array {
} }
// 4. Let len be obj.[[ArrayLength]]. // 4. Let len be obj.[[ArrayLength]].
const len: Smi = array.length; // TODO(v8:4153): Support huge TypedArrays here.
const len = Cast<Smi>(Convert<Number>(array.length)) otherwise unreachable;
// Arrays of length 1 or less are considered sorted. // Arrays of length 1 or less are considered sorted.
if (len < 2) return array; if (len < 2) return array;
......
...@@ -9658,7 +9658,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, ...@@ -9658,7 +9658,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
GotoIf(IsDetachedBuffer(buffer), if_absent); GotoIf(IsDetachedBuffer(buffer), if_absent);
Node* length = SmiUntag(LoadJSTypedArrayLength(CAST(object))); TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
Branch(UintPtrLessThan(intptr_index, length), if_found, if_absent); Branch(UintPtrLessThan(intptr_index, length), if_found, if_absent);
} }
BIND(&if_oob); BIND(&if_oob);
...@@ -10553,8 +10553,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -10553,8 +10553,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
GotoIf(IsDetachedBuffer(buffer), bailout); GotoIf(IsDetachedBuffer(buffer), bailout);
// Bounds check. // Bounds check.
Node* length = TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
TaggedToParameter(LoadJSTypedArrayLength(CAST(object)), parameter_mode);
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
// Skip the store if we write beyond the length or // Skip the store if we write beyond the length or
...@@ -13165,9 +13164,9 @@ TNode<UintPtrT> CodeStubAssembler::LoadJSArrayBufferViewByteOffset( ...@@ -13165,9 +13164,9 @@ TNode<UintPtrT> CodeStubAssembler::LoadJSArrayBufferViewByteOffset(
JSArrayBufferView::kByteOffsetOffset); JSArrayBufferView::kByteOffsetOffset);
} }
TNode<Smi> CodeStubAssembler::LoadJSTypedArrayLength( TNode<UintPtrT> CodeStubAssembler::LoadJSTypedArrayLength(
TNode<JSTypedArray> typed_array) { TNode<JSTypedArray> typed_array) {
return LoadObjectField<Smi>(typed_array, JSTypedArray::kLengthOffset); return LoadObjectField<UintPtrT>(typed_array, JSTypedArray::kLengthOffset);
} }
CodeStubArguments::CodeStubArguments( CodeStubArguments::CodeStubArguments(
......
...@@ -3238,7 +3238,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3238,7 +3238,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
const char* method_name); const char* method_name);
// JSTypedArray helpers // JSTypedArray helpers
TNode<Smi> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array); TNode<UintPtrT> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array);
TNode<IntPtrT> ElementOffsetFromIndex(Node* index, ElementsKind kind, TNode<IntPtrT> ElementOffsetFromIndex(Node* index, ElementsKind kind,
ParameterMode mode, int base_size = 0); ParameterMode mode, int base_size = 0);
......
...@@ -422,7 +422,7 @@ FieldAccess AccessBuilder::ForJSTypedArrayLength() { ...@@ -422,7 +422,7 @@ FieldAccess AccessBuilder::ForJSTypedArrayLength() {
MaybeHandle<Name>(), MaybeHandle<Name>(),
MaybeHandle<Map>(), MaybeHandle<Map>(),
TypeCache::Get()->kJSTypedArrayLengthType, TypeCache::Get()->kJSTypedArrayLengthType,
MachineType::TypeCompressedTaggedSigned(), MachineType::UintPtr(),
kNoWriteBarrier}; kNoWriteBarrier};
return access; return access;
} }
......
...@@ -113,9 +113,10 @@ class V8_EXPORT_PRIVATE TypeCache final { ...@@ -113,9 +113,10 @@ class V8_EXPORT_PRIVATE TypeCache final {
// JSArrayBuffer::byte_length above. // JSArrayBuffer::byte_length above.
Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType; Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType;
// The JSTypedArray::length property always contains a tagged number in the // The JSTypedArray::length property always contains an untagged number in
// range [0, kMaxSmiValue]. // the range [0, kMaxSmiValue].
Type const kJSTypedArrayLengthType = Type::UnsignedSmall(); Type const kJSTypedArrayLengthType =
CreateRange(0.0, JSTypedArray::kMaxLength);
// The String::length property always contains a smi in the range // The String::length property always contains a smi in the range
// [0, String::kMaxLength]. // [0, String::kMaxLength].
......
...@@ -1979,7 +1979,7 @@ void AccessorAssembler::EmitElementLoad( ...@@ -1979,7 +1979,7 @@ void AccessorAssembler::EmitElementLoad(
GotoIf(IsDetachedBuffer(buffer), miss); GotoIf(IsDetachedBuffer(buffer), miss);
// Bounds check. // Bounds check.
Node* length = SmiUntag(LoadJSTypedArrayLength(CAST(object))); TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
GotoIfNot(UintPtrLessThan(intptr_index, length), out_of_bounds); GotoIfNot(UintPtrLessThan(intptr_index, length), out_of_bounds);
if (access_mode == LoadAccessMode::kHas) { if (access_mode == LoadAccessMode::kHas) {
exit_point->Return(TrueConstant()); exit_point->Return(TrueConstant());
......
...@@ -1546,7 +1546,7 @@ void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) { ...@@ -1546,7 +1546,7 @@ void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) {
void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) { void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) {
ClassVerifiersFromDSL::JSTypedArrayVerify(*this, isolate); ClassVerifiersFromDSL::JSTypedArrayVerify(*this, isolate);
VerifyPointer(isolate, elements()); CHECK_LE(length(), JSTypedArray::kMaxLength);
} }
void JSDataView::JSDataViewVerify(Isolate* isolate) { void JSDataView::JSDataViewVerify(Isolate* isolate) {
......
...@@ -133,16 +133,11 @@ bool JSArrayBufferView::WasDetached() const { ...@@ -133,16 +133,11 @@ bool JSArrayBufferView::WasDetached() const {
} }
size_t JSTypedArray::length() const { size_t JSTypedArray::length() const {
// TODO(bmeurer, v8:4153): Change this to size_t later. return READ_UINTPTR_FIELD(*this, kLengthOffset);
int length = Smi::cast(raw_length())->value();
DCHECK_LE(0, length);
return length;
} }
void JSTypedArray::set_length(size_t value) { void JSTypedArray::set_length(size_t value) {
// TODO(bmeurer, v8:4153): Change this to size_t later. WRITE_UINTPTR_FIELD(*this, kLengthOffset, value);
CHECK_LE(value, Smi::kMaxValue);
set_raw_length(Smi::FromInt(static_cast<int>(value)), SKIP_WRITE_BARRIER);
} }
bool JSTypedArray::is_on_heap() const { bool JSTypedArray::is_on_heap() const {
...@@ -175,8 +170,6 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate, ...@@ -175,8 +170,6 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
return array; return array;
} }
ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
void* JSDataView::data_pointer() const { void* JSDataView::data_pointer() const {
intptr_t ptr = READ_INTPTR_FIELD(*this, kDataPointerOffset); intptr_t ptr = READ_INTPTR_FIELD(*this, kDataPointerOffset);
return reinterpret_cast<void*>(ptr); return reinterpret_cast<void*>(ptr);
......
...@@ -177,6 +177,9 @@ class JSArrayBufferView : public JSObject { ...@@ -177,6 +177,9 @@ class JSArrayBufferView : public JSObject {
class JSTypedArray : public JSArrayBufferView { class JSTypedArray : public JSArrayBufferView {
public: public:
// TODO(v8:4153): This should become JSArrayBuffer::kMaxByteLength eventually.
static constexpr size_t kMaxLength = kSmiMaxValue;
// [length]: length of typed array in elements. // [length]: length of typed array in elements.
DECL_PRIMITIVE_ACCESSORS(length, size_t) DECL_PRIMITIVE_ACCESSORS(length, size_t)
...@@ -206,7 +209,7 @@ class JSTypedArray : public JSArrayBufferView { ...@@ -206,7 +209,7 @@ class JSTypedArray : public JSArrayBufferView {
// Layout description. // Layout description.
#define JS_TYPED_ARRAY_FIELDS(V) \ #define JS_TYPED_ARRAY_FIELDS(V) \
/* Raw data fields. */ \ /* Raw data fields. */ \
V(kLengthOffset, kTaggedSize) \ V(kLengthOffset, kUIntptrSize) \
/* Header size. */ \ /* Header size. */ \
V(kHeaderSize, 0) V(kHeaderSize, 0)
...@@ -224,8 +227,6 @@ class JSTypedArray : public JSArrayBufferView { ...@@ -224,8 +227,6 @@ class JSTypedArray : public JSArrayBufferView {
static Handle<JSArrayBuffer> MaterializeArrayBuffer( static Handle<JSArrayBuffer> MaterializeArrayBuffer(
Handle<JSTypedArray> typed_array); Handle<JSTypedArray> typed_array);
DECL_ACCESSORS(raw_length, Object)
OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView); OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment