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 |