| Index: src/builtins/builtins-typedarray.cc
|
| diff --git a/src/builtins/builtins-typedarray.cc b/src/builtins/builtins-typedarray.cc
|
| index d63affe3ba62a62721af14a66e39bf7655d401f7..e183c9503991aede40b7268723f0a0f6c4be73a1 100644
|
| --- a/src/builtins/builtins-typedarray.cc
|
| +++ b/src/builtins/builtins-typedarray.cc
|
| @@ -20,6 +20,28 @@ BUILTIN(TypedArrayPrototypeBuffer) {
|
|
|
| namespace {
|
|
|
| +static void GotoIfIsDetachedBuffer(CodeStubAssembler* assembler,
|
| + compiler::Node* buffer,
|
| + CodeStubAssembler::Label* if_detached) {
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Label Label;
|
| +
|
| + Label if_notdetached(assembler);
|
| + assembler->Assert(
|
| + assembler->Word32Equal(assembler->LoadInstanceType(buffer),
|
| + assembler->Int32Constant(JS_ARRAY_BUFFER_TYPE)));
|
| + Node* buffer_bit_field = assembler->LoadObjectField(
|
| + buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
|
| + assembler->Branch(
|
| + assembler->Word32Equal(
|
| + assembler->Word32And(
|
| + buffer_bit_field,
|
| + assembler->Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
|
| + assembler->Int32Constant(0)),
|
| + &if_notdetached, if_detached);
|
| + assembler->Bind(&if_notdetached);
|
| +}
|
| +
|
| void Generate_TypedArrayProtoypeGetter(CodeStubAssembler* assembler,
|
| const char* method_name,
|
| int object_offset) {
|
| @@ -42,16 +64,8 @@ void Generate_TypedArrayProtoypeGetter(CodeStubAssembler* assembler,
|
| // Check if the {receiver}'s JSArrayBuffer was neutered.
|
| Node* receiver_buffer =
|
| assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset);
|
| - Node* receiver_buffer_bit_field = assembler->LoadObjectField(
|
| - receiver_buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
|
| Label if_receiverisneutered(assembler, Label::kDeferred);
|
| - assembler->GotoUnless(
|
| - assembler->Word32Equal(
|
| - assembler->Word32And(
|
| - receiver_buffer_bit_field,
|
| - assembler->Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
|
| - assembler->Int32Constant(0)),
|
| - &if_receiverisneutered);
|
| + GotoIfIsDetachedBuffer(assembler, receiver_buffer, &if_receiverisneutered);
|
| assembler->Return(assembler->LoadObjectField(receiver, object_offset));
|
|
|
| assembler->Bind(&if_receiverisneutered);
|
| @@ -98,5 +112,78 @@ void Builtins::Generate_TypedArrayPrototypeLength(
|
| JSTypedArray::kLengthOffset);
|
| }
|
|
|
| +namespace {
|
| +
|
| +template <IterationKind kIterationKind>
|
| +void Generate_TypedArrayPrototypeIterationMethod(CodeStubAssembler* assembler,
|
| + const char* method_name) {
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| +
|
| + Node* receiver = assembler->Parameter(0);
|
| + Node* context = assembler->Parameter(3);
|
| +
|
| + Label throw_bad_receiver(assembler, Label::kDeferred);
|
| + Label throw_typeerror(assembler, Label::kDeferred);
|
| +
|
| + assembler->GotoIf(assembler->TaggedIsSmi(receiver), &throw_bad_receiver);
|
| +
|
| + Node* map = assembler->LoadMap(receiver);
|
| + Node* instance_type = assembler->LoadMapInstanceType(map);
|
| + assembler->GotoIf(
|
| + assembler->Word32NotEqual(instance_type,
|
| + assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)),
|
| + &throw_bad_receiver);
|
| +
|
| + // Check if the {receiver}'s JSArrayBuffer was neutered.
|
| + Node* receiver_buffer =
|
| + assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset);
|
| + Label if_receiverisneutered(assembler, Label::kDeferred);
|
| + GotoIfIsDetachedBuffer(assembler, receiver_buffer, &if_receiverisneutered);
|
| +
|
| + assembler->Return(assembler->CreateArrayIterator(receiver, map, instance_type,
|
| + context, kIterationKind));
|
| +
|
| + Variable var_message(assembler, MachineRepresentation::kTagged);
|
| + assembler->Bind(&throw_bad_receiver);
|
| + var_message.Bind(
|
| + assembler->SmiConstant(Smi::FromInt(MessageTemplate::kNotTypedArray)));
|
| + assembler->Goto(&throw_typeerror);
|
| +
|
| + assembler->Bind(&if_receiverisneutered);
|
| + var_message.Bind(assembler->SmiConstant(
|
| + Smi::FromInt(MessageTemplate::kDetachedOperation)));
|
| + assembler->Goto(&throw_typeerror);
|
| +
|
| + assembler->Bind(&throw_typeerror);
|
| + {
|
| + Node* arg1 = assembler->HeapConstant(
|
| + assembler->isolate()->factory()->NewStringFromAsciiChecked(method_name,
|
| + TENURED));
|
| + Node* result = assembler->CallRuntime(Runtime::kThrowTypeError, context,
|
| + var_message.value(), arg1);
|
| + assembler->Return(result);
|
| + }
|
| +}
|
| +} // namespace
|
| +
|
| +void Builtins::Generate_TypedArrayPrototypeValues(
|
| + CodeStubAssembler* assembler) {
|
| + Generate_TypedArrayPrototypeIterationMethod<IterationKind::kValues>(
|
| + assembler, "%TypedArray%.prototype.values()");
|
| +}
|
| +
|
| +void Builtins::Generate_TypedArrayPrototypeEntries(
|
| + CodeStubAssembler* assembler) {
|
| + Generate_TypedArrayPrototypeIterationMethod<IterationKind::kEntries>(
|
| + assembler, "%TypedArray%.prototype.entries()");
|
| +}
|
| +
|
| +void Builtins::Generate_TypedArrayPrototypeKeys(CodeStubAssembler* assembler) {
|
| + Generate_TypedArrayPrototypeIterationMethod<IterationKind::kKeys>(
|
| + assembler, "%TypedArray%.prototype.keys()");
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|