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 |