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