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 { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 context_ = context; | 288 context_ = context; |
289 this_arg_ = this_arg; | 289 this_arg_ = this_arg; |
290 callbackfn_ = callbackfn; | 290 callbackfn_ = callbackfn; |
291 a_.Bind(a); | 291 a_.Bind(a); |
292 k_.Bind(initial_k); | 292 k_.Bind(initial_k); |
293 o_ = o; | 293 o_ = o; |
294 len_ = len; | 294 len_ = len; |
295 to_.Bind(to); | 295 to_.Bind(to); |
296 } | 296 } |
297 | 297 |
| 298 void GenerateIteratingTypedArrayBuiltinBody( |
| 299 const char* name, const BuiltinResultGenerator& generator, |
| 300 const CallResultProcessor& processor, const PostLoopAction& action) { |
| 301 Node* name_string = |
| 302 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); |
| 303 |
| 304 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray |
| 305 |
| 306 Label throw_not_typed_array(this, Label::kDeferred), |
| 307 throw_detached(this, Label::kDeferred); |
| 308 |
| 309 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array); |
| 310 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE), |
| 311 &throw_not_typed_array); |
| 312 |
| 313 o_ = receiver_; |
| 314 Node* array_buffer = LoadObjectField(o_, JSTypedArray::kBufferOffset); |
| 315 GotoIf(IsDetachedBuffer(array_buffer), &throw_detached); |
| 316 |
| 317 len_ = LoadObjectField(o_, JSTypedArray::kLengthOffset); |
| 318 |
| 319 Label throw_not_callable(this, Label::kDeferred); |
| 320 Label distinguish_types(this); |
| 321 GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable); |
| 322 Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types, |
| 323 &throw_not_callable); |
| 324 |
| 325 Bind(&throw_not_typed_array); |
| 326 { |
| 327 CallRuntime(Runtime::kThrowTypeError, context_, |
| 328 SmiConstant(MessageTemplate::kNotTypedArray)); |
| 329 Unreachable(); |
| 330 } |
| 331 |
| 332 Bind(&throw_detached); |
| 333 { |
| 334 CallRuntime(Runtime::kThrowTypeError, context_, |
| 335 SmiConstant(MessageTemplate::kDetachedOperation), |
| 336 name_string); |
| 337 Unreachable(); |
| 338 } |
| 339 |
| 340 Bind(&throw_not_callable); |
| 341 { |
| 342 CallRuntime(Runtime::kThrowTypeError, context_, |
| 343 SmiConstant(MessageTemplate::kCalledNonCallable), |
| 344 callbackfn_); |
| 345 Unreachable(); |
| 346 } |
| 347 |
| 348 Label unexpected_instance_type(this); |
| 349 Bind(&unexpected_instance_type); |
| 350 Unreachable(); |
| 351 |
| 352 std::vector<int32_t> instance_types = { |
| 353 #define INSTANCE_TYPE(Type, type, TYPE, ctype, size) FIXED_##TYPE##_ARRAY_TYPE, |
| 354 TYPED_ARRAYS(INSTANCE_TYPE) |
| 355 #undef INSTANCE_TYPE |
| 356 }; |
| 357 std::vector<Label> labels; |
| 358 for (size_t i = 0; i < instance_types.size(); ++i) { |
| 359 labels.push_back(Label(this)); |
| 360 } |
| 361 std::vector<Label*> label_ptrs; |
| 362 for (Label& label : labels) { |
| 363 label_ptrs.push_back(&label); |
| 364 } |
| 365 |
| 366 Bind(&distinguish_types); |
| 367 a_.Bind(generator(this)); |
| 368 Node* elements_type = LoadInstanceType(LoadElements(o_)); |
| 369 Switch(elements_type, &unexpected_instance_type, instance_types.data(), |
| 370 label_ptrs.data(), labels.size()); |
| 371 |
| 372 for (size_t i = 0; i < labels.size(); ++i) { |
| 373 Bind(&labels[i]); |
| 374 Label done(this); |
| 375 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a |
| 376 // spec violation. Should go to &detached and throw a TypeError instead. |
| 377 VisitAllTypedArrayElements( |
| 378 ElementsKindForInstanceType( |
| 379 static_cast<InstanceType>(instance_types[i])), |
| 380 array_buffer, processor, &done); |
| 381 Goto(&done); |
| 382 action(this); |
| 383 // No exception, return success |
| 384 Bind(&done); |
| 385 Return(a_.value()); |
| 386 } |
| 387 } |
| 388 |
298 void GenerateIteratingArrayBuiltinLoopContinuation( | 389 void GenerateIteratingArrayBuiltinLoopContinuation( |
299 const CallResultProcessor& processor, const PostLoopAction& action, | 390 const CallResultProcessor& processor, const PostLoopAction& action, |
300 ForEachDirection direction = ForEachDirection::kForward) { | 391 ForEachDirection direction = ForEachDirection::kForward) { |
301 Label loop(this, {&k_, &a_, &to_}); | 392 Label loop(this, {&k_, &a_, &to_}); |
302 Label after_loop(this); | 393 Label after_loop(this); |
303 Goto(&loop); | 394 Goto(&loop); |
304 Bind(&loop); | 395 Bind(&loop); |
305 { | 396 { |
306 if (direction == ForEachDirection::kForward) { | 397 if (direction == ForEachDirection::kForward) { |
307 // 8. Repeat, while k < len | 398 // 8. Repeat, while k < len |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 } | 434 } |
344 Goto(&loop); | 435 Goto(&loop); |
345 } | 436 } |
346 Bind(&after_loop); | 437 Bind(&after_loop); |
347 | 438 |
348 action(this); | 439 action(this); |
349 Return(a_.value()); | 440 Return(a_.value()); |
350 } | 441 } |
351 | 442 |
352 private: | 443 private: |
| 444 static ElementsKind ElementsKindForInstanceType(InstanceType type) { |
| 445 switch (type) { |
| 446 #define INSTANCE_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \ |
| 447 case FIXED_##TYPE##_ARRAY_TYPE: \ |
| 448 return TYPE##_ELEMENTS; |
| 449 |
| 450 TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENTS_KIND) |
| 451 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND |
| 452 |
| 453 default: |
| 454 UNREACHABLE(); |
| 455 return static_cast<ElementsKind>(-1); |
| 456 } |
| 457 } |
| 458 |
| 459 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer, |
| 460 const CallResultProcessor& processor, |
| 461 Label* detached) { |
| 462 VariableList list({&a_, &k_, &to_}, zone()); |
| 463 |
| 464 FastLoopBody body = [&](Node* index) { |
| 465 GotoIf(IsDetachedBuffer(array_buffer), detached); |
| 466 Node* elements = LoadElements(o_); |
| 467 Node* base_ptr = |
| 468 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); |
| 469 Node* external_ptr = |
| 470 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, |
| 471 MachineType::Pointer()); |
| 472 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); |
| 473 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind, |
| 474 SMI_PARAMETERS); |
| 475 k_.Bind(index); |
| 476 a_.Bind(processor(this, value, index)); |
| 477 }; |
| 478 BuildFastLoop(list, SmiConstant(0), len_, body, 1, |
| 479 ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost); |
| 480 } |
| 481 |
353 void VisitAllFastElementsOneKind(ElementsKind kind, | 482 void VisitAllFastElementsOneKind(ElementsKind kind, |
354 const CallResultProcessor& processor, | 483 const CallResultProcessor& processor, |
355 Label* array_changed, ParameterMode mode, | 484 Label* array_changed, ParameterMode mode, |
356 ForEachDirection direction) { | 485 ForEachDirection direction) { |
357 Comment("begin VisitAllFastElementsOneKind"); | 486 Comment("begin VisitAllFastElementsOneKind"); |
358 Variable original_map(this, MachineRepresentation::kTagged); | 487 Variable original_map(this, MachineRepresentation::kTagged); |
359 original_map.Bind(LoadMap(o())); | 488 original_map.Bind(LoadMap(o())); |
360 VariableList list({&original_map, &a_, &k_, &to_}, zone()); | 489 VariableList list({&original_map, &a_, &k_, &to_}, zone()); |
361 Node* start = IntPtrOrSmiConstant(0, mode); | 490 Node* start = IntPtrOrSmiConstant(0, mode); |
362 Node* end = TaggedToParameter(len(), mode); | 491 Node* end = TaggedToParameter(len(), mode); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 new_target); | 831 new_target); |
703 | 832 |
704 GenerateIteratingArrayBuiltinBody( | 833 GenerateIteratingArrayBuiltinBody( |
705 "Array.prototype.some", | 834 "Array.prototype.some", |
706 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, | 835 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, |
707 &ArrayBuiltinCodeStubAssembler::SomeProcessor, | 836 &ArrayBuiltinCodeStubAssembler::SomeProcessor, |
708 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, | 837 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, |
709 CodeFactory::ArraySomeLoopContinuation(isolate())); | 838 CodeFactory::ArraySomeLoopContinuation(isolate())); |
710 } | 839 } |
711 | 840 |
| 841 TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) { |
| 842 Node* context = Parameter(Descriptor::kContext); |
| 843 Node* receiver = Parameter(Descriptor::kReceiver); |
| 844 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 845 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 846 Node* new_target = Parameter(Descriptor::kNewTarget); |
| 847 |
| 848 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, |
| 849 new_target); |
| 850 |
| 851 GenerateIteratingTypedArrayBuiltinBody( |
| 852 "%TypedArray%.prototype.some", |
| 853 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, |
| 854 &ArrayBuiltinCodeStubAssembler::SomeProcessor, |
| 855 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction); |
| 856 } |
| 857 |
712 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 858 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
713 Node* context = Parameter(Descriptor::kContext); | 859 Node* context = Parameter(Descriptor::kContext); |
714 Node* receiver = Parameter(Descriptor::kReceiver); | 860 Node* receiver = Parameter(Descriptor::kReceiver); |
715 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 861 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
716 Node* this_arg = Parameter(Descriptor::kThisArg); | 862 Node* this_arg = Parameter(Descriptor::kThisArg); |
717 Node* array = Parameter(Descriptor::kArray); | 863 Node* array = Parameter(Descriptor::kArray); |
718 Node* object = Parameter(Descriptor::kObject); | 864 Node* object = Parameter(Descriptor::kObject); |
719 Node* initial_k = Parameter(Descriptor::kInitialK); | 865 Node* initial_k = Parameter(Descriptor::kInitialK); |
720 Node* len = Parameter(Descriptor::kLength); | 866 Node* len = Parameter(Descriptor::kLength); |
721 Node* to = Parameter(Descriptor::kTo); | 867 Node* to = Parameter(Descriptor::kTo); |
(...skipping 18 matching lines...) Expand all Loading... |
740 new_target); | 886 new_target); |
741 | 887 |
742 GenerateIteratingArrayBuiltinBody( | 888 GenerateIteratingArrayBuiltinBody( |
743 "Array.prototype.every", | 889 "Array.prototype.every", |
744 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, | 890 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, |
745 &ArrayBuiltinCodeStubAssembler::EveryProcessor, | 891 &ArrayBuiltinCodeStubAssembler::EveryProcessor, |
746 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, | 892 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, |
747 CodeFactory::ArrayEveryLoopContinuation(isolate())); | 893 CodeFactory::ArrayEveryLoopContinuation(isolate())); |
748 } | 894 } |
749 | 895 |
| 896 TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) { |
| 897 Node* context = Parameter(Descriptor::kContext); |
| 898 Node* receiver = Parameter(Descriptor::kReceiver); |
| 899 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 900 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 901 Node* new_target = Parameter(Descriptor::kNewTarget); |
| 902 |
| 903 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, |
| 904 new_target); |
| 905 |
| 906 GenerateIteratingTypedArrayBuiltinBody( |
| 907 "%TypedArray%.prototype.every", |
| 908 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, |
| 909 &ArrayBuiltinCodeStubAssembler::EveryProcessor, |
| 910 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction); |
| 911 } |
| 912 |
750 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 913 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
751 Node* context = Parameter(Descriptor::kContext); | 914 Node* context = Parameter(Descriptor::kContext); |
752 Node* receiver = Parameter(Descriptor::kReceiver); | 915 Node* receiver = Parameter(Descriptor::kReceiver); |
753 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 916 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
754 Node* this_arg = Parameter(Descriptor::kThisArg); | 917 Node* this_arg = Parameter(Descriptor::kThisArg); |
755 Node* accumulator = Parameter(Descriptor::kAccumulator); | 918 Node* accumulator = Parameter(Descriptor::kAccumulator); |
756 Node* object = Parameter(Descriptor::kObject); | 919 Node* object = Parameter(Descriptor::kObject); |
757 Node* initial_k = Parameter(Descriptor::kInitialK); | 920 Node* initial_k = Parameter(Descriptor::kInitialK); |
758 Node* len = Parameter(Descriptor::kLength); | 921 Node* len = Parameter(Descriptor::kLength); |
759 Node* to = Parameter(Descriptor::kTo); | 922 Node* to = Parameter(Descriptor::kTo); |
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1954 { | 2117 { |
1955 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 2118 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); |
1956 CallRuntime(Runtime::kThrowTypeError, context, message, | 2119 CallRuntime(Runtime::kThrowTypeError, context, message, |
1957 HeapConstant(operation)); | 2120 HeapConstant(operation)); |
1958 Unreachable(); | 2121 Unreachable(); |
1959 } | 2122 } |
1960 } | 2123 } |
1961 | 2124 |
1962 } // namespace internal | 2125 } // namespace internal |
1963 } // namespace v8 | 2126 } // namespace v8 |
OLD | NEW |