OLD | NEW |
---|---|
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-utils-gen.h" | 5 #include "src/builtins/builtins-utils-gen.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 | 11 |
12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { | 12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { |
13 public: | 13 public: |
14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) | 14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) |
15 : CodeStubAssembler(state), | 15 : CodeStubAssembler(state), |
16 k_(this, MachineRepresentation::kTagged, SmiConstant(0)), | 16 k_(this, MachineRepresentation::kTagged), |
17 a_(this, MachineRepresentation::kTagged, SmiConstant(0)), | 17 a_(this, MachineRepresentation::kTagged), |
Tobias Tebbi
2017/04/05 11:53:05
I removed these defaults because we should never r
| |
18 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} | 18 to_(this, MachineRepresentation::kTagged, SmiConstant(0)) {} |
19 | 19 |
20 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> | 20 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm)> |
21 BuiltinResultGenerator; | 21 BuiltinResultGenerator; |
22 | 22 |
23 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)> | 23 typedef std::function<void(ArrayBuiltinCodeStubAssembler* masm)> |
24 BuiltinResultIndexInitializer; | 24 BuiltinResultIndexInitializer; |
25 | 25 |
26 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm, | 26 typedef std::function<Node*(ArrayBuiltinCodeStubAssembler* masm, |
27 Node* k_value, Node* k)> | 27 Node* k_value, Node* k)> |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 Node* a() { return a_.value(); } | 179 Node* a() { return a_.value(); } |
180 | 180 |
181 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver, | 181 void InitIteratingArrayBuiltinBody(Node* context, Node* receiver, |
182 Node* callbackfn, Node* this_arg, | 182 Node* callbackfn, Node* this_arg, |
183 Node* new_target) { | 183 Node* new_target) { |
184 context_ = context; | 184 context_ = context; |
185 receiver_ = receiver; | 185 receiver_ = receiver; |
186 new_target_ = new_target; | 186 new_target_ = new_target; |
187 callbackfn_ = callbackfn; | 187 callbackfn_ = callbackfn; |
188 this_arg_ = this_arg; | 188 this_arg_ = this_arg; |
189 | |
190 k_.Bind(SmiConstant(0)); | |
191 a_.Bind(UndefinedConstant()); | |
Tobias Tebbi
2017/04/05 11:53:05
Same here.
| |
192 } | 189 } |
193 | 190 |
194 void GenerateIteratingArrayBuiltinBody( | 191 void GenerateIteratingArrayBuiltinBody( |
195 const char* name, const BuiltinResultGenerator& generator, | 192 const char* name, const BuiltinResultGenerator& generator, |
196 const CallResultProcessor& processor, const PostLoopAction& action, | 193 const CallResultProcessor& processor, const PostLoopAction& action, |
197 const Callable& slow_case_continuation, | 194 const Callable& slow_case_continuation, |
198 ForEachDirection direction = ForEachDirection::kForward) { | 195 ForEachDirection direction = ForEachDirection::kForward) { |
199 Label non_array(this), slow(this, {&k_, &a_, &to_}), | 196 Label non_array(this), slow(this, {&k_, &a_, &to_}), |
200 array_changes(this, {&k_, &a_, &to_}); | 197 array_changes(this, {&k_, &a_, &to_}); |
201 | 198 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 | 251 |
255 Bind(&done); | 252 Bind(&done); |
256 | 253 |
257 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. | 254 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. |
258 // [Already done by the arguments adapter] | 255 // [Already done by the arguments adapter] |
259 | 256 |
260 if (direction == ForEachDirection::kForward) { | 257 if (direction == ForEachDirection::kForward) { |
261 // 7. Let k be 0. | 258 // 7. Let k be 0. |
262 k_.Bind(SmiConstant(0)); | 259 k_.Bind(SmiConstant(0)); |
263 } else { | 260 } else { |
264 k_.Bind(len()); | 261 k_.Bind(NumberDec(len())); |
265 k_.Bind(NumberDec(k_.value())); | |
266 } | 262 } |
267 | 263 |
268 a_.Bind(generator(this)); | 264 a_.Bind(generator(this)); |
269 | 265 |
270 HandleFastElements(processor, action, &slow, direction); | 266 HandleFastElements(processor, action, &slow, direction); |
271 | 267 |
272 Bind(&slow); | 268 Bind(&slow); |
273 | 269 |
274 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, | 270 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, |
275 MachineType::TaggedPointer()); | 271 MachineType::TaggedPointer()); |
(...skipping 14 matching lines...) Expand all Loading... | |
290 callbackfn_ = callbackfn; | 286 callbackfn_ = callbackfn; |
291 a_.Bind(a); | 287 a_.Bind(a); |
292 k_.Bind(initial_k); | 288 k_.Bind(initial_k); |
293 o_ = o; | 289 o_ = o; |
294 len_ = len; | 290 len_ = len; |
295 to_.Bind(to); | 291 to_.Bind(to); |
296 } | 292 } |
297 | 293 |
298 void GenerateIteratingTypedArrayBuiltinBody( | 294 void GenerateIteratingTypedArrayBuiltinBody( |
299 const char* name, const BuiltinResultGenerator& generator, | 295 const char* name, const BuiltinResultGenerator& generator, |
300 const CallResultProcessor& processor, const PostLoopAction& action) { | 296 const CallResultProcessor& processor, const PostLoopAction& action, |
297 ForEachDirection direction = ForEachDirection::kForward) { | |
301 Node* name_string = | 298 Node* name_string = |
302 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); | 299 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); |
303 | 300 |
304 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray | 301 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray |
305 | 302 |
306 Label throw_not_typed_array(this, Label::kDeferred), | 303 Label throw_not_typed_array(this, Label::kDeferred), |
307 throw_detached(this, Label::kDeferred); | 304 throw_detached(this, Label::kDeferred); |
308 | 305 |
309 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); | 306 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); |
310 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE), | 307 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 std::vector<Label> labels; | 354 std::vector<Label> labels; |
358 for (size_t i = 0; i < instance_types.size(); ++i) { | 355 for (size_t i = 0; i < instance_types.size(); ++i) { |
359 labels.push_back(Label(this)); | 356 labels.push_back(Label(this)); |
360 } | 357 } |
361 std::vector<Label*> label_ptrs; | 358 std::vector<Label*> label_ptrs; |
362 for (Label& label : labels) { | 359 for (Label& label : labels) { |
363 label_ptrs.push_back(&label); | 360 label_ptrs.push_back(&label); |
364 } | 361 } |
365 | 362 |
366 Bind(&distinguish_types); | 363 Bind(&distinguish_types); |
364 | |
365 if (direction == ForEachDirection::kForward) { | |
366 k_.Bind(SmiConstant(0)); | |
367 } else { | |
368 k_.Bind(NumberDec(len())); | |
369 } | |
367 a_.Bind(generator(this)); | 370 a_.Bind(generator(this)); |
368 Node* elements_type = LoadInstanceType(LoadElements(o_)); | 371 Node* elements_type = LoadInstanceType(LoadElements(o_)); |
369 Switch(elements_type, &unexpected_instance_type, instance_types.data(), | 372 Switch(elements_type, &unexpected_instance_type, instance_types.data(), |
370 label_ptrs.data(), labels.size()); | 373 label_ptrs.data(), labels.size()); |
371 | 374 |
372 for (size_t i = 0; i < labels.size(); ++i) { | 375 for (size_t i = 0; i < labels.size(); ++i) { |
373 Bind(&labels[i]); | 376 Bind(&labels[i]); |
374 Label done(this); | 377 Label done(this); |
375 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a | 378 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a |
376 // spec violation. Should go to &detached and throw a TypeError instead. | 379 // spec violation. Should go to &detached and throw a TypeError instead. |
377 VisitAllTypedArrayElements( | 380 VisitAllTypedArrayElements( |
378 ElementsKindForInstanceType( | 381 ElementsKindForInstanceType( |
379 static_cast<InstanceType>(instance_types[i])), | 382 static_cast<InstanceType>(instance_types[i])), |
380 array_buffer, processor, &done); | 383 array_buffer, processor, &done, direction); |
381 Goto(&done); | 384 Goto(&done); |
382 action(this); | |
383 // No exception, return success | 385 // No exception, return success |
384 Bind(&done); | 386 Bind(&done); |
387 action(this); | |
385 Return(a_.value()); | 388 Return(a_.value()); |
386 } | 389 } |
387 } | 390 } |
388 | 391 |
389 void GenerateIteratingArrayBuiltinLoopContinuation( | 392 void GenerateIteratingArrayBuiltinLoopContinuation( |
390 const CallResultProcessor& processor, const PostLoopAction& action, | 393 const CallResultProcessor& processor, const PostLoopAction& action, |
391 ForEachDirection direction = ForEachDirection::kForward) { | 394 ForEachDirection direction = ForEachDirection::kForward) { |
392 Label loop(this, {&k_, &a_, &to_}); | 395 Label loop(this, {&k_, &a_, &to_}); |
393 Label after_loop(this); | 396 Label after_loop(this); |
394 Goto(&loop); | 397 Goto(&loop); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND | 454 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND |
452 | 455 |
453 default: | 456 default: |
454 UNREACHABLE(); | 457 UNREACHABLE(); |
455 return static_cast<ElementsKind>(-1); | 458 return static_cast<ElementsKind>(-1); |
456 } | 459 } |
457 } | 460 } |
458 | 461 |
459 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer, | 462 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer, |
460 const CallResultProcessor& processor, | 463 const CallResultProcessor& processor, |
461 Label* detached) { | 464 Label* detached, ForEachDirection direction) { |
462 VariableList list({&a_, &k_, &to_}, zone()); | 465 VariableList list({&a_, &k_, &to_}, zone()); |
463 | 466 |
464 FastLoopBody body = [&](Node* index) { | 467 FastLoopBody body = [&](Node* index) { |
465 GotoIf(IsDetachedBuffer(array_buffer), detached); | 468 GotoIf(IsDetachedBuffer(array_buffer), detached); |
466 Node* elements = LoadElements(o_); | 469 Node* elements = LoadElements(o_); |
467 Node* base_ptr = | 470 Node* base_ptr = |
468 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); | 471 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); |
469 Node* external_ptr = | 472 Node* external_ptr = |
470 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, | 473 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, |
471 MachineType::Pointer()); | 474 MachineType::Pointer()); |
472 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); | 475 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); |
473 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind, | 476 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind, |
474 SMI_PARAMETERS); | 477 SMI_PARAMETERS); |
475 k_.Bind(index); | 478 k_.Bind(index); |
476 a_.Bind(processor(this, value, index)); | 479 a_.Bind(processor(this, value, index)); |
477 }; | 480 }; |
478 BuildFastLoop(list, SmiConstant(0), len_, body, 1, | 481 Node* start = SmiConstant(0); |
479 ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost); | 482 Node* end = len_; |
483 IndexAdvanceMode advance_mode = IndexAdvanceMode::kPost; | |
484 int incr = 1; | |
485 if (direction == ForEachDirection::kReverse) { | |
486 std::swap(start, end); | |
487 advance_mode = IndexAdvanceMode::kPre; | |
488 incr = -1; | |
489 } | |
490 BuildFastLoop(list, start, end, body, incr, ParameterMode::SMI_PARAMETERS, | |
491 advance_mode); | |
480 } | 492 } |
481 | 493 |
482 void VisitAllFastElementsOneKind(ElementsKind kind, | 494 void VisitAllFastElementsOneKind(ElementsKind kind, |
483 const CallResultProcessor& processor, | 495 const CallResultProcessor& processor, |
484 Label* array_changed, ParameterMode mode, | 496 Label* array_changed, ParameterMode mode, |
485 ForEachDirection direction) { | 497 ForEachDirection direction) { |
486 Comment("begin VisitAllFastElementsOneKind"); | 498 Comment("begin VisitAllFastElementsOneKind"); |
487 Variable original_map(this, MachineRepresentation::kTagged); | 499 Variable original_map(this, MachineRepresentation::kTagged); |
488 original_map.Bind(LoadMap(o())); | 500 original_map.Bind(LoadMap(o())); |
489 VariableList list({&original_map, &a_, &k_, &to_}, zone()); | 501 VariableList list({&original_map, &a_, &k_, &to_}, zone()); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 new_target); | 953 new_target); |
942 | 954 |
943 GenerateIteratingArrayBuiltinBody( | 955 GenerateIteratingArrayBuiltinBody( |
944 "Array.prototype.reduce", | 956 "Array.prototype.reduce", |
945 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, | 957 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, |
946 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, | 958 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, |
947 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, | 959 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, |
948 CodeFactory::ArrayReduceLoopContinuation(isolate())); | 960 CodeFactory::ArrayReduceLoopContinuation(isolate())); |
949 } | 961 } |
950 | 962 |
963 TF_BUILTIN(TypedArrayPrototypeReduce, ArrayBuiltinCodeStubAssembler) { | |
964 Node* context = Parameter(Descriptor::kContext); | |
965 Node* receiver = Parameter(Descriptor::kReceiver); | |
966 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | |
967 Node* initial_value = Parameter(Descriptor::kInitialValue); | |
968 Node* new_target = Parameter(Descriptor::kNewTarget); | |
969 | |
970 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value, | |
971 new_target); | |
972 | |
973 GenerateIteratingTypedArrayBuiltinBody( | |
974 "%TypedArray%.prototype.reduce", | |
975 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, | |
976 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, | |
977 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction); | |
978 } | |
979 | |
951 TF_BUILTIN(ArrayReduceRightLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 980 TF_BUILTIN(ArrayReduceRightLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
952 Node* context = Parameter(Descriptor::kContext); | 981 Node* context = Parameter(Descriptor::kContext); |
953 Node* receiver = Parameter(Descriptor::kReceiver); | 982 Node* receiver = Parameter(Descriptor::kReceiver); |
954 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 983 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
955 Node* this_arg = Parameter(Descriptor::kThisArg); | 984 Node* this_arg = Parameter(Descriptor::kThisArg); |
956 Node* accumulator = Parameter(Descriptor::kAccumulator); | 985 Node* accumulator = Parameter(Descriptor::kAccumulator); |
957 Node* object = Parameter(Descriptor::kObject); | 986 Node* object = Parameter(Descriptor::kObject); |
958 Node* initial_k = Parameter(Descriptor::kInitialK); | 987 Node* initial_k = Parameter(Descriptor::kInitialK); |
959 Node* len = Parameter(Descriptor::kLength); | 988 Node* len = Parameter(Descriptor::kLength); |
960 Node* to = Parameter(Descriptor::kTo); | 989 Node* to = Parameter(Descriptor::kTo); |
(...skipping 20 matching lines...) Expand all Loading... | |
981 | 1010 |
982 GenerateIteratingArrayBuiltinBody( | 1011 GenerateIteratingArrayBuiltinBody( |
983 "Array.prototype.reduceRight", | 1012 "Array.prototype.reduceRight", |
984 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, | 1013 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, |
985 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, | 1014 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, |
986 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, | 1015 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, |
987 CodeFactory::ArrayReduceRightLoopContinuation(isolate()), | 1016 CodeFactory::ArrayReduceRightLoopContinuation(isolate()), |
988 ForEachDirection::kReverse); | 1017 ForEachDirection::kReverse); |
989 } | 1018 } |
990 | 1019 |
1020 TF_BUILTIN(TypedArrayPrototypeReduceRight, ArrayBuiltinCodeStubAssembler) { | |
1021 Node* context = Parameter(Descriptor::kContext); | |
1022 Node* receiver = Parameter(Descriptor::kReceiver); | |
1023 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | |
1024 Node* initial_value = Parameter(Descriptor::kInitialValue); | |
1025 Node* new_target = Parameter(Descriptor::kNewTarget); | |
1026 | |
1027 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, initial_value, | |
1028 new_target); | |
1029 | |
1030 GenerateIteratingTypedArrayBuiltinBody( | |
1031 "%TypedArray%.prototype.reduceRight", | |
1032 &ArrayBuiltinCodeStubAssembler::ReduceResultGenerator, | |
1033 &ArrayBuiltinCodeStubAssembler::ReduceProcessor, | |
1034 &ArrayBuiltinCodeStubAssembler::ReducePostLoopAction, | |
1035 ForEachDirection::kReverse); | |
1036 } | |
1037 | |
991 TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 1038 TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
992 Node* context = Parameter(Descriptor::kContext); | 1039 Node* context = Parameter(Descriptor::kContext); |
993 Node* receiver = Parameter(Descriptor::kReceiver); | 1040 Node* receiver = Parameter(Descriptor::kReceiver); |
994 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 1041 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
995 Node* this_arg = Parameter(Descriptor::kThisArg); | 1042 Node* this_arg = Parameter(Descriptor::kThisArg); |
996 Node* array = Parameter(Descriptor::kArray); | 1043 Node* array = Parameter(Descriptor::kArray); |
997 Node* object = Parameter(Descriptor::kObject); | 1044 Node* object = Parameter(Descriptor::kObject); |
998 Node* initial_k = Parameter(Descriptor::kInitialK); | 1045 Node* initial_k = Parameter(Descriptor::kInitialK); |
999 Node* len = Parameter(Descriptor::kLength); | 1046 Node* len = Parameter(Descriptor::kLength); |
1000 Node* to = Parameter(Descriptor::kTo); | 1047 Node* to = Parameter(Descriptor::kTo); |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2117 { | 2164 { |
2118 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 2165 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); |
2119 CallRuntime(Runtime::kThrowTypeError, context, message, | 2166 CallRuntime(Runtime::kThrowTypeError, context, message, |
2120 HeapConstant(operation)); | 2167 HeapConstant(operation)); |
2121 Unreachable(); | 2168 Unreachable(); |
2122 } | 2169 } |
2123 } | 2170 } |
2124 | 2171 |
2125 } // namespace internal | 2172 } // namespace internal |
2126 } // namespace v8 | 2173 } // namespace v8 |
OLD | NEW |