OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 } | 950 } |
951 | 951 |
952 | 952 |
953 // Observing array length (including truncation) | 953 // Observing array length (including truncation) |
954 reset(); | 954 reset(); |
955 var arr = ['a', 'b', 'c', 'd']; | 955 var arr = ['a', 'b', 'c', 'd']; |
956 var arr2 = ['alpha', 'beta']; | 956 var arr2 = ['alpha', 'beta']; |
957 var arr3 = ['hello']; | 957 var arr3 = ['hello']; |
958 arr3[2] = 'goodbye'; | 958 arr3[2] = 'goodbye'; |
959 arr3.length = 6; | 959 arr3.length = 6; |
960 var slow_arr = new Array(1000000000); | |
961 slow_arr[500000000] = 'hello'; | |
962 Object.defineProperty(arr, '0', {configurable: false}); | 960 Object.defineProperty(arr, '0', {configurable: false}); |
963 Object.defineProperty(arr, '2', {get: function(){}}); | 961 Object.defineProperty(arr, '2', {get: function(){}}); |
964 Object.defineProperty(arr2, '0', {get: function(){}, configurable: false}); | 962 Object.defineProperty(arr2, '0', {get: function(){}, configurable: false}); |
965 Object.observe(arr, observer.callback); | 963 Object.observe(arr, observer.callback); |
| 964 Array.observe(arr, observer2.callback); |
966 Object.observe(arr2, observer.callback); | 965 Object.observe(arr2, observer.callback); |
| 966 Array.observe(arr2, observer2.callback); |
967 Object.observe(arr3, observer.callback); | 967 Object.observe(arr3, observer.callback); |
968 Object.observe(slow_arr, observer.callback); | 968 Array.observe(arr3, observer2.callback); |
969 arr.length = 2; | 969 arr.length = 2; |
970 arr.length = 0; | 970 arr.length = 0; |
971 arr.length = 10; | 971 arr.length = 10; |
972 Object.defineProperty(arr, 'length', {writable: false}); | 972 Object.defineProperty(arr, 'length', {writable: false}); |
973 arr2.length = 0; | 973 arr2.length = 0; |
974 arr2.length = 1; // no change expected | 974 arr2.length = 1; // no change expected |
975 Object.defineProperty(arr2, 'length', {value: 1, writable: false}); | 975 Object.defineProperty(arr2, 'length', {value: 1, writable: false}); |
976 arr3.length = 0; | 976 arr3.length = 0; |
977 ++arr3.length; | 977 ++arr3.length; |
978 arr3.length++; | 978 arr3.length++; |
979 arr3.length /= 2; | 979 arr3.length /= 2; |
980 Object.defineProperty(arr3, 'length', {value: 5}); | 980 Object.defineProperty(arr3, 'length', {value: 5}); |
981 Object.defineProperty(arr3, 'length', {value: 10, writable: false}); | 981 arr3[4] = 5; |
982 slow_arr.length = 100; | 982 Object.defineProperty(arr3, 'length', {value: 1, writable: false}); |
983 Object.deliverChangeRecords(observer.callback); | 983 Object.deliverChangeRecords(observer.callback); |
984 observer.assertCallbackRecords([ | 984 observer.assertCallbackRecords([ |
985 { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, | 985 { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, |
986 { object: arr, name: '2', type: 'deleted' }, | 986 { object: arr, name: '2', type: 'deleted' }, |
987 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, | 987 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, |
988 { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, | 988 { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, |
989 { object: arr, name: 'length', type: 'updated', oldValue: 2 }, | 989 { object: arr, name: 'length', type: 'updated', oldValue: 2 }, |
990 { object: arr, name: 'length', type: 'updated', oldValue: 1 }, | 990 { object: arr, name: 'length', type: 'updated', oldValue: 1 }, |
991 { object: arr, name: 'length', type: 'reconfigured' }, | 991 { object: arr, name: 'length', type: 'reconfigured' }, |
992 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, | 992 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, |
993 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, | 993 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, |
994 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, | 994 { object: arr2, name: 'length', type: 'reconfigured' }, |
995 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, | 995 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, |
996 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, | 996 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, |
997 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, | 997 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, |
998 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, | 998 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, |
999 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, | 999 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, |
1000 { object: arr3, name: 'length', type: 'updated', oldValue: 2 }, | 1000 { object: arr3, name: 'length', type: 'updated', oldValue: 2 }, |
1001 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, | 1001 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, |
1002 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, | 1002 { object: arr3, name: '4', type: 'new' }, |
| 1003 { object: arr3, name: '4', type: 'deleted', oldValue: 5 }, |
| 1004 // TODO(rafaelw): It breaks spec compliance to get two records here. |
| 1005 // When the TODO in v8natives.js::DefineArrayProperty is addressed |
| 1006 // which prevents DefineProperty from over-writing the magic length |
| 1007 // property, these will collapse into a single record. |
| 1008 { object: arr3, name: 'length', type: 'updated', oldValue: 5 }, |
| 1009 { object: arr3, name: 'length', type: 'reconfigured' } |
| 1010 ]); |
| 1011 Object.deliverChangeRecords(observer2.callback); |
| 1012 observer2.assertCallbackRecords([ |
| 1013 { object: arr, type: 'splice', index: 2, removed: [, 'd'], addedCount: 0 }, |
| 1014 { object: arr, type: 'splice', index: 1, removed: ['b'], addedCount: 0 }, |
| 1015 { object: arr, type: 'splice', index: 1, removed: [], addedCount: 9 }, |
| 1016 { object: arr2, type: 'splice', index: 1, removed: ['beta'], addedCount: 0 }, |
| 1017 { object: arr3, type: 'splice', index: 0, removed: ['hello',, 'goodbye',,,,],
addedCount: 0 }, |
| 1018 { object: arr3, type: 'splice', index: 0, removed: [], addedCount: 1 }, |
| 1019 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 }, |
| 1020 { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 }, |
| 1021 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 }, |
| 1022 { object: arr3, name: '4', type: 'new' }, |
| 1023 { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 } |
| 1024 ]); |
| 1025 |
| 1026 |
| 1027 // Updating length on large (slow) array |
| 1028 reset(); |
| 1029 var slow_arr = new Array(1000000000); |
| 1030 slow_arr[500000000] = 'hello'; |
| 1031 Object.observe(slow_arr, observer.callback); |
| 1032 var spliceRecords; |
| 1033 function slowSpliceCallback(records) { |
| 1034 spliceRecords = records; |
| 1035 } |
| 1036 Array.observe(slow_arr, slowSpliceCallback); |
| 1037 slow_arr.length = 100; |
| 1038 Object.deliverChangeRecords(observer.callback); |
| 1039 observer.assertCallbackRecords([ |
1003 { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' }, | 1040 { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' }, |
1004 { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 }, | 1041 { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 }, |
1005 ]); | 1042 ]); |
| 1043 Object.deliverChangeRecords(slowSpliceCallback); |
| 1044 assertEquals(spliceRecords.length, 1); |
| 1045 // Have to custom assert this splice record because the removed array is huge. |
| 1046 var splice = spliceRecords[0]; |
| 1047 assertSame(splice.object, slow_arr); |
| 1048 assertEquals(splice.type, 'splice'); |
| 1049 assertEquals(splice.index, 100); |
| 1050 assertEquals(splice.addedCount, 0); |
| 1051 var array_keys = %GetArrayKeys(splice.removed, splice.removed.length); |
| 1052 assertEquals(array_keys.length, 1); |
| 1053 assertEquals(array_keys[0], 499999900); |
| 1054 assertEquals(splice.removed[499999900], 'hello'); |
| 1055 assertEquals(splice.removed.length, 999999900); |
1006 | 1056 |
1007 | 1057 |
1008 // Assignments in loops (checking different IC states). | 1058 // Assignments in loops (checking different IC states). |
1009 reset(); | 1059 reset(); |
1010 var obj = {}; | 1060 var obj = {}; |
1011 Object.observe(obj, observer.callback); | 1061 Object.observe(obj, observer.callback); |
1012 for (var i = 0; i < 5; i++) { | 1062 for (var i = 0; i < 5; i++) { |
1013 obj["a" + i] = i; | 1063 obj["a" + i] = i; |
1014 } | 1064 } |
1015 Object.deliverChangeRecords(observer.callback); | 1065 Object.deliverChangeRecords(observer.callback); |
(...skipping 14 matching lines...) Expand all Loading... |
1030 Object.deliverChangeRecords(observer.callback); | 1080 Object.deliverChangeRecords(observer.callback); |
1031 observer.assertCallbackRecords([ | 1081 observer.assertCallbackRecords([ |
1032 { object: obj, name: "0", type: "new" }, | 1082 { object: obj, name: "0", type: "new" }, |
1033 { object: obj, name: "1", type: "new" }, | 1083 { object: obj, name: "1", type: "new" }, |
1034 { object: obj, name: "2", type: "new" }, | 1084 { object: obj, name: "2", type: "new" }, |
1035 { object: obj, name: "3", type: "new" }, | 1085 { object: obj, name: "3", type: "new" }, |
1036 { object: obj, name: "4", type: "new" }, | 1086 { object: obj, name: "4", type: "new" }, |
1037 ]); | 1087 ]); |
1038 | 1088 |
1039 | 1089 |
1040 // Adding elements past the end of an array should notify on length | 1090 // Adding elements past the end of an array should notify on length for |
| 1091 // Object.observe and emit "splices" for Array.observe. |
1041 reset(); | 1092 reset(); |
1042 var arr = [1, 2, 3]; | 1093 var arr = [1, 2, 3]; |
1043 Object.observe(arr, observer.callback); | 1094 Object.observe(arr, observer.callback); |
| 1095 Array.observe(arr, observer2.callback); |
1044 arr[3] = 10; | 1096 arr[3] = 10; |
1045 arr[100] = 20; | 1097 arr[100] = 20; |
1046 Object.defineProperty(arr, '200', {value: 7}); | 1098 Object.defineProperty(arr, '200', {value: 7}); |
1047 Object.defineProperty(arr, '400', {get: function(){}}); | 1099 Object.defineProperty(arr, '400', {get: function(){}}); |
1048 arr[50] = 30; // no length change expected | 1100 arr[50] = 30; // no length change expected |
1049 Object.deliverChangeRecords(observer.callback); | 1101 Object.deliverChangeRecords(observer.callback); |
1050 observer.assertCallbackRecords([ | 1102 observer.assertCallbackRecords([ |
1051 { object: arr, name: '3', type: 'new' }, | 1103 { object: arr, name: '3', type: 'new' }, |
1052 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, | 1104 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, |
1053 { object: arr, name: '100', type: 'new' }, | 1105 { object: arr, name: '100', type: 'new' }, |
1054 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, | 1106 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, |
1055 { object: arr, name: '200', type: 'new' }, | 1107 { object: arr, name: '200', type: 'new' }, |
1056 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, | 1108 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, |
1057 { object: arr, name: '400', type: 'new' }, | 1109 { object: arr, name: '400', type: 'new' }, |
1058 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, | 1110 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, |
1059 { object: arr, name: '50', type: 'new' }, | 1111 { object: arr, name: '50', type: 'new' }, |
1060 ]); | 1112 ]); |
| 1113 Object.deliverChangeRecords(observer2.callback); |
| 1114 observer2.assertCallbackRecords([ |
| 1115 { object: arr, type: 'splice', index: 3, removed: [], addedCount: 1 }, |
| 1116 { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 }, |
| 1117 { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 }, |
| 1118 { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 }, |
| 1119 { object: arr, type: 'new', name: '50' }, |
| 1120 ]); |
1061 | 1121 |
1062 | 1122 |
1063 // Tests for array methods, first on arrays and then on plain objects | 1123 // Tests for array methods, first on arrays and then on plain objects |
1064 // | 1124 // |
1065 // === ARRAYS === | 1125 // === ARRAYS === |
1066 // | 1126 // |
1067 // Push | 1127 // Push |
1068 reset(); | 1128 reset(); |
1069 var array = [1, 2]; | 1129 var array = [1, 2]; |
1070 Object.observe(array, observer.callback); | 1130 Object.observe(array, observer.callback); |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 for (var n1 = 0; n1 < 3; ++n1) | 1511 for (var n1 = 0; n1 < 3; ++n1) |
1452 for (var n2 = 0; n2 < 3; ++n2) | 1512 for (var n2 = 0; n2 < 3; ++n2) |
1453 for (var i in mutation) | 1513 for (var i in mutation) |
1454 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); | 1514 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); |
1455 | 1515 |
1456 for (var b1 = 0; b1 < 2; ++b1) | 1516 for (var b1 = 0; b1 < 2; ++b1) |
1457 for (var b2 = 0; b2 < 2; ++b2) | 1517 for (var b2 = 0; b2 < 2; ++b2) |
1458 for (var n = 0; n < 3; ++n) | 1518 for (var n = 0; n < 3; ++n) |
1459 for (var i in mutationByIncr) | 1519 for (var i in mutationByIncr) |
1460 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); | 1520 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); |
OLD | NEW |