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/value-serializer.h" | 5 #include "src/value-serializer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "include/v8.h" | 10 #include "include/v8.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 const OutputFunctor& output_functor) { | 168 const OutputFunctor& output_functor) { |
169 Local<Context> context = deserialization_context(); | 169 Local<Context> context = deserialization_context(); |
170 Context::Scope scope(context); | 170 Context::Scope scope(context); |
171 TryCatch try_catch(isolate()); | 171 TryCatch try_catch(isolate()); |
172 ValueDeserializer deserializer(isolate(), &data[0], | 172 ValueDeserializer deserializer(isolate(), &data[0], |
173 static_cast<int>(data.size()), | 173 static_cast<int>(data.size()), |
174 GetDeserializerDelegate()); | 174 GetDeserializerDelegate()); |
175 deserializer.SetSupportsLegacyWireFormat(true); | 175 deserializer.SetSupportsLegacyWireFormat(true); |
176 BeforeDecode(&deserializer); | 176 BeforeDecode(&deserializer); |
177 ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false)); | 177 ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false)); |
178 ASSERT_EQ(0, deserializer.GetWireFormatVersion()); | 178 ASSERT_EQ(0u, deserializer.GetWireFormatVersion()); |
179 Local<Value> result; | 179 Local<Value> result; |
180 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result)); | 180 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result)); |
181 ASSERT_FALSE(result.IsEmpty()); | 181 ASSERT_FALSE(result.IsEmpty()); |
182 ASSERT_FALSE(try_catch.HasCaught()); | 182 ASSERT_FALSE(try_catch.HasCaught()); |
183 ASSERT_TRUE( | 183 ASSERT_TRUE( |
184 context->Global() | 184 context->Global() |
185 ->CreateDataProperty(context, StringFromUtf8("result"), result) | 185 ->CreateDataProperty(context, StringFromUtf8("result"), result) |
186 .FromMaybe(false)); | 186 .FromMaybe(false)); |
187 output_functor(result); | 187 output_functor(result); |
188 ASSERT_FALSE(try_catch.HasCaught()); | 188 ASSERT_FALSE(try_catch.HasCaught()); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 "Object.getOwnPropertyNames(result).toString() === '42,a'")); | 795 "Object.getOwnPropertyNames(result).toString() === '42,a'")); |
796 EXPECT_TRUE(EvaluateScriptForResultBool("result[42] === 'a'")); | 796 EXPECT_TRUE(EvaluateScriptForResultBool("result[42] === 'a'")); |
797 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === 42")); | 797 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === 42")); |
798 }); | 798 }); |
799 } | 799 } |
800 | 800 |
801 TEST_F(ValueSerializerTest, RoundTripArray) { | 801 TEST_F(ValueSerializerTest, RoundTripArray) { |
802 // A simple array of integers. | 802 // A simple array of integers. |
803 RoundTripTest("[1, 2, 3, 4, 5]", [this](Local<Value> value) { | 803 RoundTripTest("[1, 2, 3, 4, 5]", [this](Local<Value> value) { |
804 ASSERT_TRUE(value->IsArray()); | 804 ASSERT_TRUE(value->IsArray()); |
805 EXPECT_EQ(5, Array::Cast(*value)->Length()); | 805 EXPECT_EQ(5u, Array::Cast(*value)->Length()); |
806 EXPECT_TRUE(EvaluateScriptForResultBool( | 806 EXPECT_TRUE(EvaluateScriptForResultBool( |
807 "Object.getPrototypeOf(result) === Array.prototype")); | 807 "Object.getPrototypeOf(result) === Array.prototype")); |
808 EXPECT_TRUE( | 808 EXPECT_TRUE( |
809 EvaluateScriptForResultBool("result.toString() === '1,2,3,4,5'")); | 809 EvaluateScriptForResultBool("result.toString() === '1,2,3,4,5'")); |
810 }); | 810 }); |
811 // A long (sparse) array. | 811 // A long (sparse) array. |
812 RoundTripTest( | 812 RoundTripTest( |
813 "(() => { var x = new Array(1000); x[500] = 42; return x; })()", | 813 "(() => { var x = new Array(1000); x[500] = 42; return x; })()", |
814 [this](Local<Value> value) { | 814 [this](Local<Value> value) { |
815 ASSERT_TRUE(value->IsArray()); | 815 ASSERT_TRUE(value->IsArray()); |
816 EXPECT_EQ(1000, Array::Cast(*value)->Length()); | 816 EXPECT_EQ(1000u, Array::Cast(*value)->Length()); |
817 EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42")); | 817 EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42")); |
818 }); | 818 }); |
819 // Duplicate reference. | 819 // Duplicate reference. |
820 RoundTripTest( | 820 RoundTripTest( |
821 "(() => { var y = {}; return [y, y]; })()", [this](Local<Value> value) { | 821 "(() => { var y = {}; return [y, y]; })()", [this](Local<Value> value) { |
822 ASSERT_TRUE(value->IsArray()); | 822 ASSERT_TRUE(value->IsArray()); |
823 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 823 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
824 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]")); | 824 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]")); |
825 }); | 825 }); |
826 // Duplicate reference in a sparse array. | 826 // Duplicate reference in a sparse array. |
827 RoundTripTest( | 827 RoundTripTest( |
828 "(() => { var x = new Array(1000); x[1] = x[500] = {}; return x; })()", | 828 "(() => { var x = new Array(1000); x[1] = x[500] = {}; return x; })()", |
829 [this](Local<Value> value) { | 829 [this](Local<Value> value) { |
830 ASSERT_TRUE(value->IsArray()); | 830 ASSERT_TRUE(value->IsArray()); |
831 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 831 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
832 EXPECT_TRUE( | 832 EXPECT_TRUE( |
833 EvaluateScriptForResultBool("typeof result[1] === 'object'")); | 833 EvaluateScriptForResultBool("typeof result[1] === 'object'")); |
834 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]")); | 834 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]")); |
835 }); | 835 }); |
836 // Self reference. | 836 // Self reference. |
837 RoundTripTest( | 837 RoundTripTest( |
838 "(() => { var y = []; y[0] = y; return y; })()", | 838 "(() => { var y = []; y[0] = y; return y; })()", |
839 [this](Local<Value> value) { | 839 [this](Local<Value> value) { |
840 ASSERT_TRUE(value->IsArray()); | 840 ASSERT_TRUE(value->IsArray()); |
841 ASSERT_EQ(1, Array::Cast(*value)->Length()); | 841 ASSERT_EQ(1u, Array::Cast(*value)->Length()); |
842 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result")); | 842 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result")); |
843 }); | 843 }); |
844 // Self reference in a sparse array. | 844 // Self reference in a sparse array. |
845 RoundTripTest( | 845 RoundTripTest( |
846 "(() => { var y = new Array(1000); y[519] = y; return y; })()", | 846 "(() => { var y = new Array(1000); y[519] = y; return y; })()", |
847 [this](Local<Value> value) { | 847 [this](Local<Value> value) { |
848 ASSERT_TRUE(value->IsArray()); | 848 ASSERT_TRUE(value->IsArray()); |
849 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 849 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
850 EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result")); | 850 EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result")); |
851 }); | 851 }); |
852 // Array with additional properties. | 852 // Array with additional properties. |
853 RoundTripTest( | 853 RoundTripTest( |
854 "(() => { var y = [1, 2]; y.foo = 'bar'; return y; })()", | 854 "(() => { var y = [1, 2]; y.foo = 'bar'; return y; })()", |
855 [this](Local<Value> value) { | 855 [this](Local<Value> value) { |
856 ASSERT_TRUE(value->IsArray()); | 856 ASSERT_TRUE(value->IsArray()); |
857 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 857 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
858 EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'")); | 858 EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'")); |
859 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); | 859 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); |
860 }); | 860 }); |
861 // Sparse array with additional properties. | 861 // Sparse array with additional properties. |
862 RoundTripTest( | 862 RoundTripTest( |
863 "(() => { var y = new Array(1000); y.foo = 'bar'; return y; })()", | 863 "(() => { var y = new Array(1000); y.foo = 'bar'; return y; })()", |
864 [this](Local<Value> value) { | 864 [this](Local<Value> value) { |
865 ASSERT_TRUE(value->IsArray()); | 865 ASSERT_TRUE(value->IsArray()); |
866 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 866 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
867 EXPECT_TRUE(EvaluateScriptForResultBool( | 867 EXPECT_TRUE(EvaluateScriptForResultBool( |
868 "result.toString() === ','.repeat(999)")); | 868 "result.toString() === ','.repeat(999)")); |
869 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); | 869 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); |
870 }); | 870 }); |
871 // The distinction between holes and undefined elements must be maintained. | 871 // The distinction between holes and undefined elements must be maintained. |
872 RoundTripTest("[,undefined]", [this](Local<Value> value) { | 872 RoundTripTest("[,undefined]", [this](Local<Value> value) { |
873 ASSERT_TRUE(value->IsArray()); | 873 ASSERT_TRUE(value->IsArray()); |
874 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 874 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
875 EXPECT_TRUE( | 875 EXPECT_TRUE( |
876 EvaluateScriptForResultBool("typeof result[0] === 'undefined'")); | 876 EvaluateScriptForResultBool("typeof result[0] === 'undefined'")); |
877 EXPECT_TRUE( | 877 EXPECT_TRUE( |
878 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); | 878 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); |
879 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(0)")); | 879 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(0)")); |
880 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty(1)")); | 880 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty(1)")); |
881 }); | 881 }); |
882 } | 882 } |
883 | 883 |
884 TEST_F(ValueSerializerTest, DecodeArray) { | 884 TEST_F(ValueSerializerTest, DecodeArray) { |
885 // A simple array of integers. | 885 // A simple array of integers. |
886 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x41, 0x05, 0x3f, 0x01, 0x49, 0x02, | 886 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x41, 0x05, 0x3f, 0x01, 0x49, 0x02, |
887 0x3f, 0x01, 0x49, 0x04, 0x3f, 0x01, 0x49, 0x06, 0x3f, 0x01, | 887 0x3f, 0x01, 0x49, 0x04, 0x3f, 0x01, 0x49, 0x06, 0x3f, 0x01, |
888 0x49, 0x08, 0x3f, 0x01, 0x49, 0x0a, 0x24, 0x00, 0x05, 0x00}, | 888 0x49, 0x08, 0x3f, 0x01, 0x49, 0x0a, 0x24, 0x00, 0x05, 0x00}, |
889 [this](Local<Value> value) { | 889 [this](Local<Value> value) { |
890 ASSERT_TRUE(value->IsArray()); | 890 ASSERT_TRUE(value->IsArray()); |
891 EXPECT_EQ(5, Array::Cast(*value)->Length()); | 891 EXPECT_EQ(5u, Array::Cast(*value)->Length()); |
892 EXPECT_TRUE(EvaluateScriptForResultBool( | 892 EXPECT_TRUE(EvaluateScriptForResultBool( |
893 "Object.getPrototypeOf(result) === Array.prototype")); | 893 "Object.getPrototypeOf(result) === Array.prototype")); |
894 EXPECT_TRUE(EvaluateScriptForResultBool( | 894 EXPECT_TRUE(EvaluateScriptForResultBool( |
895 "result.toString() === '1,2,3,4,5'")); | 895 "result.toString() === '1,2,3,4,5'")); |
896 }); | 896 }); |
897 // A long (sparse) array. | 897 // A long (sparse) array. |
898 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, | 898 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, |
899 0xe8, 0x07, 0x3f, 0x01, 0x49, 0x54, 0x40, 0x01, 0xe8, 0x07}, | 899 0xe8, 0x07, 0x3f, 0x01, 0x49, 0x54, 0x40, 0x01, 0xe8, 0x07}, |
900 [this](Local<Value> value) { | 900 [this](Local<Value> value) { |
901 ASSERT_TRUE(value->IsArray()); | 901 ASSERT_TRUE(value->IsArray()); |
902 EXPECT_EQ(1000, Array::Cast(*value)->Length()); | 902 EXPECT_EQ(1000u, Array::Cast(*value)->Length()); |
903 EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42")); | 903 EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42")); |
904 }); | 904 }); |
905 // Duplicate reference. | 905 // Duplicate reference. |
906 DecodeTest( | 906 DecodeTest( |
907 {0xff, 0x09, 0x3f, 0x00, 0x41, 0x02, 0x3f, 0x01, 0x6f, 0x7b, 0x00, 0x3f, | 907 {0xff, 0x09, 0x3f, 0x00, 0x41, 0x02, 0x3f, 0x01, 0x6f, 0x7b, 0x00, 0x3f, |
908 0x02, 0x5e, 0x01, 0x24, 0x00, 0x02}, | 908 0x02, 0x5e, 0x01, 0x24, 0x00, 0x02}, |
909 [this](Local<Value> value) { | 909 [this](Local<Value> value) { |
910 ASSERT_TRUE(value->IsArray()); | 910 ASSERT_TRUE(value->IsArray()); |
911 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 911 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
912 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]")); | 912 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]")); |
913 }); | 913 }); |
914 // Duplicate reference in a sparse array. | 914 // Duplicate reference in a sparse array. |
915 DecodeTest( | 915 DecodeTest( |
916 {0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, | 916 {0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, |
917 0x02, 0x3f, 0x01, 0x6f, 0x7b, 0x00, 0x3f, 0x02, 0x49, 0xe8, | 917 0x02, 0x3f, 0x01, 0x6f, 0x7b, 0x00, 0x3f, 0x02, 0x49, 0xe8, |
918 0x07, 0x3f, 0x02, 0x5e, 0x01, 0x40, 0x02, 0xe8, 0x07, 0x00}, | 918 0x07, 0x3f, 0x02, 0x5e, 0x01, 0x40, 0x02, 0xe8, 0x07, 0x00}, |
919 [this](Local<Value> value) { | 919 [this](Local<Value> value) { |
920 ASSERT_TRUE(value->IsArray()); | 920 ASSERT_TRUE(value->IsArray()); |
921 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 921 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
922 EXPECT_TRUE( | 922 EXPECT_TRUE( |
923 EvaluateScriptForResultBool("typeof result[1] === 'object'")); | 923 EvaluateScriptForResultBool("typeof result[1] === 'object'")); |
924 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]")); | 924 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]")); |
925 }); | 925 }); |
926 // Self reference. | 926 // Self reference. |
927 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x41, 0x01, 0x3f, 0x01, 0x5e, 0x00, 0x24, | 927 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x41, 0x01, 0x3f, 0x01, 0x5e, 0x00, 0x24, |
928 0x00, 0x01, 0x00}, | 928 0x00, 0x01, 0x00}, |
929 [this](Local<Value> value) { | 929 [this](Local<Value> value) { |
930 ASSERT_TRUE(value->IsArray()); | 930 ASSERT_TRUE(value->IsArray()); |
931 ASSERT_EQ(1, Array::Cast(*value)->Length()); | 931 ASSERT_EQ(1u, Array::Cast(*value)->Length()); |
932 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result")); | 932 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result")); |
933 }); | 933 }); |
934 // Self reference in a sparse array. | 934 // Self reference in a sparse array. |
935 DecodeTest( | 935 DecodeTest( |
936 {0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, | 936 {0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, 0x49, |
937 0x8e, 0x08, 0x3f, 0x01, 0x5e, 0x00, 0x40, 0x01, 0xe8, 0x07}, | 937 0x8e, 0x08, 0x3f, 0x01, 0x5e, 0x00, 0x40, 0x01, 0xe8, 0x07}, |
938 [this](Local<Value> value) { | 938 [this](Local<Value> value) { |
939 ASSERT_TRUE(value->IsArray()); | 939 ASSERT_TRUE(value->IsArray()); |
940 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 940 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
941 EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result")); | 941 EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result")); |
942 }); | 942 }); |
943 // Array with additional properties. | 943 // Array with additional properties. |
944 DecodeTest( | 944 DecodeTest( |
945 {0xff, 0x09, 0x3f, 0x00, 0x41, 0x02, 0x3f, 0x01, 0x49, 0x02, 0x3f, | 945 {0xff, 0x09, 0x3f, 0x00, 0x41, 0x02, 0x3f, 0x01, 0x49, 0x02, 0x3f, |
946 0x01, 0x49, 0x04, 0x3f, 0x01, 0x53, 0x03, 0x66, 0x6f, 0x6f, 0x3f, | 946 0x01, 0x49, 0x04, 0x3f, 0x01, 0x53, 0x03, 0x66, 0x6f, 0x6f, 0x3f, |
947 0x01, 0x53, 0x03, 0x62, 0x61, 0x72, 0x24, 0x01, 0x02, 0x00}, | 947 0x01, 0x53, 0x03, 0x62, 0x61, 0x72, 0x24, 0x01, 0x02, 0x00}, |
948 [this](Local<Value> value) { | 948 [this](Local<Value> value) { |
949 ASSERT_TRUE(value->IsArray()); | 949 ASSERT_TRUE(value->IsArray()); |
950 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 950 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
951 EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'")); | 951 EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'")); |
952 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); | 952 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); |
953 }); | 953 }); |
954 // Sparse array with additional properties. | 954 // Sparse array with additional properties. |
955 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, | 955 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x61, 0xe8, 0x07, 0x3f, 0x01, |
956 0x53, 0x03, 0x66, 0x6f, 0x6f, 0x3f, 0x01, 0x53, 0x03, | 956 0x53, 0x03, 0x66, 0x6f, 0x6f, 0x3f, 0x01, 0x53, 0x03, |
957 0x62, 0x61, 0x72, 0x40, 0x01, 0xe8, 0x07, 0x00}, | 957 0x62, 0x61, 0x72, 0x40, 0x01, 0xe8, 0x07, 0x00}, |
958 [this](Local<Value> value) { | 958 [this](Local<Value> value) { |
959 ASSERT_TRUE(value->IsArray()); | 959 ASSERT_TRUE(value->IsArray()); |
960 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 960 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
961 EXPECT_TRUE(EvaluateScriptForResultBool( | 961 EXPECT_TRUE(EvaluateScriptForResultBool( |
962 "result.toString() === ','.repeat(999)")); | 962 "result.toString() === ','.repeat(999)")); |
963 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); | 963 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); |
964 }); | 964 }); |
965 // The distinction between holes and undefined elements must be maintained. | 965 // The distinction between holes and undefined elements must be maintained. |
966 // Note that since the previous output from Chrome fails this test, an | 966 // Note that since the previous output from Chrome fails this test, an |
967 // encoding using the sparse format was constructed instead. | 967 // encoding using the sparse format was constructed instead. |
968 DecodeTest( | 968 DecodeTest( |
969 {0xff, 0x09, 0x61, 0x02, 0x49, 0x02, 0x5f, 0x40, 0x01, 0x02}, | 969 {0xff, 0x09, 0x61, 0x02, 0x49, 0x02, 0x5f, 0x40, 0x01, 0x02}, |
970 [this](Local<Value> value) { | 970 [this](Local<Value> value) { |
971 ASSERT_TRUE(value->IsArray()); | 971 ASSERT_TRUE(value->IsArray()); |
972 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 972 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
973 EXPECT_TRUE( | 973 EXPECT_TRUE( |
974 EvaluateScriptForResultBool("typeof result[0] === 'undefined'")); | 974 EvaluateScriptForResultBool("typeof result[0] === 'undefined'")); |
975 EXPECT_TRUE( | 975 EXPECT_TRUE( |
976 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); | 976 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); |
977 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(0)")); | 977 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(0)")); |
978 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty(1)")); | 978 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty(1)")); |
979 }); | 979 }); |
980 } | 980 } |
981 | 981 |
982 TEST_F(ValueSerializerTest, DecodeInvalidOverLargeArray) { | 982 TEST_F(ValueSerializerTest, DecodeInvalidOverLargeArray) { |
983 // So large it couldn't exist in the V8 heap, and its size couldn't fit in a | 983 // So large it couldn't exist in the V8 heap, and its size couldn't fit in a |
984 // SMI on 32-bit systems (2^30). | 984 // SMI on 32-bit systems (2^30). |
985 InvalidDecodeTest({0xff, 0x09, 0x41, 0x80, 0x80, 0x80, 0x80, 0x04}); | 985 InvalidDecodeTest({0xff, 0x09, 0x41, 0x80, 0x80, 0x80, 0x80, 0x04}); |
986 // Not so large, but there isn't enough data left in the buffer. | 986 // Not so large, but there isn't enough data left in the buffer. |
987 InvalidDecodeTest({0xff, 0x09, 0x41, 0x01}); | 987 InvalidDecodeTest({0xff, 0x09, 0x41, 0x01}); |
988 } | 988 } |
989 | 989 |
990 TEST_F(ValueSerializerTest, RoundTripArrayWithNonEnumerableElement) { | 990 TEST_F(ValueSerializerTest, RoundTripArrayWithNonEnumerableElement) { |
991 // Even though this array looks like [1,5,3], the 5 should be missing from the | 991 // Even though this array looks like [1,5,3], the 5 should be missing from the |
992 // perspective of structured clone, which only clones properties that were | 992 // perspective of structured clone, which only clones properties that were |
993 // enumerable. | 993 // enumerable. |
994 RoundTripTest( | 994 RoundTripTest( |
995 "(() => {" | 995 "(() => {" |
996 " var x = [1,2,3];" | 996 " var x = [1,2,3];" |
997 " Object.defineProperty(x, '1', {enumerable:false, value:5});" | 997 " Object.defineProperty(x, '1', {enumerable:false, value:5});" |
998 " return x;" | 998 " return x;" |
999 "})()", | 999 "})()", |
1000 [this](Local<Value> value) { | 1000 [this](Local<Value> value) { |
1001 ASSERT_TRUE(value->IsArray()); | 1001 ASSERT_TRUE(value->IsArray()); |
1002 ASSERT_EQ(3, Array::Cast(*value)->Length()); | 1002 ASSERT_EQ(3u, Array::Cast(*value)->Length()); |
1003 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty('1')")); | 1003 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty('1')")); |
1004 }); | 1004 }); |
1005 } | 1005 } |
1006 | 1006 |
1007 TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) { | 1007 TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) { |
1008 // If an element is deleted before it is serialized, then it's deleted. | 1008 // If an element is deleted before it is serialized, then it's deleted. |
1009 RoundTripTest( | 1009 RoundTripTest( |
1010 "(() => {" | 1010 "(() => {" |
1011 " var x = [{ get a() { delete x[1]; }}, 42];" | 1011 " var x = [{ get a() { delete x[1]; }}, 42];" |
1012 " return x;" | 1012 " return x;" |
1013 "})()", | 1013 "})()", |
1014 [this](Local<Value> value) { | 1014 [this](Local<Value> value) { |
1015 ASSERT_TRUE(value->IsArray()); | 1015 ASSERT_TRUE(value->IsArray()); |
1016 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 1016 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
1017 EXPECT_TRUE( | 1017 EXPECT_TRUE( |
1018 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); | 1018 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); |
1019 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)")); | 1019 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)")); |
1020 }); | 1020 }); |
1021 // Same for sparse arrays. | 1021 // Same for sparse arrays. |
1022 RoundTripTest( | 1022 RoundTripTest( |
1023 "(() => {" | 1023 "(() => {" |
1024 " var x = [{ get a() { delete x[1]; }}, 42];" | 1024 " var x = [{ get a() { delete x[1]; }}, 42];" |
1025 " x.length = 1000;" | 1025 " x.length = 1000;" |
1026 " return x;" | 1026 " return x;" |
1027 "})()", | 1027 "})()", |
1028 [this](Local<Value> value) { | 1028 [this](Local<Value> value) { |
1029 ASSERT_TRUE(value->IsArray()); | 1029 ASSERT_TRUE(value->IsArray()); |
1030 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1030 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1031 EXPECT_TRUE( | 1031 EXPECT_TRUE( |
1032 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); | 1032 EvaluateScriptForResultBool("typeof result[1] === 'undefined'")); |
1033 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)")); | 1033 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)")); |
1034 }); | 1034 }); |
1035 // If the length is changed, then the resulting array still has the original | 1035 // If the length is changed, then the resulting array still has the original |
1036 // length, but elements that were not yet serialized are gone. | 1036 // length, but elements that were not yet serialized are gone. |
1037 RoundTripTest( | 1037 RoundTripTest( |
1038 "(() => {" | 1038 "(() => {" |
1039 " var x = [1, { get a() { x.length = 0; }}, 3, 4];" | 1039 " var x = [1, { get a() { x.length = 0; }}, 3, 4];" |
1040 " return x;" | 1040 " return x;" |
1041 "})()", | 1041 "})()", |
1042 [this](Local<Value> value) { | 1042 [this](Local<Value> value) { |
1043 ASSERT_TRUE(value->IsArray()); | 1043 ASSERT_TRUE(value->IsArray()); |
1044 ASSERT_EQ(4, Array::Cast(*value)->Length()); | 1044 ASSERT_EQ(4u, Array::Cast(*value)->Length()); |
1045 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1")); | 1045 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1")); |
1046 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)")); | 1046 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)")); |
1047 }); | 1047 }); |
1048 // The same is true if the length is shortened, but there are still items | 1048 // The same is true if the length is shortened, but there are still items |
1049 // remaining. | 1049 // remaining. |
1050 RoundTripTest( | 1050 RoundTripTest( |
1051 "(() => {" | 1051 "(() => {" |
1052 " var x = [1, { get a() { x.length = 3; }}, 3, 4];" | 1052 " var x = [1, { get a() { x.length = 3; }}, 3, 4];" |
1053 " return x;" | 1053 " return x;" |
1054 "})()", | 1054 "})()", |
1055 [this](Local<Value> value) { | 1055 [this](Local<Value> value) { |
1056 ASSERT_TRUE(value->IsArray()); | 1056 ASSERT_TRUE(value->IsArray()); |
1057 ASSERT_EQ(4, Array::Cast(*value)->Length()); | 1057 ASSERT_EQ(4u, Array::Cast(*value)->Length()); |
1058 EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3")); | 1058 EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3")); |
1059 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)")); | 1059 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)")); |
1060 }); | 1060 }); |
1061 // Same for sparse arrays. | 1061 // Same for sparse arrays. |
1062 RoundTripTest( | 1062 RoundTripTest( |
1063 "(() => {" | 1063 "(() => {" |
1064 " var x = [1, { get a() { x.length = 0; }}, 3, 4];" | 1064 " var x = [1, { get a() { x.length = 0; }}, 3, 4];" |
1065 " x.length = 1000;" | 1065 " x.length = 1000;" |
1066 " return x;" | 1066 " return x;" |
1067 "})()", | 1067 "})()", |
1068 [this](Local<Value> value) { | 1068 [this](Local<Value> value) { |
1069 ASSERT_TRUE(value->IsArray()); | 1069 ASSERT_TRUE(value->IsArray()); |
1070 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1070 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1071 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1")); | 1071 EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1")); |
1072 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)")); | 1072 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)")); |
1073 }); | 1073 }); |
1074 RoundTripTest( | 1074 RoundTripTest( |
1075 "(() => {" | 1075 "(() => {" |
1076 " var x = [1, { get a() { x.length = 3; }}, 3, 4];" | 1076 " var x = [1, { get a() { x.length = 3; }}, 3, 4];" |
1077 " x.length = 1000;" | 1077 " x.length = 1000;" |
1078 " return x;" | 1078 " return x;" |
1079 "})()", | 1079 "})()", |
1080 [this](Local<Value> value) { | 1080 [this](Local<Value> value) { |
1081 ASSERT_TRUE(value->IsArray()); | 1081 ASSERT_TRUE(value->IsArray()); |
1082 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1082 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1083 EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3")); | 1083 EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3")); |
1084 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)")); | 1084 EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)")); |
1085 }); | 1085 }); |
1086 // If a getter makes a property non-enumerable, it should still be enumerated | 1086 // If a getter makes a property non-enumerable, it should still be enumerated |
1087 // as enumeration happens once before getters are invoked. | 1087 // as enumeration happens once before getters are invoked. |
1088 RoundTripTest( | 1088 RoundTripTest( |
1089 "(() => {" | 1089 "(() => {" |
1090 " var x = [{ get a() {" | 1090 " var x = [{ get a() {" |
1091 " Object.defineProperty(x, '1', { value: 3, enumerable: false });" | 1091 " Object.defineProperty(x, '1', { value: 3, enumerable: false });" |
1092 " }}, 2];" | 1092 " }}, 2];" |
1093 " return x;" | 1093 " return x;" |
1094 "})()", | 1094 "})()", |
1095 [this](Local<Value> value) { | 1095 [this](Local<Value> value) { |
1096 ASSERT_TRUE(value->IsArray()); | 1096 ASSERT_TRUE(value->IsArray()); |
1097 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 1097 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
1098 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3")); | 1098 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3")); |
1099 }); | 1099 }); |
1100 // Same for sparse arrays. | 1100 // Same for sparse arrays. |
1101 RoundTripTest( | 1101 RoundTripTest( |
1102 "(() => {" | 1102 "(() => {" |
1103 " var x = [{ get a() {" | 1103 " var x = [{ get a() {" |
1104 " Object.defineProperty(x, '1', { value: 3, enumerable: false });" | 1104 " Object.defineProperty(x, '1', { value: 3, enumerable: false });" |
1105 " }}, 2];" | 1105 " }}, 2];" |
1106 " x.length = 1000;" | 1106 " x.length = 1000;" |
1107 " return x;" | 1107 " return x;" |
1108 "})()", | 1108 "})()", |
1109 [this](Local<Value> value) { | 1109 [this](Local<Value> value) { |
1110 ASSERT_TRUE(value->IsArray()); | 1110 ASSERT_TRUE(value->IsArray()); |
1111 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1111 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1112 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3")); | 1112 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3")); |
1113 }); | 1113 }); |
1114 // Getters on the array itself must also run. | 1114 // Getters on the array itself must also run. |
1115 RoundTripTest( | 1115 RoundTripTest( |
1116 "(() => {" | 1116 "(() => {" |
1117 " var x = [1, 2, 3];" | 1117 " var x = [1, 2, 3];" |
1118 " Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });" | 1118 " Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });" |
1119 " return x;" | 1119 " return x;" |
1120 "})()", | 1120 "})()", |
1121 [this](Local<Value> value) { | 1121 [this](Local<Value> value) { |
1122 ASSERT_TRUE(value->IsArray()); | 1122 ASSERT_TRUE(value->IsArray()); |
1123 ASSERT_EQ(3, Array::Cast(*value)->Length()); | 1123 ASSERT_EQ(3u, Array::Cast(*value)->Length()); |
1124 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4")); | 1124 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4")); |
1125 }); | 1125 }); |
1126 // Same for sparse arrays. | 1126 // Same for sparse arrays. |
1127 RoundTripTest( | 1127 RoundTripTest( |
1128 "(() => {" | 1128 "(() => {" |
1129 " var x = [1, 2, 3];" | 1129 " var x = [1, 2, 3];" |
1130 " Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });" | 1130 " Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });" |
1131 " x.length = 1000;" | 1131 " x.length = 1000;" |
1132 " return x;" | 1132 " return x;" |
1133 "})()", | 1133 "})()", |
1134 [this](Local<Value> value) { | 1134 [this](Local<Value> value) { |
1135 ASSERT_TRUE(value->IsArray()); | 1135 ASSERT_TRUE(value->IsArray()); |
1136 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1136 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1137 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4")); | 1137 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4")); |
1138 }); | 1138 }); |
1139 // Even with a getter that deletes things, we don't read from the prototype. | 1139 // Even with a getter that deletes things, we don't read from the prototype. |
1140 RoundTripTest( | 1140 RoundTripTest( |
1141 "(() => {" | 1141 "(() => {" |
1142 " var x = [{ get a() { delete x[1]; } }, 2];" | 1142 " var x = [{ get a() { delete x[1]; } }, 2];" |
1143 " x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });" | 1143 " x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });" |
1144 " return x;" | 1144 " return x;" |
1145 "})()", | 1145 "})()", |
1146 [this](Local<Value> value) { | 1146 [this](Local<Value> value) { |
1147 ASSERT_TRUE(value->IsArray()); | 1147 ASSERT_TRUE(value->IsArray()); |
1148 ASSERT_EQ(2, Array::Cast(*value)->Length()); | 1148 ASSERT_EQ(2u, Array::Cast(*value)->Length()); |
1149 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); | 1149 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); |
1150 }); | 1150 }); |
1151 // Same for sparse arrays. | 1151 // Same for sparse arrays. |
1152 RoundTripTest( | 1152 RoundTripTest( |
1153 "(() => {" | 1153 "(() => {" |
1154 " var x = [{ get a() { delete x[1]; } }, 2];" | 1154 " var x = [{ get a() { delete x[1]; } }, 2];" |
1155 " x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });" | 1155 " x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });" |
1156 " x.length = 1000;" | 1156 " x.length = 1000;" |
1157 " return x;" | 1157 " return x;" |
1158 "})()", | 1158 "})()", |
1159 [this](Local<Value> value) { | 1159 [this](Local<Value> value) { |
1160 ASSERT_TRUE(value->IsArray()); | 1160 ASSERT_TRUE(value->IsArray()); |
1161 ASSERT_EQ(1000, Array::Cast(*value)->Length()); | 1161 ASSERT_EQ(1000u, Array::Cast(*value)->Length()); |
1162 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); | 1162 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); |
1163 }); | 1163 }); |
1164 } | 1164 } |
1165 | 1165 |
1166 TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) { | 1166 TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) { |
1167 // Empty (sparse) array. | 1167 // Empty (sparse) array. |
1168 DecodeTestForVersion0({0x40, 0x00, 0x00, 0x00}, | 1168 DecodeTestForVersion0({0x40, 0x00, 0x00, 0x00}, |
1169 [this](Local<Value> value) { | 1169 [this](Local<Value> value) { |
1170 ASSERT_TRUE(value->IsArray()); | 1170 ASSERT_TRUE(value->IsArray()); |
1171 ASSERT_EQ(0, Array::Cast(*value)->Length()); | 1171 ASSERT_EQ(0u, Array::Cast(*value)->Length()); |
1172 }); | 1172 }); |
1173 // Sparse array with a mixture of elements and properties. | 1173 // Sparse array with a mixture of elements and properties. |
1174 DecodeTestForVersion0( | 1174 DecodeTestForVersion0( |
1175 {0x55, 0x00, 0x53, 0x01, 'a', 0x55, 0x02, 0x55, 0x05, 0x53, | 1175 {0x55, 0x00, 0x53, 0x01, 'a', 0x55, 0x02, 0x55, 0x05, 0x53, |
1176 0x03, 'f', 'o', 'o', 0x53, 0x03, 'b', 'a', 'r', 0x53, | 1176 0x03, 'f', 'o', 'o', 0x53, 0x03, 'b', 'a', 'r', 0x53, |
1177 0x03, 'b', 'a', 'z', 0x49, 0x0b, 0x40, 0x04, 0x03, 0x00}, | 1177 0x03, 'b', 'a', 'z', 0x49, 0x0b, 0x40, 0x04, 0x03, 0x00}, |
1178 [this](Local<Value> value) { | 1178 [this](Local<Value> value) { |
1179 ASSERT_TRUE(value->IsArray()); | 1179 ASSERT_TRUE(value->IsArray()); |
1180 EXPECT_EQ(3, Array::Cast(*value)->Length()); | 1180 EXPECT_EQ(3u, Array::Cast(*value)->Length()); |
1181 EXPECT_TRUE( | 1181 EXPECT_TRUE( |
1182 EvaluateScriptForResultBool("result.toString() === 'a,,5'")); | 1182 EvaluateScriptForResultBool("result.toString() === 'a,,5'")); |
1183 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); | 1183 EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)")); |
1184 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); | 1184 EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'")); |
1185 EXPECT_TRUE(EvaluateScriptForResultBool("result.baz === -6")); | 1185 EXPECT_TRUE(EvaluateScriptForResultBool("result.baz === -6")); |
1186 }); | 1186 }); |
1187 // Sparse array in a sparse array (sanity check of nesting). | 1187 // Sparse array in a sparse array (sanity check of nesting). |
1188 DecodeTestForVersion0( | 1188 DecodeTestForVersion0( |
1189 {0x55, 0x01, 0x55, 0x01, 0x54, 0x40, 0x01, 0x02, 0x40, 0x01, 0x02, 0x00}, | 1189 {0x55, 0x01, 0x55, 0x01, 0x54, 0x40, 0x01, 0x02, 0x40, 0x01, 0x02, 0x00}, |
1190 [this](Local<Value> value) { | 1190 [this](Local<Value> value) { |
1191 ASSERT_TRUE(value->IsArray()); | 1191 ASSERT_TRUE(value->IsArray()); |
1192 EXPECT_EQ(2, Array::Cast(*value)->Length()); | 1192 EXPECT_EQ(2u, Array::Cast(*value)->Length()); |
1193 EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result)")); | 1193 EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result)")); |
1194 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] instanceof Array")); | 1194 EXPECT_TRUE(EvaluateScriptForResultBool("result[1] instanceof Array")); |
1195 EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result[1])")); | 1195 EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result[1])")); |
1196 EXPECT_TRUE(EvaluateScriptForResultBool("result[1][1] === true")); | 1196 EXPECT_TRUE(EvaluateScriptForResultBool("result[1][1] === true")); |
1197 }); | 1197 }); |
1198 } | 1198 } |
1199 | 1199 |
1200 TEST_F(ValueSerializerTest, RoundTripDate) { | 1200 TEST_F(ValueSerializerTest, RoundTripDate) { |
1201 RoundTripTest("new Date(1e6)", [this](Local<Value> value) { | 1201 RoundTripTest("new Date(1e6)", [this](Local<Value> value) { |
1202 ASSERT_TRUE(value->IsDate()); | 1202 ASSERT_TRUE(value->IsDate()); |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 "new Uint8Array(result.a).toString() === '0,1,128,255'")); | 1801 "new Uint8Array(result.a).toString() === '0,1,128,255'")); |
1802 }); | 1802 }); |
1803 } | 1803 } |
1804 | 1804 |
1805 TEST_F(ValueSerializerTest, RoundTripTypedArray) { | 1805 TEST_F(ValueSerializerTest, RoundTripTypedArray) { |
1806 // Check that the right type comes out the other side for every kind of typed | 1806 // Check that the right type comes out the other side for every kind of typed |
1807 // array. | 1807 // array. |
1808 #define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype, size) \ | 1808 #define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype, size) \ |
1809 RoundTripTest("new " #Type "Array(2)", [this](Local<Value> value) { \ | 1809 RoundTripTest("new " #Type "Array(2)", [this](Local<Value> value) { \ |
1810 ASSERT_TRUE(value->Is##Type##Array()); \ | 1810 ASSERT_TRUE(value->Is##Type##Array()); \ |
1811 EXPECT_EQ(2 * size, TypedArray::Cast(*value)->ByteLength()); \ | 1811 EXPECT_EQ(2u * size, TypedArray::Cast(*value)->ByteLength()); \ |
1812 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); \ | 1812 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); \ |
1813 EXPECT_TRUE(EvaluateScriptForResultBool( \ | 1813 EXPECT_TRUE(EvaluateScriptForResultBool( \ |
1814 "Object.getPrototypeOf(result) === " #Type "Array.prototype")); \ | 1814 "Object.getPrototypeOf(result) === " #Type "Array.prototype")); \ |
1815 }); | 1815 }); |
1816 TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST) | 1816 TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST) |
1817 #undef TYPED_ARRAY_CASE | 1817 #undef TYPED_ARRAY_CASE |
1818 | 1818 |
1819 // Check that values of various kinds are suitably preserved. | 1819 // Check that values of various kinds are suitably preserved. |
1820 RoundTripTest("new Uint8Array([1, 128, 255])", [this](Local<Value> value) { | 1820 RoundTripTest("new Uint8Array([1, 128, 255])", [this](Local<Value> value) { |
1821 EXPECT_TRUE( | 1821 EXPECT_TRUE( |
1822 EvaluateScriptForResultBool("result.toString() === '1,128,255'")); | 1822 EvaluateScriptForResultBool("result.toString() === '1,128,255'")); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 }); | 1856 }); |
1857 } | 1857 } |
1858 | 1858 |
1859 TEST_F(ValueSerializerTest, DecodeTypedArray) { | 1859 TEST_F(ValueSerializerTest, DecodeTypedArray) { |
1860 // Check that the right type comes out the other side for every kind of typed | 1860 // Check that the right type comes out the other side for every kind of typed |
1861 // array. | 1861 // array. |
1862 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x02, 0x00, 0x00, 0x56, | 1862 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x02, 0x00, 0x00, 0x56, |
1863 0x42, 0x00, 0x02}, | 1863 0x42, 0x00, 0x02}, |
1864 [this](Local<Value> value) { | 1864 [this](Local<Value> value) { |
1865 ASSERT_TRUE(value->IsUint8Array()); | 1865 ASSERT_TRUE(value->IsUint8Array()); |
1866 EXPECT_EQ(2, TypedArray::Cast(*value)->ByteLength()); | 1866 EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength()); |
1867 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1867 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1868 EXPECT_TRUE(EvaluateScriptForResultBool( | 1868 EXPECT_TRUE(EvaluateScriptForResultBool( |
1869 "Object.getPrototypeOf(result) === Uint8Array.prototype")); | 1869 "Object.getPrototypeOf(result) === Uint8Array.prototype")); |
1870 }); | 1870 }); |
1871 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x02, 0x00, 0x00, 0x56, | 1871 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x02, 0x00, 0x00, 0x56, |
1872 0x62, 0x00, 0x02}, | 1872 0x62, 0x00, 0x02}, |
1873 [this](Local<Value> value) { | 1873 [this](Local<Value> value) { |
1874 ASSERT_TRUE(value->IsInt8Array()); | 1874 ASSERT_TRUE(value->IsInt8Array()); |
1875 EXPECT_EQ(2, TypedArray::Cast(*value)->ByteLength()); | 1875 EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength()); |
1876 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1876 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1877 EXPECT_TRUE(EvaluateScriptForResultBool( | 1877 EXPECT_TRUE(EvaluateScriptForResultBool( |
1878 "Object.getPrototypeOf(result) === Int8Array.prototype")); | 1878 "Object.getPrototypeOf(result) === Int8Array.prototype")); |
1879 }); | 1879 }); |
1880 #if defined(V8_TARGET_LITTLE_ENDIAN) | 1880 #if defined(V8_TARGET_LITTLE_ENDIAN) |
1881 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, | 1881 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, |
1882 0x00, 0x56, 0x57, 0x00, 0x04}, | 1882 0x00, 0x56, 0x57, 0x00, 0x04}, |
1883 [this](Local<Value> value) { | 1883 [this](Local<Value> value) { |
1884 ASSERT_TRUE(value->IsUint16Array()); | 1884 ASSERT_TRUE(value->IsUint16Array()); |
1885 EXPECT_EQ(4, TypedArray::Cast(*value)->ByteLength()); | 1885 EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength()); |
1886 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1886 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1887 EXPECT_TRUE(EvaluateScriptForResultBool( | 1887 EXPECT_TRUE(EvaluateScriptForResultBool( |
1888 "Object.getPrototypeOf(result) === Uint16Array.prototype")); | 1888 "Object.getPrototypeOf(result) === Uint16Array.prototype")); |
1889 }); | 1889 }); |
1890 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, | 1890 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, |
1891 0x00, 0x56, 0x77, 0x00, 0x04}, | 1891 0x00, 0x56, 0x77, 0x00, 0x04}, |
1892 [this](Local<Value> value) { | 1892 [this](Local<Value> value) { |
1893 ASSERT_TRUE(value->IsInt16Array()); | 1893 ASSERT_TRUE(value->IsInt16Array()); |
1894 EXPECT_EQ(4, TypedArray::Cast(*value)->ByteLength()); | 1894 EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength()); |
1895 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1895 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1896 EXPECT_TRUE(EvaluateScriptForResultBool( | 1896 EXPECT_TRUE(EvaluateScriptForResultBool( |
1897 "Object.getPrototypeOf(result) === Int16Array.prototype")); | 1897 "Object.getPrototypeOf(result) === Int16Array.prototype")); |
1898 }); | 1898 }); |
1899 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, | 1899 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, |
1900 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x44, 0x00, 0x08}, | 1900 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x44, 0x00, 0x08}, |
1901 [this](Local<Value> value) { | 1901 [this](Local<Value> value) { |
1902 ASSERT_TRUE(value->IsUint32Array()); | 1902 ASSERT_TRUE(value->IsUint32Array()); |
1903 EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength()); | 1903 EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength()); |
1904 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1904 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1905 EXPECT_TRUE(EvaluateScriptForResultBool( | 1905 EXPECT_TRUE(EvaluateScriptForResultBool( |
1906 "Object.getPrototypeOf(result) === Uint32Array.prototype")); | 1906 "Object.getPrototypeOf(result) === Uint32Array.prototype")); |
1907 }); | 1907 }); |
1908 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, | 1908 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, |
1909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x64, 0x00, 0x08}, | 1909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x64, 0x00, 0x08}, |
1910 [this](Local<Value> value) { | 1910 [this](Local<Value> value) { |
1911 ASSERT_TRUE(value->IsInt32Array()); | 1911 ASSERT_TRUE(value->IsInt32Array()); |
1912 EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength()); | 1912 EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength()); |
1913 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1913 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1914 EXPECT_TRUE(EvaluateScriptForResultBool( | 1914 EXPECT_TRUE(EvaluateScriptForResultBool( |
1915 "Object.getPrototypeOf(result) === Int32Array.prototype")); | 1915 "Object.getPrototypeOf(result) === Int32Array.prototype")); |
1916 }); | 1916 }); |
1917 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, | 1917 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x08, 0x00, 0x00, |
1918 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x66, 0x00, 0x08}, | 1918 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x66, 0x00, 0x08}, |
1919 [this](Local<Value> value) { | 1919 [this](Local<Value> value) { |
1920 ASSERT_TRUE(value->IsFloat32Array()); | 1920 ASSERT_TRUE(value->IsFloat32Array()); |
1921 EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength()); | 1921 EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength()); |
1922 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1922 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1923 EXPECT_TRUE(EvaluateScriptForResultBool( | 1923 EXPECT_TRUE(EvaluateScriptForResultBool( |
1924 "Object.getPrototypeOf(result) === Float32Array.prototype")); | 1924 "Object.getPrototypeOf(result) === Float32Array.prototype")); |
1925 }); | 1925 }); |
1926 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x10, 0x00, 0x00, | 1926 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x10, 0x00, 0x00, |
1927 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 1927 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1928 0x00, 0x00, 0x00, 0x00, 0x56, 0x46, 0x00, 0x10}, | 1928 0x00, 0x00, 0x00, 0x00, 0x56, 0x46, 0x00, 0x10}, |
1929 [this](Local<Value> value) { | 1929 [this](Local<Value> value) { |
1930 ASSERT_TRUE(value->IsFloat64Array()); | 1930 ASSERT_TRUE(value->IsFloat64Array()); |
1931 EXPECT_EQ(16, TypedArray::Cast(*value)->ByteLength()); | 1931 EXPECT_EQ(16u, TypedArray::Cast(*value)->ByteLength()); |
1932 EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); | 1932 EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); |
1933 EXPECT_TRUE(EvaluateScriptForResultBool( | 1933 EXPECT_TRUE(EvaluateScriptForResultBool( |
1934 "Object.getPrototypeOf(result) === Float64Array.prototype")); | 1934 "Object.getPrototypeOf(result) === Float64Array.prototype")); |
1935 }); | 1935 }); |
1936 #endif // V8_TARGET_LITTLE_ENDIAN | 1936 #endif // V8_TARGET_LITTLE_ENDIAN |
1937 | 1937 |
1938 // Check that values of various kinds are suitably preserved. | 1938 // Check that values of various kinds are suitably preserved. |
1939 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x03, 0x01, 0x80, 0xff, | 1939 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x03, 0x01, 0x80, 0xff, |
1940 0x56, 0x42, 0x00, 0x03, 0x00}, | 1940 0x56, 0x42, 0x00, 0x03, 0x00}, |
1941 [this](Local<Value> value) { | 1941 [this](Local<Value> value) { |
1942 EXPECT_TRUE(EvaluateScriptForResultBool( | 1942 EXPECT_TRUE(EvaluateScriptForResultBool( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1997 {0xff, 0x09, 0x42, 0x04, 0x00, 0x00, 0x00, 0x00, 0x56, 0x77, 0x02, 0x01}); | 1997 {0xff, 0x09, 0x42, 0x04, 0x00, 0x00, 0x00, 0x00, 0x56, 0x77, 0x02, 0x01}); |
1998 // Invalid view type (0xff). | 1998 // Invalid view type (0xff). |
1999 InvalidDecodeTest( | 1999 InvalidDecodeTest( |
2000 {0xff, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0xff, 0x01, 0x01}); | 2000 {0xff, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0xff, 0x01, 0x01}); |
2001 } | 2001 } |
2002 | 2002 |
2003 TEST_F(ValueSerializerTest, RoundTripDataView) { | 2003 TEST_F(ValueSerializerTest, RoundTripDataView) { |
2004 RoundTripTest("new DataView(new ArrayBuffer(4), 1, 2)", | 2004 RoundTripTest("new DataView(new ArrayBuffer(4), 1, 2)", |
2005 [this](Local<Value> value) { | 2005 [this](Local<Value> value) { |
2006 ASSERT_TRUE(value->IsDataView()); | 2006 ASSERT_TRUE(value->IsDataView()); |
2007 EXPECT_EQ(1, DataView::Cast(*value)->ByteOffset()); | 2007 EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset()); |
2008 EXPECT_EQ(2, DataView::Cast(*value)->ByteLength()); | 2008 EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength()); |
2009 EXPECT_EQ(4, DataView::Cast(*value)->Buffer()->ByteLength()); | 2009 EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength()); |
2010 EXPECT_TRUE(EvaluateScriptForResultBool( | 2010 EXPECT_TRUE(EvaluateScriptForResultBool( |
2011 "Object.getPrototypeOf(result) === DataView.prototype")); | 2011 "Object.getPrototypeOf(result) === DataView.prototype")); |
2012 }); | 2012 }); |
2013 } | 2013 } |
2014 | 2014 |
2015 TEST_F(ValueSerializerTest, DecodeDataView) { | 2015 TEST_F(ValueSerializerTest, DecodeDataView) { |
2016 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, | 2016 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x3f, 0x00, 0x42, 0x04, 0x00, 0x00, 0x00, |
2017 0x00, 0x56, 0x3f, 0x01, 0x02}, | 2017 0x00, 0x56, 0x3f, 0x01, 0x02}, |
2018 [this](Local<Value> value) { | 2018 [this](Local<Value> value) { |
2019 ASSERT_TRUE(value->IsDataView()); | 2019 ASSERT_TRUE(value->IsDataView()); |
2020 EXPECT_EQ(1, DataView::Cast(*value)->ByteOffset()); | 2020 EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset()); |
2021 EXPECT_EQ(2, DataView::Cast(*value)->ByteLength()); | 2021 EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength()); |
2022 EXPECT_EQ(4, DataView::Cast(*value)->Buffer()->ByteLength()); | 2022 EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength()); |
2023 EXPECT_TRUE(EvaluateScriptForResultBool( | 2023 EXPECT_TRUE(EvaluateScriptForResultBool( |
2024 "Object.getPrototypeOf(result) === DataView.prototype")); | 2024 "Object.getPrototypeOf(result) === DataView.prototype")); |
2025 }); | 2025 }); |
2026 } | 2026 } |
2027 | 2027 |
2028 TEST_F(ValueSerializerTest, DecodeInvalidDataView) { | 2028 TEST_F(ValueSerializerTest, DecodeInvalidDataView) { |
2029 // Byte offset out of range. | 2029 // Byte offset out of range. |
2030 InvalidDecodeTest( | 2030 InvalidDecodeTest( |
2031 {0xff, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x3f, 0x03, 0x01}); | 2031 {0xff, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x3f, 0x03, 0x01}); |
2032 // Byte offset in range, offset + length out of range. | 2032 // Byte offset in range, offset + length out of range. |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 InvalidDecodeTest(raw); | 2524 InvalidDecodeTest(raw); |
2525 } | 2525 } |
2526 | 2526 |
2527 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { | 2527 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { |
2528 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); | 2528 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); |
2529 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); | 2529 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); |
2530 } | 2530 } |
2531 | 2531 |
2532 } // namespace | 2532 } // namespace |
2533 } // namespace v8 | 2533 } // namespace v8 |
OLD | NEW |