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 |