| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 | 10 |
| 11 // ----------------------------------------------------------------------------- | 11 // ----------------------------------------------------------------------------- |
| 12 // ES6 section 22.2 TypedArray Objects | 12 // ES6 section 22.2 TypedArray Objects |
| 13 | 13 |
| 14 // ES6 section 22.2.3.1 get %TypedArray%.prototype.buffer | 14 // ES6 section 22.2.3.1 get %TypedArray%.prototype.buffer |
| 15 BUILTIN(TypedArrayPrototypeBuffer) { | 15 BUILTIN(TypedArrayPrototypeBuffer) { |
| 16 HandleScope scope(isolate); | 16 HandleScope scope(isolate); |
| 17 CHECK_RECEIVER(JSTypedArray, typed_array, "get TypedArray.prototype.buffer"); | 17 CHECK_RECEIVER(JSTypedArray, typed_array, "get TypedArray.prototype.buffer"); |
| 18 return *typed_array->GetBuffer(); | 18 return *typed_array->GetBuffer(); |
| 19 } | 19 } |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 void Generate_TypedArrayProtoypeGetter(CodeStubAssembler* assembler, | 23 void Generate_TypedArrayProtoypeGetter(compiler::CodeAssemblerState* state, |
| 24 const char* method_name, | 24 const char* method_name, |
| 25 int object_offset) { | 25 int object_offset) { |
| 26 typedef CodeStubAssembler::Label Label; | 26 typedef CodeStubAssembler::Label Label; |
| 27 typedef compiler::Node Node; | 27 typedef compiler::Node Node; |
| 28 CodeStubAssembler assembler(state); |
| 28 | 29 |
| 29 Node* receiver = assembler->Parameter(0); | 30 Node* receiver = assembler.Parameter(0); |
| 30 Node* context = assembler->Parameter(3); | 31 Node* context = assembler.Parameter(3); |
| 31 | 32 |
| 32 // Check if the {receiver} is actually a JSTypedArray. | 33 // Check if the {receiver} is actually a JSTypedArray. |
| 33 Label if_receiverisincompatible(assembler, Label::kDeferred); | 34 Label if_receiverisincompatible(&assembler, Label::kDeferred); |
| 34 assembler->GotoIf(assembler->TaggedIsSmi(receiver), | 35 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_receiverisincompatible); |
| 35 &if_receiverisincompatible); | 36 Node* receiver_instance_type = assembler.LoadInstanceType(receiver); |
| 36 Node* receiver_instance_type = assembler->LoadInstanceType(receiver); | 37 assembler.GotoUnless( |
| 37 assembler->GotoUnless( | 38 assembler.Word32Equal(receiver_instance_type, |
| 38 assembler->Word32Equal(receiver_instance_type, | 39 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 39 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
| 40 &if_receiverisincompatible); | 40 &if_receiverisincompatible); |
| 41 | 41 |
| 42 // Check if the {receiver}'s JSArrayBuffer was neutered. | 42 // Check if the {receiver}'s JSArrayBuffer was neutered. |
| 43 Node* receiver_buffer = | 43 Node* receiver_buffer = |
| 44 assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset); | 44 assembler.LoadObjectField(receiver, JSTypedArray::kBufferOffset); |
| 45 Label if_receiverisneutered(assembler, Label::kDeferred); | 45 Label if_receiverisneutered(&assembler, Label::kDeferred); |
| 46 assembler->GotoIf(assembler->IsDetachedBuffer(receiver_buffer), | 46 assembler.GotoIf(assembler.IsDetachedBuffer(receiver_buffer), |
| 47 &if_receiverisneutered); | 47 &if_receiverisneutered); |
| 48 assembler->Return(assembler->LoadObjectField(receiver, object_offset)); | 48 assembler.Return(assembler.LoadObjectField(receiver, object_offset)); |
| 49 | 49 |
| 50 assembler->Bind(&if_receiverisneutered); | 50 assembler.Bind(&if_receiverisneutered); |
| 51 { | 51 { |
| 52 // The {receiver}s buffer was neutered, default to zero. | 52 // The {receiver}s buffer was neutered, default to zero. |
| 53 assembler->Return(assembler->SmiConstant(0)); | 53 assembler.Return(assembler.SmiConstant(0)); |
| 54 } | 54 } |
| 55 | 55 |
| 56 assembler->Bind(&if_receiverisincompatible); | 56 assembler.Bind(&if_receiverisincompatible); |
| 57 { | 57 { |
| 58 // The {receiver} is not a valid JSGeneratorObject. | 58 // The {receiver} is not a valid JSGeneratorObject. |
| 59 Node* result = assembler->CallRuntime( | 59 Node* result = assembler.CallRuntime( |
| 60 Runtime::kThrowIncompatibleMethodReceiver, context, | 60 Runtime::kThrowIncompatibleMethodReceiver, context, |
| 61 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | 61 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( |
| 62 method_name, TENURED)), | 62 method_name, TENURED)), |
| 63 receiver); | 63 receiver); |
| 64 assembler->Return(result); // Never reached. | 64 assembler.Return(result); // Never reached. |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 } // namespace | 68 } // namespace |
| 69 | 69 |
| 70 // ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength | 70 // ES6 section 22.2.3.2 get %TypedArray%.prototype.byteLength |
| 71 void Builtins::Generate_TypedArrayPrototypeByteLength( | 71 void Builtins::Generate_TypedArrayPrototypeByteLength( |
| 72 CodeStubAssembler* assembler) { | 72 compiler::CodeAssemblerState* state) { |
| 73 Generate_TypedArrayProtoypeGetter(assembler, | 73 Generate_TypedArrayProtoypeGetter(state, |
| 74 "get TypedArray.prototype.byteLength", | 74 "get TypedArray.prototype.byteLength", |
| 75 JSTypedArray::kByteLengthOffset); | 75 JSTypedArray::kByteLengthOffset); |
| 76 } | 76 } |
| 77 | 77 |
| 78 // ES6 section 22.2.3.3 get %TypedArray%.prototype.byteOffset | 78 // ES6 section 22.2.3.3 get %TypedArray%.prototype.byteOffset |
| 79 void Builtins::Generate_TypedArrayPrototypeByteOffset( | 79 void Builtins::Generate_TypedArrayPrototypeByteOffset( |
| 80 CodeStubAssembler* assembler) { | 80 compiler::CodeAssemblerState* state) { |
| 81 Generate_TypedArrayProtoypeGetter(assembler, | 81 Generate_TypedArrayProtoypeGetter(state, |
| 82 "get TypedArray.prototype.byteOffset", | 82 "get TypedArray.prototype.byteOffset", |
| 83 JSTypedArray::kByteOffsetOffset); | 83 JSTypedArray::kByteOffsetOffset); |
| 84 } | 84 } |
| 85 | 85 |
| 86 // ES6 section 22.2.3.18 get %TypedArray%.prototype.length | 86 // ES6 section 22.2.3.18 get %TypedArray%.prototype.length |
| 87 void Builtins::Generate_TypedArrayPrototypeLength( | 87 void Builtins::Generate_TypedArrayPrototypeLength( |
| 88 CodeStubAssembler* assembler) { | 88 compiler::CodeAssemblerState* state) { |
| 89 Generate_TypedArrayProtoypeGetter(assembler, | 89 Generate_TypedArrayProtoypeGetter(state, "get TypedArray.prototype.length", |
| 90 "get TypedArray.prototype.length", | |
| 91 JSTypedArray::kLengthOffset); | 90 JSTypedArray::kLengthOffset); |
| 92 } | 91 } |
| 93 | 92 |
| 94 namespace { | 93 namespace { |
| 95 | 94 |
| 96 template <IterationKind kIterationKind> | 95 template <IterationKind kIterationKind> |
| 97 void Generate_TypedArrayPrototypeIterationMethod(CodeStubAssembler* assembler, | 96 void Generate_TypedArrayPrototypeIterationMethod( |
| 98 const char* method_name) { | 97 compiler::CodeAssemblerState* state, const char* method_name) { |
| 99 typedef compiler::Node Node; | 98 typedef compiler::Node Node; |
| 100 typedef CodeStubAssembler::Label Label; | 99 typedef CodeStubAssembler::Label Label; |
| 101 typedef CodeStubAssembler::Variable Variable; | 100 typedef CodeStubAssembler::Variable Variable; |
| 101 CodeStubAssembler assembler(state); |
| 102 | 102 |
| 103 Node* receiver = assembler->Parameter(0); | 103 Node* receiver = assembler.Parameter(0); |
| 104 Node* context = assembler->Parameter(3); | 104 Node* context = assembler.Parameter(3); |
| 105 | 105 |
| 106 Label throw_bad_receiver(assembler, Label::kDeferred); | 106 Label throw_bad_receiver(&assembler, Label::kDeferred); |
| 107 Label throw_typeerror(assembler, Label::kDeferred); | 107 Label throw_typeerror(&assembler, Label::kDeferred); |
| 108 | 108 |
| 109 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &throw_bad_receiver); | 109 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &throw_bad_receiver); |
| 110 | 110 |
| 111 Node* map = assembler->LoadMap(receiver); | 111 Node* map = assembler.LoadMap(receiver); |
| 112 Node* instance_type = assembler->LoadMapInstanceType(map); | 112 Node* instance_type = assembler.LoadMapInstanceType(map); |
| 113 assembler->GotoIf( | 113 assembler.GotoIf( |
| 114 assembler->Word32NotEqual(instance_type, | 114 assembler.Word32NotEqual(instance_type, |
| 115 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | 115 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 116 &throw_bad_receiver); | 116 &throw_bad_receiver); |
| 117 | 117 |
| 118 // Check if the {receiver}'s JSArrayBuffer was neutered. | 118 // Check if the {receiver}'s JSArrayBuffer was neutered. |
| 119 Node* receiver_buffer = | 119 Node* receiver_buffer = |
| 120 assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset); | 120 assembler.LoadObjectField(receiver, JSTypedArray::kBufferOffset); |
| 121 Label if_receiverisneutered(assembler, Label::kDeferred); | 121 Label if_receiverisneutered(&assembler, Label::kDeferred); |
| 122 assembler->GotoIf(assembler->IsDetachedBuffer(receiver_buffer), | 122 assembler.GotoIf(assembler.IsDetachedBuffer(receiver_buffer), |
| 123 &if_receiverisneutered); | 123 &if_receiverisneutered); |
| 124 | 124 |
| 125 assembler->Return(assembler->CreateArrayIterator(receiver, map, instance_type, | 125 assembler.Return(assembler.CreateArrayIterator(receiver, map, instance_type, |
| 126 context, kIterationKind)); | 126 context, kIterationKind)); |
| 127 | 127 |
| 128 Variable var_message(assembler, MachineRepresentation::kTagged); | 128 Variable var_message(&assembler, MachineRepresentation::kTagged); |
| 129 assembler->Bind(&throw_bad_receiver); | 129 assembler.Bind(&throw_bad_receiver); |
| 130 var_message.Bind( | 130 var_message.Bind( |
| 131 assembler->SmiConstant(Smi::FromInt(MessageTemplate::kNotTypedArray))); | 131 assembler.SmiConstant(Smi::FromInt(MessageTemplate::kNotTypedArray))); |
| 132 assembler->Goto(&throw_typeerror); | 132 assembler.Goto(&throw_typeerror); |
| 133 | 133 |
| 134 assembler->Bind(&if_receiverisneutered); | 134 assembler.Bind(&if_receiverisneutered); |
| 135 var_message.Bind(assembler->SmiConstant( | 135 var_message.Bind( |
| 136 Smi::FromInt(MessageTemplate::kDetachedOperation))); | 136 assembler.SmiConstant(Smi::FromInt(MessageTemplate::kDetachedOperation))); |
| 137 assembler->Goto(&throw_typeerror); | 137 assembler.Goto(&throw_typeerror); |
| 138 | 138 |
| 139 assembler->Bind(&throw_typeerror); | 139 assembler.Bind(&throw_typeerror); |
| 140 { | 140 { |
| 141 Node* arg1 = assembler->HeapConstant( | 141 Node* arg1 = assembler.HeapConstant( |
| 142 assembler->isolate()->factory()->NewStringFromAsciiChecked(method_name, | 142 assembler.isolate()->factory()->NewStringFromAsciiChecked(method_name, |
| 143 TENURED)); | 143 TENURED)); |
| 144 Node* result = assembler->CallRuntime(Runtime::kThrowTypeError, context, | 144 Node* result = assembler.CallRuntime(Runtime::kThrowTypeError, context, |
| 145 var_message.value(), arg1); | 145 var_message.value(), arg1); |
| 146 assembler->Return(result); | 146 assembler.Return(result); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 } // namespace | 149 } // namespace |
| 150 | 150 |
| 151 void Builtins::Generate_TypedArrayPrototypeValues( | 151 void Builtins::Generate_TypedArrayPrototypeValues( |
| 152 CodeStubAssembler* assembler) { | 152 compiler::CodeAssemblerState* state) { |
| 153 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kValues>( | 153 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kValues>( |
| 154 assembler, "%TypedArray%.prototype.values()"); | 154 state, "%TypedArray%.prototype.values()"); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void Builtins::Generate_TypedArrayPrototypeEntries( | 157 void Builtins::Generate_TypedArrayPrototypeEntries( |
| 158 CodeStubAssembler* assembler) { | 158 compiler::CodeAssemblerState* state) { |
| 159 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kEntries>( | 159 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kEntries>( |
| 160 assembler, "%TypedArray%.prototype.entries()"); | 160 state, "%TypedArray%.prototype.entries()"); |
| 161 } | 161 } |
| 162 | 162 |
| 163 void Builtins::Generate_TypedArrayPrototypeKeys(CodeStubAssembler* assembler) { | 163 void Builtins::Generate_TypedArrayPrototypeKeys( |
| 164 compiler::CodeAssemblerState* state) { |
| 164 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kKeys>( | 165 Generate_TypedArrayPrototypeIterationMethod<IterationKind::kKeys>( |
| 165 assembler, "%TypedArray%.prototype.keys()"); | 166 state, "%TypedArray%.prototype.keys()"); |
| 166 } | 167 } |
| 167 | 168 |
| 168 } // namespace internal | 169 } // namespace internal |
| 169 } // namespace v8 | 170 } // namespace v8 |
| OLD | NEW |