OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/base/macros.h" | 5 #include "src/base/macros.h" |
6 #include "src/base/platform/mutex.h" | 6 #include "src/base/platform/mutex.h" |
7 #include "src/base/platform/time.h" | 7 #include "src/base/platform/time.h" |
8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
9 #include "src/builtins/builtins.h" | 9 #include "src/builtins/builtins.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 } | 631 } |
632 | 632 |
633 template <typename T> | 633 template <typename T> |
634 inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, | 634 inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, |
635 Handle<Object> obj) { | 635 Handle<Object> obj) { |
636 T value = FromObject<T>(obj); | 636 T value = FromObject<T>(obj); |
637 T result = ExchangeSeqCst(static_cast<T*>(buffer) + index, value); | 637 T result = ExchangeSeqCst(static_cast<T*>(buffer) + index, value); |
638 return ToObject(isolate, result); | 638 return ToObject(isolate, result); |
639 } | 639 } |
640 | 640 |
| 641 // Uint8Clamped functions |
| 642 |
| 643 uint8_t ClampToUint8(int32_t value) { |
| 644 if (value < 0) return 0; |
| 645 if (value > 255) return 255; |
| 646 return value; |
| 647 } |
| 648 |
| 649 inline Object* DoCompareExchangeUint8Clamped(Isolate* isolate, void* buffer, |
| 650 size_t index, |
| 651 Handle<Object> oldobj, |
| 652 Handle<Object> newobj) { |
| 653 typedef int32_t convert_type; |
| 654 uint8_t oldval = ClampToUint8(FromObject<convert_type>(oldobj)); |
| 655 uint8_t newval = ClampToUint8(FromObject<convert_type>(newobj)); |
| 656 uint8_t result = CompareExchangeSeqCst(static_cast<uint8_t*>(buffer) + index, |
| 657 oldval, newval); |
| 658 return ToObject(isolate, result); |
| 659 } |
| 660 |
| 661 #define DO_UINT8_CLAMPED_OP(name, op) \ |
| 662 inline Object* Do##name##Uint8Clamped(Isolate* isolate, void* buffer, \ |
| 663 size_t index, Handle<Object> obj) { \ |
| 664 typedef int32_t convert_type; \ |
| 665 uint8_t* p = static_cast<uint8_t*>(buffer) + index; \ |
| 666 convert_type operand = FromObject<convert_type>(obj); \ |
| 667 uint8_t expected; \ |
| 668 uint8_t result; \ |
| 669 do { \ |
| 670 expected = *p; \ |
| 671 result = ClampToUint8(static_cast<convert_type>(expected) op operand); \ |
| 672 } while (CompareExchangeSeqCst(p, expected, result) != expected); \ |
| 673 return ToObject(isolate, expected); \ |
| 674 } |
| 675 |
| 676 DO_UINT8_CLAMPED_OP(Add, +) |
| 677 DO_UINT8_CLAMPED_OP(Sub, -) |
| 678 DO_UINT8_CLAMPED_OP(And, &) |
| 679 DO_UINT8_CLAMPED_OP(Or, |) |
| 680 DO_UINT8_CLAMPED_OP(Xor, ^) |
| 681 |
| 682 #undef DO_UINT8_CLAMPED_OP |
| 683 |
| 684 inline Object* DoExchangeUint8Clamped(Isolate* isolate, void* buffer, |
| 685 size_t index, Handle<Object> obj) { |
| 686 typedef int32_t convert_type; |
| 687 uint8_t* p = static_cast<uint8_t*>(buffer) + index; |
| 688 uint8_t result = ClampToUint8(FromObject<convert_type>(obj)); |
| 689 uint8_t expected; |
| 690 do { |
| 691 expected = *p; |
| 692 } while (CompareExchangeSeqCst(p, expected, result) != expected); |
| 693 return ToObject(isolate, expected); |
| 694 } |
| 695 |
641 } // anonymous namespace | 696 } // anonymous namespace |
642 | 697 |
643 // Duplicated from objects.h | 698 // Duplicated from objects.h |
644 // V has parameters (Type, type, TYPE, C type, element_size) | 699 // V has parameters (Type, type, TYPE, C type, element_size) |
645 #define INTEGER_TYPED_ARRAYS(V) \ | 700 #define INTEGER_TYPED_ARRAYS(V) \ |
646 V(Uint8, uint8, UINT8, uint8_t, 1) \ | 701 V(Uint8, uint8, UINT8, uint8_t, 1) \ |
647 V(Int8, int8, INT8, int8_t, 1) \ | 702 V(Int8, int8, INT8, int8_t, 1) \ |
648 V(Uint16, uint16, UINT16, uint16_t, 2) \ | 703 V(Uint16, uint16, UINT16, uint16_t, 2) \ |
649 V(Int16, int16, INT16, int16_t, 2) \ | 704 V(Int16, int16, INT16, int16_t, 2) \ |
650 V(Uint32, uint32, UINT32, uint32_t, 4) \ | 705 V(Uint32, uint32, UINT32, uint32_t, 4) \ |
(...skipping 28 matching lines...) Expand all Loading... |
679 switch (sta->type()) { | 734 switch (sta->type()) { |
680 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 735 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
681 case kExternal##Type##Array: \ | 736 case kExternal##Type##Array: \ |
682 return DoCompareExchange<ctype>(isolate, source, i, expectedValue, \ | 737 return DoCompareExchange<ctype>(isolate, source, i, expectedValue, \ |
683 replacementValue); | 738 replacementValue); |
684 | 739 |
685 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 740 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
686 #undef TYPED_ARRAY_CASE | 741 #undef TYPED_ARRAY_CASE |
687 | 742 |
688 case kExternalUint8ClampedArray: | 743 case kExternalUint8ClampedArray: |
689 UNREACHABLE(); | 744 return DoCompareExchangeUint8Clamped(isolate, source, i, expectedValue, |
| 745 replacementValue); |
690 | 746 |
691 default: | 747 default: |
692 break; | 748 break; |
693 } | 749 } |
694 | 750 |
695 UNREACHABLE(); | 751 UNREACHABLE(); |
696 return isolate->heap()->undefined_value(); | 752 return isolate->heap()->undefined_value(); |
697 } | 753 } |
698 | 754 |
699 // ES #sec-atomics.add | 755 // ES #sec-atomics.add |
(...skipping 20 matching lines...) Expand all Loading... |
720 | 776 |
721 switch (sta->type()) { | 777 switch (sta->type()) { |
722 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 778 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
723 case kExternal##Type##Array: \ | 779 case kExternal##Type##Array: \ |
724 return DoAdd<ctype>(isolate, source, i, value); | 780 return DoAdd<ctype>(isolate, source, i, value); |
725 | 781 |
726 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 782 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
727 #undef TYPED_ARRAY_CASE | 783 #undef TYPED_ARRAY_CASE |
728 | 784 |
729 case kExternalUint8ClampedArray: | 785 case kExternalUint8ClampedArray: |
730 UNREACHABLE(); | 786 return DoAddUint8Clamped(isolate, source, i, value); |
731 | 787 |
732 default: | 788 default: |
733 break; | 789 break; |
734 } | 790 } |
735 | 791 |
736 UNREACHABLE(); | 792 UNREACHABLE(); |
737 return isolate->heap()->undefined_value(); | 793 return isolate->heap()->undefined_value(); |
738 } | 794 } |
739 | 795 |
740 // ES #sec-atomics.sub | 796 // ES #sec-atomics.sub |
(...skipping 20 matching lines...) Expand all Loading... |
761 | 817 |
762 switch (sta->type()) { | 818 switch (sta->type()) { |
763 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 819 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
764 case kExternal##Type##Array: \ | 820 case kExternal##Type##Array: \ |
765 return DoSub<ctype>(isolate, source, i, value); | 821 return DoSub<ctype>(isolate, source, i, value); |
766 | 822 |
767 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 823 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
768 #undef TYPED_ARRAY_CASE | 824 #undef TYPED_ARRAY_CASE |
769 | 825 |
770 case kExternalUint8ClampedArray: | 826 case kExternalUint8ClampedArray: |
771 UNREACHABLE(); | 827 return DoSubUint8Clamped(isolate, source, i, value); |
772 | 828 |
773 default: | 829 default: |
774 break; | 830 break; |
775 } | 831 } |
776 | 832 |
777 UNREACHABLE(); | 833 UNREACHABLE(); |
778 return isolate->heap()->undefined_value(); | 834 return isolate->heap()->undefined_value(); |
779 } | 835 } |
780 | 836 |
781 // ES #sec-atomics.and | 837 // ES #sec-atomics.and |
(...skipping 20 matching lines...) Expand all Loading... |
802 | 858 |
803 switch (sta->type()) { | 859 switch (sta->type()) { |
804 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 860 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
805 case kExternal##Type##Array: \ | 861 case kExternal##Type##Array: \ |
806 return DoAnd<ctype>(isolate, source, i, value); | 862 return DoAnd<ctype>(isolate, source, i, value); |
807 | 863 |
808 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 864 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
809 #undef TYPED_ARRAY_CASE | 865 #undef TYPED_ARRAY_CASE |
810 | 866 |
811 case kExternalUint8ClampedArray: | 867 case kExternalUint8ClampedArray: |
812 UNREACHABLE(); | 868 return DoAndUint8Clamped(isolate, source, i, value); |
813 | 869 |
814 default: | 870 default: |
815 break; | 871 break; |
816 } | 872 } |
817 | 873 |
818 UNREACHABLE(); | 874 UNREACHABLE(); |
819 return isolate->heap()->undefined_value(); | 875 return isolate->heap()->undefined_value(); |
820 } | 876 } |
821 | 877 |
822 // ES #sec-atomics.or | 878 // ES #sec-atomics.or |
(...skipping 20 matching lines...) Expand all Loading... |
843 | 899 |
844 switch (sta->type()) { | 900 switch (sta->type()) { |
845 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 901 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
846 case kExternal##Type##Array: \ | 902 case kExternal##Type##Array: \ |
847 return DoOr<ctype>(isolate, source, i, value); | 903 return DoOr<ctype>(isolate, source, i, value); |
848 | 904 |
849 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 905 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
850 #undef TYPED_ARRAY_CASE | 906 #undef TYPED_ARRAY_CASE |
851 | 907 |
852 case kExternalUint8ClampedArray: | 908 case kExternalUint8ClampedArray: |
853 UNREACHABLE(); | 909 return DoOrUint8Clamped(isolate, source, i, value); |
854 | 910 |
855 default: | 911 default: |
856 break; | 912 break; |
857 } | 913 } |
858 | 914 |
859 UNREACHABLE(); | 915 UNREACHABLE(); |
860 return isolate->heap()->undefined_value(); | 916 return isolate->heap()->undefined_value(); |
861 } | 917 } |
862 | 918 |
863 // ES #sec-atomics.xor | 919 // ES #sec-atomics.xor |
(...skipping 20 matching lines...) Expand all Loading... |
884 | 940 |
885 switch (sta->type()) { | 941 switch (sta->type()) { |
886 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 942 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
887 case kExternal##Type##Array: \ | 943 case kExternal##Type##Array: \ |
888 return DoXor<ctype>(isolate, source, i, value); | 944 return DoXor<ctype>(isolate, source, i, value); |
889 | 945 |
890 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 946 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
891 #undef TYPED_ARRAY_CASE | 947 #undef TYPED_ARRAY_CASE |
892 | 948 |
893 case kExternalUint8ClampedArray: | 949 case kExternalUint8ClampedArray: |
894 UNREACHABLE(); | 950 return DoXorUint8Clamped(isolate, source, i, value); |
895 | 951 |
896 default: | 952 default: |
897 break; | 953 break; |
898 } | 954 } |
899 | 955 |
900 UNREACHABLE(); | 956 UNREACHABLE(); |
901 return isolate->heap()->undefined_value(); | 957 return isolate->heap()->undefined_value(); |
902 } | 958 } |
903 | 959 |
904 // ES #sec-atomics.exchange | 960 // ES #sec-atomics.exchange |
(...skipping 20 matching lines...) Expand all Loading... |
925 | 981 |
926 switch (sta->type()) { | 982 switch (sta->type()) { |
927 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ | 983 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ |
928 case kExternal##Type##Array: \ | 984 case kExternal##Type##Array: \ |
929 return DoExchange<ctype>(isolate, source, i, value); | 985 return DoExchange<ctype>(isolate, source, i, value); |
930 | 986 |
931 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) | 987 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
932 #undef TYPED_ARRAY_CASE | 988 #undef TYPED_ARRAY_CASE |
933 | 989 |
934 case kExternalUint8ClampedArray: | 990 case kExternalUint8ClampedArray: |
935 UNREACHABLE(); | 991 return DoExchangeUint8Clamped(isolate, source, i, value); |
936 | 992 |
937 default: | 993 default: |
938 break; | 994 break; |
939 } | 995 } |
940 | 996 |
941 UNREACHABLE(); | 997 UNREACHABLE(); |
942 return isolate->heap()->undefined_value(); | 998 return isolate->heap()->undefined_value(); |
943 } | 999 } |
944 | 1000 |
945 } // namespace internal | 1001 } // namespace internal |
946 } // namespace v8 | 1002 } // namespace v8 |
OLD | NEW |