| 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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 context_ = context; | 282 context_ = context; |
| 283 this_arg_ = this_arg; | 283 this_arg_ = this_arg; |
| 284 callbackfn_ = callbackfn; | 284 callbackfn_ = callbackfn; |
| 285 a_.Bind(a); | 285 a_.Bind(a); |
| 286 k_.Bind(initial_k); | 286 k_.Bind(initial_k); |
| 287 o_ = o; | 287 o_ = o; |
| 288 len_ = len; | 288 len_ = len; |
| 289 to_.Bind(to); | 289 to_.Bind(to); |
| 290 } | 290 } |
| 291 | 291 |
| 292 void GenerateIteratingTypedArrayBuiltinBody( |
| 293 const char* name, const BuiltinResultGenerator& generator, |
| 294 const CallResultProcessor& processor, const PostLoopAction& action) { |
| 295 Node* name_string = |
| 296 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)); |
| 297 |
| 298 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray |
| 299 |
| 300 Label not_typed_array(this, Label::kDeferred), |
| 301 detached(this, Label::kDeferred); |
| 302 |
| 303 GotoIf(TaggedIsSmi(receiver_), ¬_typed_array); |
| 304 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE), |
| 305 ¬_typed_array); |
| 306 |
| 307 o_ = receiver_; |
| 308 Node* array_buffer = LoadObjectField(o_, JSTypedArray::kBufferOffset); |
| 309 GotoIf(IsDetachedBuffer(array_buffer), &detached); |
| 310 |
| 311 len_ = LoadObjectField(o_, JSTypedArray::kLengthOffset); |
| 312 |
| 313 Label not_callable(this, Label::kDeferred); |
| 314 Label start(this); |
| 315 GotoIf(TaggedIsSmi(callbackfn_), ¬_callable); |
| 316 Branch(IsCallableMap(LoadMap(callbackfn_)), &start, ¬_callable); |
| 317 |
| 318 Bind(¬_typed_array); |
| 319 { |
| 320 CallRuntime(Runtime::kThrowTypeError, context_, |
| 321 SmiConstant(MessageTemplate::kNotTypedArray)); |
| 322 Unreachable(); |
| 323 } |
| 324 |
| 325 Bind(&detached); |
| 326 { |
| 327 CallRuntime(Runtime::kThrowTypeError, context_, |
| 328 SmiConstant(MessageTemplate::kDetachedOperation), |
| 329 name_string); |
| 330 Unreachable(); |
| 331 } |
| 332 |
| 333 Bind(¬_callable); |
| 334 { |
| 335 CallRuntime(Runtime::kThrowTypeError, context_, |
| 336 SmiConstant(MessageTemplate::kCalledNonCallable), |
| 337 callbackfn_); |
| 338 Unreachable(); |
| 339 } |
| 340 |
| 341 Label unexpected_instance_type(this); |
| 342 Bind(&unexpected_instance_type); |
| 343 Unreachable(); |
| 344 |
| 345 std::vector<int32_t> instance_types = { |
| 346 #define INSTANCE_TYPE(Type, type, TYPE, ctype, size) FIXED_##TYPE##_ARRAY_TYPE, |
| 347 TYPED_ARRAYS(INSTANCE_TYPE) |
| 348 #undef INSTANCE_TYPE |
| 349 }; |
| 350 std::vector<Label> labels; |
| 351 for (size_t i = 0; i < instance_types.size(); ++i) { |
| 352 labels.push_back(Label(this)); |
| 353 } |
| 354 std::vector<Label*> label_ptrs; |
| 355 for (Label& label : labels) { |
| 356 label_ptrs.push_back(&label); |
| 357 } |
| 358 |
| 359 Bind(&start); |
| 360 a_.Bind(generator(this)); |
| 361 Node* elements_type = LoadInstanceType(LoadElements(o_)); |
| 362 Switch(elements_type, &unexpected_instance_type, instance_types.data(), |
| 363 label_ptrs.data(), labels.size()); |
| 364 |
| 365 for (size_t i = 0; i < labels.size(); ++i) { |
| 366 Bind(&labels[i]); |
| 367 Label done(this); |
| 368 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a |
| 369 // spec violation. Should go to &detached and throw a TypeError instead. |
| 370 VisitAllTypedArrayElements( |
| 371 ElementsKindForInstanceType( |
| 372 static_cast<InstanceType>(instance_types[i])), |
| 373 array_buffer, processor, &done); |
| 374 Goto(&done); |
| 375 action(this); |
| 376 // No exception, return success |
| 377 Bind(&done); |
| 378 Return(a_.value()); |
| 379 } |
| 380 } |
| 381 |
| 292 void GenerateIteratingArrayBuiltinLoopContinuation( | 382 void GenerateIteratingArrayBuiltinLoopContinuation( |
| 293 const CallResultProcessor& processor, const PostLoopAction& action) { | 383 const CallResultProcessor& processor, const PostLoopAction& action) { |
| 294 // 8. Repeat, while k < len | 384 // 8. Repeat, while k < len |
| 295 Label loop(this, {&k_, &a_, &to_}); | 385 Label loop(this, {&k_, &a_, &to_}); |
| 296 Label after_loop(this); | 386 Label after_loop(this); |
| 297 Goto(&loop); | 387 Goto(&loop); |
| 298 Bind(&loop); | 388 Bind(&loop); |
| 299 { | 389 { |
| 300 GotoUnlessNumberLessThan(k(), len_, &after_loop); | 390 GotoUnlessNumberLessThan(k(), len_, &after_loop); |
| 301 | 391 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 325 k_.Bind(NumberInc(k_.value())); | 415 k_.Bind(NumberInc(k_.value())); |
| 326 Goto(&loop); | 416 Goto(&loop); |
| 327 } | 417 } |
| 328 Bind(&after_loop); | 418 Bind(&after_loop); |
| 329 | 419 |
| 330 action(this); | 420 action(this); |
| 331 Return(a_.value()); | 421 Return(a_.value()); |
| 332 } | 422 } |
| 333 | 423 |
| 334 private: | 424 private: |
| 425 static ElementsKind ElementsKindForInstanceType(InstanceType type) { |
| 426 switch (type) { |
| 427 #define INSTANCE_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \ |
| 428 case FIXED_##TYPE##_ARRAY_TYPE: \ |
| 429 return TYPE##_ELEMENTS; |
| 430 |
| 431 TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENTS_KIND) |
| 432 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND |
| 433 |
| 434 default: |
| 435 UNREACHABLE(); |
| 436 return static_cast<ElementsKind>(-1); |
| 437 } |
| 438 } |
| 439 |
| 440 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer, |
| 441 const CallResultProcessor& processor, |
| 442 Label* detached) { |
| 443 Node* elements = LoadElements(o_); |
| 444 Node* base_ptr = |
| 445 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); |
| 446 Node* external_ptr = |
| 447 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, |
| 448 MachineType::Pointer()); |
| 449 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); |
| 450 VariableList list({&a_, &k_, &to_}, zone()); |
| 451 BuildFastLoop(list, SmiConstant(0), len_, |
| 452 [&](Node* index) { |
| 453 GotoIf(IsDetachedBuffer(array_buffer), detached); |
| 454 Node* value = LoadFixedTypedArrayElementAsTagged( |
| 455 data_ptr, index, kind, SMI_PARAMETERS); |
| 456 k_.Bind(index); |
| 457 a_.Bind(processor(this, value, index)); |
| 458 }, |
| 459 1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost); |
| 460 } |
| 461 |
| 335 void VisitAllFastElementsOneKind(ElementsKind kind, | 462 void VisitAllFastElementsOneKind(ElementsKind kind, |
| 336 const CallResultProcessor& processor, | 463 const CallResultProcessor& processor, |
| 337 Label* array_changed, ParameterMode mode) { | 464 Label* array_changed, ParameterMode mode) { |
| 338 Comment("begin VisitAllFastElementsOneKind"); | 465 Comment("begin VisitAllFastElementsOneKind"); |
| 339 Variable original_map(this, MachineRepresentation::kTagged); | 466 Variable original_map(this, MachineRepresentation::kTagged); |
| 340 original_map.Bind(LoadMap(o())); | 467 original_map.Bind(LoadMap(o())); |
| 341 VariableList list({&original_map, &a_, &k_, &to_}, zone()); | 468 VariableList list({&original_map, &a_, &k_, &to_}, zone()); |
| 342 BuildFastLoop( | 469 BuildFastLoop( |
| 343 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len(), mode), | 470 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len(), mode), |
| 344 [=, &original_map](Node* index) { | 471 [=, &original_map](Node* index) { |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 new_target); | 801 new_target); |
| 675 | 802 |
| 676 GenerateIteratingArrayBuiltinBody( | 803 GenerateIteratingArrayBuiltinBody( |
| 677 "Array.prototype.some", | 804 "Array.prototype.some", |
| 678 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, | 805 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, |
| 679 &ArrayBuiltinCodeStubAssembler::SomeProcessor, | 806 &ArrayBuiltinCodeStubAssembler::SomeProcessor, |
| 680 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, | 807 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, |
| 681 CodeFactory::ArraySomeLoopContinuation(isolate())); | 808 CodeFactory::ArraySomeLoopContinuation(isolate())); |
| 682 } | 809 } |
| 683 | 810 |
| 811 TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) { |
| 812 Node* context = Parameter(Descriptor::kContext); |
| 813 Node* receiver = Parameter(Descriptor::kReceiver); |
| 814 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 815 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 816 Node* new_target = Parameter(Descriptor::kNewTarget); |
| 817 |
| 818 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, |
| 819 new_target); |
| 820 |
| 821 GenerateIteratingTypedArrayBuiltinBody( |
| 822 "%TypedArray%.prototype.some", |
| 823 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, |
| 824 &ArrayBuiltinCodeStubAssembler::SomeProcessor, |
| 825 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction); |
| 826 } |
| 827 |
| 684 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 828 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
| 685 Node* context = Parameter(Descriptor::kContext); | 829 Node* context = Parameter(Descriptor::kContext); |
| 686 Node* receiver = Parameter(Descriptor::kReceiver); | 830 Node* receiver = Parameter(Descriptor::kReceiver); |
| 687 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 831 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 688 Node* this_arg = Parameter(Descriptor::kThisArg); | 832 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 689 Node* array = Parameter(Descriptor::kArray); | 833 Node* array = Parameter(Descriptor::kArray); |
| 690 Node* object = Parameter(Descriptor::kObject); | 834 Node* object = Parameter(Descriptor::kObject); |
| 691 Node* initial_k = Parameter(Descriptor::kInitialK); | 835 Node* initial_k = Parameter(Descriptor::kInitialK); |
| 692 Node* len = Parameter(Descriptor::kLength); | 836 Node* len = Parameter(Descriptor::kLength); |
| 693 Node* to = Parameter(Descriptor::kTo); | 837 Node* to = Parameter(Descriptor::kTo); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 712 new_target); | 856 new_target); |
| 713 | 857 |
| 714 GenerateIteratingArrayBuiltinBody( | 858 GenerateIteratingArrayBuiltinBody( |
| 715 "Array.prototype.every", | 859 "Array.prototype.every", |
| 716 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, | 860 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, |
| 717 &ArrayBuiltinCodeStubAssembler::EveryProcessor, | 861 &ArrayBuiltinCodeStubAssembler::EveryProcessor, |
| 718 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, | 862 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, |
| 719 CodeFactory::ArrayEveryLoopContinuation(isolate())); | 863 CodeFactory::ArrayEveryLoopContinuation(isolate())); |
| 720 } | 864 } |
| 721 | 865 |
| 866 TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) { |
| 867 Node* context = Parameter(Descriptor::kContext); |
| 868 Node* receiver = Parameter(Descriptor::kReceiver); |
| 869 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 870 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 871 Node* new_target = Parameter(Descriptor::kNewTarget); |
| 872 |
| 873 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, |
| 874 new_target); |
| 875 |
| 876 GenerateIteratingTypedArrayBuiltinBody( |
| 877 "%TypedArray%.prototype.every", |
| 878 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, |
| 879 &ArrayBuiltinCodeStubAssembler::EveryProcessor, |
| 880 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction); |
| 881 } |
| 882 |
| 722 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 883 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { |
| 723 Node* context = Parameter(Descriptor::kContext); | 884 Node* context = Parameter(Descriptor::kContext); |
| 724 Node* receiver = Parameter(Descriptor::kReceiver); | 885 Node* receiver = Parameter(Descriptor::kReceiver); |
| 725 Node* callbackfn = Parameter(Descriptor::kCallbackFn); | 886 Node* callbackfn = Parameter(Descriptor::kCallbackFn); |
| 726 Node* this_arg = Parameter(Descriptor::kThisArg); | 887 Node* this_arg = Parameter(Descriptor::kThisArg); |
| 727 Node* accumulator = Parameter(Descriptor::kAccumulator); | 888 Node* accumulator = Parameter(Descriptor::kAccumulator); |
| 728 Node* object = Parameter(Descriptor::kObject); | 889 Node* object = Parameter(Descriptor::kObject); |
| 729 Node* initial_k = Parameter(Descriptor::kInitialK); | 890 Node* initial_k = Parameter(Descriptor::kInitialK); |
| 730 Node* len = Parameter(Descriptor::kLength); | 891 Node* len = Parameter(Descriptor::kLength); |
| 731 Node* to = Parameter(Descriptor::kTo); | 892 Node* to = Parameter(Descriptor::kTo); |
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 { | 2047 { |
| 1887 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 2048 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); |
| 1888 CallRuntime(Runtime::kThrowTypeError, context, message, | 2049 CallRuntime(Runtime::kThrowTypeError, context, message, |
| 1889 HeapConstant(operation)); | 2050 HeapConstant(operation)); |
| 1890 Unreachable(); | 2051 Unreachable(); |
| 1891 } | 2052 } |
| 1892 } | 2053 } |
| 1893 | 2054 |
| 1894 } // namespace internal | 2055 } // namespace internal |
| 1895 } // namespace v8 | 2056 } // namespace v8 |
| OLD | NEW |