OLD | NEW |
| (Empty) |
1 // Copyright 2015 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Flags: --strong-mode --allow-natives-syntax | |
6 | |
7 function getSloppyArguments() { | |
8 return arguments; | |
9 } | |
10 | |
11 function getObjects() { | |
12 "use strict"; | |
13 return [ | |
14 {}, | |
15 Object(""), | |
16 [], | |
17 (function(){}), | |
18 (class Foo {}), | |
19 getSloppyArguments(), | |
20 arguments, | |
21 new Date(), | |
22 ]; | |
23 } | |
24 | |
25 // TODO(conradw): add tests for non-inheritance once semantics are implemented. | |
26 function getNonInheritingObjects() { | |
27 "use strong"; | |
28 return [ | |
29 Object(""), | |
30 [], | |
31 // TODO(conradw): uncomment and correct test once Object.defineProperty is | |
32 // fixed. | |
33 // new Uint32Array(0) | |
34 ]; | |
35 } | |
36 | |
37 function readFromObjectElementSloppy(o) { | |
38 return o[0]; | |
39 } | |
40 | |
41 function readFromObjectElementSparseSloppy(o) { | |
42 return o[100000]; | |
43 } | |
44 | |
45 function readFromObjectElementNonSmiSloppy(o) { | |
46 return o[3000000000]; | |
47 } | |
48 | |
49 function readFromObjectNonIndexSloppy(o) { | |
50 return o[5000000000]; | |
51 } | |
52 | |
53 function readFromObjectElementVarSloppy(o) { | |
54 var a = 0; | |
55 return o[a]; | |
56 } | |
57 | |
58 function readFromObjectElementSparseVarSloppy(o) { | |
59 var a = 100000; | |
60 return o[a]; | |
61 } | |
62 | |
63 function readFromObjectElementNonSmiVarSloppy(o) { | |
64 var a = 3000000000; | |
65 return o[a]; | |
66 } | |
67 | |
68 function readFromObjectNonIndexVarSloppy(o) { | |
69 var a = 5000000000; | |
70 return o[a]; | |
71 } | |
72 | |
73 function readFromObjectElementStrong(o) { | |
74 "use strong"; | |
75 return o[0]; | |
76 } | |
77 | |
78 function readFromObjectElementSparseStrong(o) { | |
79 "use strong"; | |
80 return o[100000]; | |
81 } | |
82 | |
83 function readFromObjectElementNonSmiStrong(o) { | |
84 "use strong"; | |
85 return o[3000000000]; | |
86 } | |
87 | |
88 function readFromObjectNonIndexStrong(o) { | |
89 "use strong"; | |
90 return o[5000000000]; | |
91 } | |
92 | |
93 function readFromObjectElementLetStrong(o) { | |
94 "use strong"; | |
95 let a = 0; | |
96 return o[a]; | |
97 } | |
98 | |
99 function readFromObjectElementSparseLetStrong(o) { | |
100 "use strong"; | |
101 let a = 100000; | |
102 return o[a]; | |
103 } | |
104 | |
105 function readFromObjectElementNonSmiLetStrong(o) { | |
106 "use strong"; | |
107 let a = 3000000000; | |
108 return o[a]; | |
109 } | |
110 | |
111 function readFromObjectNonIndexLetStrong(o) { | |
112 "use strong"; | |
113 let a = 5000000000; | |
114 return o[a]; | |
115 } | |
116 | |
117 function getDescs(x) { | |
118 return [ | |
119 {value: x}, | |
120 {configurable: true, enumerable: true, writable: true, value: x}, | |
121 {configurable: true, enumerable: true, get: (function() {return x}) }, | |
122 ]; | |
123 } | |
124 | |
125 function assertStrongSemantics(func, object) { | |
126 %DeoptimizeFunction(func); | |
127 %ClearFunctionTypeFeedback(func); | |
128 assertThrows(function(){func(object)}, TypeError); | |
129 assertThrows(function(){func(object)}, TypeError); | |
130 assertThrows(function(){func(object)}, TypeError); | |
131 %OptimizeFunctionOnNextCall(func); | |
132 assertThrows(function(){func(object)}, TypeError); | |
133 %DeoptimizeFunction(func); | |
134 assertThrows(function(){func(object)}, TypeError); | |
135 } | |
136 | |
137 function assertSloppySemantics(func, object) { | |
138 %DeoptimizeFunction(func); | |
139 %ClearFunctionTypeFeedback(func); | |
140 assertDoesNotThrow(function(){func(object)}); | |
141 assertDoesNotThrow(function(){func(object)}); | |
142 assertDoesNotThrow(function(){func(object)}); | |
143 %OptimizeFunctionOnNextCall(func); | |
144 assertDoesNotThrow(function(){func(object)}); | |
145 %DeoptimizeFunction(func); | |
146 assertDoesNotThrow(function(){func(object)}); | |
147 } | |
148 | |
149 (function () { | |
150 "use strict"; | |
151 | |
152 let goodKeys = [ | |
153 "0", | |
154 "100000", | |
155 "3000000000", | |
156 "5000000000" | |
157 ] | |
158 | |
159 let badKeys = [ | |
160 "bar", | |
161 "1", | |
162 "100001", | |
163 "3000000001", | |
164 "5000000001" | |
165 ]; | |
166 | |
167 let values = [ | |
168 "string", | |
169 1, | |
170 100001, | |
171 30000000001, | |
172 50000000001, | |
173 NaN, | |
174 {}, | |
175 undefined | |
176 ]; | |
177 | |
178 let badAccessorDescs = [ | |
179 { set: (function(){}) }, | |
180 { configurable: true, enumerable: true, set: (function(){}) } | |
181 ]; | |
182 | |
183 let readSloppy = [ | |
184 readFromObjectElementSloppy, | |
185 readFromObjectElementSparseSloppy, | |
186 readFromObjectElementNonSmiSloppy, | |
187 readFromObjectNonIndexSloppy, | |
188 readFromObjectElementVarSloppy, | |
189 readFromObjectElementSparseVarSloppy, | |
190 readFromObjectElementNonSmiVarSloppy, | |
191 readFromObjectNonIndexVarSloppy | |
192 ]; | |
193 | |
194 let readStrong = [ | |
195 readFromObjectElementStrong, | |
196 readFromObjectElementSparseStrong, | |
197 readFromObjectElementNonSmiStrong, | |
198 readFromObjectNonIndexStrong, | |
199 readFromObjectElementLetStrong, | |
200 readFromObjectElementSparseLetStrong, | |
201 readFromObjectElementNonSmiLetStrong, | |
202 readFromObjectNonIndexLetStrong | |
203 ]; | |
204 | |
205 let dummyProto = {}; | |
206 for (let key of goodKeys) { | |
207 Object.defineProperty(dummyProto, key, { value: undefined }); | |
208 } | |
209 | |
210 // After altering the backing store, accessing a missing property should still | |
211 // throw. | |
212 for (let key of badKeys) { | |
213 for (let value of values) { | |
214 for (let desc of getDescs(value)) { | |
215 let objects = getObjects(); | |
216 let nonInheritingObjects = getNonInheritingObjects(); | |
217 for (let object of objects.concat(nonInheritingObjects)) { | |
218 Object.defineProperty(object, key, desc); | |
219 for (let func of readStrong) { | |
220 assertStrongSemantics(func, object); | |
221 } | |
222 for (let func of readSloppy) { | |
223 assertSloppySemantics(func, object); | |
224 } | |
225 } | |
226 for (let object of objects) { | |
227 // Accessing a property which is on the prototype chain of the object | |
228 // should not throw. | |
229 object.__proto__ = dummyProto; | |
230 for (let key of goodKeys) { | |
231 for (let func of readStrong.concat(readSloppy)) { | |
232 assertSloppySemantics(func, object); | |
233 } | |
234 } | |
235 } | |
236 } | |
237 } | |
238 } | |
239 })(); | |
OLD | NEW |