aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-typed-array-gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/builtins-typed-array-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-typed-array-gen.cc184
1 files changed, 95 insertions, 89 deletions
diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.cc b/deps/v8/src/builtins/builtins-typed-array-gen.cc
index c7c416d924..99979b0283 100644
--- a/deps/v8/src/builtins/builtins-typed-array-gen.cc
+++ b/deps/v8/src/builtins/builtins-typed-array-gen.cc
@@ -5,7 +5,6 @@
#include "src/builtins/builtins-typed-array-gen.h"
#include "src/builtins/builtins-constructor-gen.h"
-#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/builtins/growable-fixed-array-gen.h"
@@ -33,12 +32,12 @@ TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
TVARIABLE(Map, var_typed_map);
TNode<Map> array_map = LoadMap(array);
TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);
+ ReadOnlyRoots roots(isolate());
DispatchTypedArrayByElementsKind(
elements_kind,
[&](ElementsKind kind, int size, int typed_array_fun_index) {
- Handle<Map> map(isolate()->heap()->MapForFixedTypedArray(kind),
- isolate());
+ Handle<Map> map(roots.MapForFixedTypedArray(kind), isolate());
var_typed_map = HeapConstant(map);
});
@@ -65,11 +64,15 @@ TNode<UintPtrT> TypedArrayBuiltinsAssembler::CalculateExternalPointer(
// - Set EmbedderFields to 0.
void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
TNode<Smi> length,
- TNode<Number> byte_offset,
- TNode<Number> byte_length) {
+ TNode<UintPtrT> byte_offset,
+ TNode<UintPtrT> byte_length) {
StoreObjectField(holder, JSTypedArray::kLengthOffset, length);
- StoreObjectField(holder, JSArrayBufferView::kByteOffsetOffset, byte_offset);
- StoreObjectField(holder, JSArrayBufferView::kByteLengthOffset, byte_length);
+ StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
+ byte_offset,
+ MachineType::PointerRepresentation());
+ StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteLengthOffset,
+ byte_length,
+ MachineType::PointerRepresentation());
for (int offset = JSTypedArray::kSize;
offset < JSTypedArray::kSizeWithEmbedderFields; offset += kPointerSize) {
StoreObjectField(holder, offset, SmiConstant(0));
@@ -114,7 +117,8 @@ TF_BUILTIN(TypedArrayInitializeWithBuffer, TypedArrayBuiltinsAssembler) {
// SmiMul returns a heap number in case of Smi overflow.
TNode<Number> byte_length = SmiMul(length, element_size);
- SetupTypedArray(holder, length, byte_offset, byte_length);
+ SetupTypedArray(holder, length, ChangeNonnegativeNumberToUintPtr(byte_offset),
+ ChangeNonnegativeNumberToUintPtr(byte_length));
AttachBuffer(holder, buffer, fixed_typed_map, length, byte_offset);
Return(UndefinedConstant());
}
@@ -146,8 +150,6 @@ TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
// SmiMul returns a heap number in case of Smi overflow.
TNode<Number> byte_length = SmiMul(length, element_size);
- SetupTypedArray(holder, length, byte_offset, byte_length);
-
TNode<Map> fixed_typed_map = LoadMapForType(holder);
// If target and new_target for the buffer differ, allocate off-heap.
@@ -173,7 +175,7 @@ TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
Node* native_context = LoadNativeContext(context);
Node* map =
LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX);
- Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
+ Node* empty_fixed_array = LoadRoot(RootIndex::kEmptyFixedArray);
Node* buffer = Allocate(JSArrayBuffer::kSizeWithEmbedderFields);
StoreMapNoWriteBarrier(buffer, map);
@@ -189,14 +191,15 @@ TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
// - Set all embedder fields to Smi(0).
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldSlot,
SmiConstant(0));
- int32_t bitfield_value = (1 << JSArrayBuffer::IsExternal::kShift) |
- (1 << JSArrayBuffer::IsNeuterable::kShift);
+ int32_t bitfield_value = (1 << JSArrayBuffer::IsExternalBit::kShift) |
+ (1 << JSArrayBuffer::IsNeuterableBit::kShift);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldOffset,
Int32Constant(bitfield_value),
MachineRepresentation::kWord32);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
- byte_length);
+ SmiToIntPtr(CAST(byte_length)),
+ MachineType::PointerRepresentation());
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
SmiConstant(0));
for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) {
@@ -305,6 +308,8 @@ TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
}
BIND(&done);
+ SetupTypedArray(holder, length, ChangeNonnegativeNumberToUintPtr(byte_offset),
+ ChangeNonnegativeNumberToUintPtr(byte_length));
Return(UndefinedConstant());
}
@@ -399,8 +404,8 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
BIND(&length_undefined);
{
ThrowIfArrayBufferIsDetached(context, buffer, "Construct");
- Node* buffer_byte_length =
- LoadObjectField(buffer, JSArrayBuffer::kByteLengthOffset);
+ TNode<Number> buffer_byte_length = ChangeUintPtrToTagged(
+ LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kByteLengthOffset));
Node* remainder = CallBuiltin(Builtins::kModulus, context,
buffer_byte_length, element_size);
@@ -424,8 +429,8 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
new_byte_length.Bind(SmiMul(new_length, element_size));
// Reading the byte length must come after the ToIndex operation, which
// could cause the buffer to become detached.
- Node* buffer_byte_length =
- LoadObjectField(buffer, JSArrayBuffer::kByteLengthOffset);
+ TNode<Number> buffer_byte_length = ChangeUintPtrToTagged(
+ LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kByteLengthOffset));
Node* end = CallBuiltin(Builtins::kAdd, context, offset.value(),
new_byte_length.value());
@@ -502,7 +507,7 @@ void TypedArrayBuiltinsAssembler::ConstructByTypedArray(
Goto(&check_for_sab);
BIND(&if_notdetached);
- source_length = LoadTypedArrayLength(typed_array);
+ source_length = LoadJSTypedArrayLength(typed_array);
Goto(&check_for_sab);
// The spec requires that constructing a typed array using a SAB-backed typed
@@ -511,7 +516,7 @@ void TypedArrayBuiltinsAssembler::ConstructByTypedArray(
BIND(&check_for_sab);
TNode<Uint32T> bitfield =
LoadObjectField<Uint32T>(source_buffer, JSArrayBuffer::kBitFieldOffset);
- Branch(IsSetWord32<JSArrayBuffer::IsShared>(bitfield), &construct,
+ Branch(IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield), &construct,
&if_buffernotshared);
BIND(&if_buffernotshared);
@@ -640,8 +645,9 @@ void TypedArrayBuiltinsAssembler::ConstructByIterable(
Label fast_path(this), slow_path(this), done(this);
CSA_ASSERT(this, IsCallable(iterator_fn));
- TNode<JSArray> array_like = CAST(
- CallBuiltin(Builtins::kIterableToList, context, iterable, iterator_fn));
+ TNode<JSArray> array_like =
+ CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
+ iterable, iterator_fn));
TNode<Object> initial_length = LoadJSArrayLength(array_like);
TNode<JSFunction> default_constructor = CAST(LoadContextElement(
@@ -674,6 +680,17 @@ TF_BUILTIN(CreateTypedArray, TypedArrayBuiltinsAssembler) {
ConstructorBuiltinsAssembler constructor_assembler(this->state());
TNode<JSTypedArray> result = CAST(
constructor_assembler.EmitFastNewObject(context, target, new_target));
+ // We need to set the byte_offset / byte_length to some sane values
+ // to keep the heap verifier happy.
+ // TODO(bmeurer): Fix this initialization to not use EmitFastNewObject,
+ // which causes the problem, since it puts Undefined into all slots of
+ // the object even though that doesn't make any sense for these fields.
+ StoreObjectFieldNoWriteBarrier(result, JSTypedArray::kByteOffsetOffset,
+ UintPtrConstant(0),
+ MachineType::PointerRepresentation());
+ StoreObjectFieldNoWriteBarrier(result, JSTypedArray::kByteLengthOffset,
+ UintPtrConstant(0),
+ MachineType::PointerRepresentation());
TNode<Smi> element_size =
SmiTag(GetTypedArrayElementSize(LoadElementsKind(result)));
@@ -775,50 +792,58 @@ TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
}
}
-void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeGetter(
- Node* context, Node* receiver, const char* method_name, int object_offset) {
- // Check if the {receiver} is actually a JSTypedArray.
- ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, method_name);
-
- // Check if the {receiver}'s JSArrayBuffer was neutered.
- Node* receiver_buffer =
- LoadObjectField(receiver, JSTypedArray::kBufferOffset);
- Label if_receiverisneutered(this, Label::kDeferred);
- GotoIf(IsDetachedBuffer(receiver_buffer), &if_receiverisneutered);
- Return(LoadObjectField(receiver, object_offset));
-
- BIND(&if_receiverisneutered);
- {
- // The {receiver}s buffer was neutered, default to zero.
- Return(SmiConstant(0));
- }
-}
-
// ES6 #sec-get-%typedarray%.prototype.bytelength
TF_BUILTIN(TypedArrayPrototypeByteLength, TypedArrayBuiltinsAssembler) {
+ const char* const kMethodName = "get TypedArray.prototype.byteLength";
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
- GenerateTypedArrayPrototypeGetter(context, receiver,
- "get TypedArray.prototype.byteLength",
- JSTypedArray::kByteLengthOffset);
+
+ // Check if the {receiver} is actually a JSTypedArray.
+ ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
+
+ // Default to zero if the {receiver}s buffer was neutered.
+ TNode<JSArrayBuffer> receiver_buffer =
+ LoadJSArrayBufferViewBuffer(CAST(receiver));
+ TNode<UintPtrT> byte_length = Select<UintPtrT>(
+ IsDetachedBuffer(receiver_buffer), [=] { return UintPtrConstant(0); },
+ [=] { return LoadJSArrayBufferViewByteLength(CAST(receiver)); });
+ Return(ChangeUintPtrToTagged(byte_length));
}
// ES6 #sec-get-%typedarray%.prototype.byteoffset
TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) {
+ const char* const kMethodName = "get TypedArray.prototype.byteOffset";
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
- GenerateTypedArrayPrototypeGetter(context, receiver,
- "get TypedArray.prototype.byteOffset",
- JSTypedArray::kByteOffsetOffset);
+
+ // Check if the {receiver} is actually a JSTypedArray.
+ ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
+
+ // Default to zero if the {receiver}s buffer was neutered.
+ TNode<JSArrayBuffer> receiver_buffer =
+ LoadJSArrayBufferViewBuffer(CAST(receiver));
+ TNode<UintPtrT> byte_offset = Select<UintPtrT>(
+ IsDetachedBuffer(receiver_buffer), [=] { return UintPtrConstant(0); },
+ [=] { return LoadJSArrayBufferViewByteOffset(CAST(receiver)); });
+ Return(ChangeUintPtrToTagged(byte_offset));
}
// ES6 #sec-get-%typedarray%.prototype.length
TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) {
+ const char* const kMethodName = "get TypedArray.prototype.length";
Node* context = Parameter(Descriptor::kContext);
Node* receiver = Parameter(Descriptor::kReceiver);
- GenerateTypedArrayPrototypeGetter(context, receiver,
- "get TypedArray.prototype.length",
- JSTypedArray::kLengthOffset);
+
+ // Check if the {receiver} is actually a JSTypedArray.
+ ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
+
+ // Default to zero if the {receiver}s buffer was neutered.
+ TNode<JSArrayBuffer> receiver_buffer =
+ LoadJSArrayBufferViewBuffer(CAST(receiver));
+ TNode<Smi> length = Select<Smi>(
+ IsDetachedBuffer(receiver_buffer), [=] { return SmiConstant(0); },
+ [=] { return LoadJSTypedArrayLength(CAST(receiver)); });
+ Return(length);
}
TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
@@ -923,7 +948,7 @@ TNode<JSTypedArray> TypedArrayBuiltinsAssembler::CreateByLength(
// If newTypedArray.[[ArrayLength]] < argumentList[0], throw a TypeError
// exception.
Label if_length_is_not_short(this);
- TNode<Smi> new_length = LoadTypedArrayLength(new_typed_array);
+ TNode<Smi> new_length = LoadJSTypedArrayLength(new_typed_array);
GotoIfNot(SmiLessThan(new_length, len), &if_length_is_not_short);
ThrowTypeError(context, MessageTemplate::kTypedArrayTooShort);
@@ -979,8 +1004,8 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
// Check for possible range errors.
- TNode<IntPtrT> source_length = SmiUntag(LoadTypedArrayLength(source));
- TNode<IntPtrT> target_length = SmiUntag(LoadTypedArrayLength(target));
+ TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
+ TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset);
GotoIf(IntPtrGreaterThan(required_target_length, target_length),
@@ -1030,7 +1055,7 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
IsBigInt64ElementsKind(target_el_kind)),
&exception);
- TNode<IntPtrT> source_length = SmiUntag(LoadTypedArrayLength(source));
+ TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
offset);
Goto(&out);
@@ -1051,7 +1076,7 @@ void TypedArrayBuiltinsAssembler::SetJSArraySource(
IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source));
- TNode<IntPtrT> target_length = SmiUntag(LoadTypedArrayLength(target));
+ TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
// Maybe out of bounds?
GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length),
@@ -1266,7 +1291,7 @@ TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
TNode<JSTypedArray> source =
ValidateTypedArray(context, receiver, method_name);
- TNode<Smi> source_length = LoadTypedArrayLength(source);
+ TNode<Smi> source_length = LoadJSTypedArrayLength(source);
// Convert start offset argument to integer, and calculate relative offset.
TNode<Object> start = args.GetOptionalArgumentValue(0, SmiConstant(0));
@@ -1299,7 +1324,7 @@ TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(LoadObjectField(
result_array, JSTypedArray::kBufferOffset))));
TNode<JSArrayBuffer> receiver_buffer =
- LoadArrayBufferViewBuffer(CAST(receiver));
+ LoadJSArrayBufferViewBuffer(CAST(receiver));
ThrowIfArrayBufferIsDetached(context, receiver_buffer, method_name);
// result_array could be a different type from source or share the same
@@ -1332,24 +1357,16 @@ TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
TNode<IntPtrT> count_bytes = IntPtrMul(SmiToIntPtr(count), source_el_size);
#ifdef DEBUG
- Label done(this), to_intptr_failed(this, Label::kDeferred);
- TNode<IntPtrT> target_byte_length = TryToIntptr(
- LoadObjectField<Number>(result_array, JSTypedArray::kByteLengthOffset),
- &to_intptr_failed);
- CSA_ASSERT(this, IntPtrLessThanOrEqual(count_bytes, target_byte_length));
-
- TNode<IntPtrT> source_byte_length = TryToIntptr(
- LoadObjectField<Number>(source, JSTypedArray::kByteLengthOffset),
- &to_intptr_failed);
- TNode<IntPtrT> source_size_in_bytes =
- IntPtrSub(source_byte_length, source_start_bytes);
- CSA_ASSERT(this, IntPtrLessThanOrEqual(count_bytes, source_size_in_bytes));
- Goto(&done);
-
- BIND(&to_intptr_failed);
- Unreachable();
-
- BIND(&done);
+ TNode<UintPtrT> target_byte_length =
+ LoadJSArrayBufferViewByteLength(result_array);
+ CSA_ASSERT(this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
+ target_byte_length));
+ TNode<UintPtrT> source_byte_length =
+ LoadJSArrayBufferViewByteLength(source);
+ TNode<UintPtrT> source_size_in_bytes =
+ UintPtrSub(source_byte_length, Unsigned(source_start_bytes));
+ CSA_ASSERT(this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
+ source_size_in_bytes));
#endif // DEBUG
CallCMemmove(target_data_ptr, source_start, count_bytes);
@@ -1395,7 +1412,7 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
// 5. Let buffer be O.[[ViewedArrayBuffer]].
TNode<JSArrayBuffer> buffer = GetBuffer(context, source);
// 6. Let srcLength be O.[[ArrayLength]].
- TNode<Smi> source_length = LoadTypedArrayLength(source);
+ TNode<Smi> source_length = LoadJSTypedArrayLength(source);
// 7. Let relativeBegin be ? ToInteger(begin).
// 8. If relativeBegin < 0, let beginIndex be max((srcLength + relativeBegin),
@@ -1430,7 +1447,7 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
// 14. Let srcByteOffset be O.[[ByteOffset]].
TNode<Number> source_byte_offset =
- LoadObjectField<Number>(source, JSTypedArray::kByteOffsetOffset);
+ ChangeUintPtrToTagged(LoadJSArrayBufferViewByteOffset(source));
// 15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
TNode<Number> offset = SmiMul(var_begin.value(), SmiFromIntPtr(element_size));
@@ -1606,17 +1623,6 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
"%TypedArray%.of");
}
-// This builtin always returns a new JSArray and is thus safe to use even in the
-// presence of code that may call back into user-JS.
-TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
- TNode<Context> context = CAST(Parameter(Descriptor::kContext));
- TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
- TNode<Object> iterator_fn = CAST(Parameter(Descriptor::kIteratorFn));
-
- IteratorBuiltinsAssembler iterator_assembler(state());
- Return(iterator_assembler.IterableToList(context, iterable, iterator_fn));
-}
-
// ES6 #sec-%typedarray%.from
TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
@@ -1818,7 +1824,7 @@ TF_BUILTIN(TypedArrayPrototypeFilter, TypedArrayBuiltinsAssembler) {
ValidateTypedArray(context, receiver, method_name);
// 3. Let len be O.[[ArrayLength]].
- TNode<Smi> length = LoadTypedArrayLength(source);
+ TNode<Smi> length = LoadJSTypedArrayLength(source);
// 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
TNode<Object> callbackfn = args.GetOptionalArgumentValue(0);