Chromium Code Reviews| 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, |
|
Benedikt Meurer
2016/10/17 04:02:42
Nit: Remove static, it's implicitly static via the
caitp
2016/10/18 00:16:50
I've just removed this helper and added CodeStubAs
|
| + 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 |