OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // Test that optimized JSArray indexers enerate the same error as dyncamically | 5 // Test that optimized JSArray indexers enerate the same error as dyncamically |
6 // dispatched calls. | 6 // dispatched calls. |
7 | 7 |
8 | |
9 import 'package:expect/expect.dart'; | 8 import 'package:expect/expect.dart'; |
10 | 9 |
11 @NoInline() @AssumeDynamic() | 10 @NoInline() |
| 11 @AssumeDynamic() |
12 confuse(x) => x; | 12 confuse(x) => x; |
13 | 13 |
14 | |
15 Error getError(action(), name, part) { | 14 Error getError(action(), name, part) { |
16 try { | 15 try { |
17 action(); | 16 action(); |
18 } catch (e) { | 17 } catch (e) { |
19 return e; | 18 return e; |
20 } | 19 } |
21 Expect.fail('must throw: $name: $part'); | 20 Expect.fail('must throw: $name: $part'); |
22 } | 21 } |
23 | 22 |
24 indexErrorContainsIndex() { | 23 indexErrorContainsIndex() { |
25 makeFault(i) => () => confuse([])[i]; | 24 makeFault(i) => () => confuse([])[i]; |
26 | 25 |
27 var name = 'index error contains index'; | 26 var name = 'index error contains index'; |
28 var e1 = getError(makeFault(1234), name, 'small'); | 27 var e1 = getError(makeFault(1234), name, 'small'); |
29 var e2 = getError(makeFault(1234000), name, 'medium'); | 28 var e2 = getError(makeFault(1234000), name, 'medium'); |
30 var e3 = getError(makeFault(1234000000000), name, 'large'); | 29 var e3 = getError(makeFault(1234000000000), name, 'large'); |
31 | 30 |
32 Expect.equals('$e1', '$e2'.replaceAll('000', '')); | 31 Expect.equals('$e1', '$e2'.replaceAll('000', '')); |
33 Expect.equals('$e1', '$e3'.replaceAll('000', '')); | 32 Expect.equals('$e1', '$e3'.replaceAll('000', '')); |
34 Expect.equals('$e1'.length + 3, '$e2'.length); | 33 Expect.equals('$e1'.length + 3, '$e2'.length); |
35 Expect.equals('$e1'.length + 9, '$e3'.length); | 34 Expect.equals('$e1'.length + 9, '$e3'.length); |
36 } | 35 } |
37 | 36 |
38 | |
39 compare(name, fault1(), fault2(), fault3()) { | 37 compare(name, fault1(), fault2(), fault3()) { |
40 var e1 = getError(fault1, name, 'fault1'); | 38 var e1 = getError(fault1, name, 'fault1'); |
41 var e2 = getError(fault2, name, 'fault2'); | 39 var e2 = getError(fault2, name, 'fault2'); |
42 var e3 = getError(fault3, name, 'fault3'); | 40 var e3 = getError(fault3, name, 'fault3'); |
43 | 41 |
44 Expect.equals('$e1', '$e2', '$name: fault1 vs fault2'); | 42 Expect.equals('$e1', '$e2', '$name: fault1 vs fault2'); |
45 Expect.equals('$e1', '$e3', '$name: fault1 vs fault3'); | 43 Expect.equals('$e1', '$e3', '$name: fault1 vs fault3'); |
46 } | 44 } |
47 | 45 |
48 // These tests are a bit tedious and avoid common helpers with higher order | 46 // These tests are a bit tedious and avoid common helpers with higher order |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 var a = []; | 85 var a = []; |
88 while (confuse(false)) a.add(1); | 86 while (confuse(false)) a.add(1); |
89 return a[HUGE]; | 87 return a[HUGE]; |
90 } | 88 } |
91 | 89 |
92 fault3() { | 90 fault3() { |
93 var a = confuse([]); | 91 var a = confuse([]); |
94 return [a[HUGE], a[1], a[2]]; | 92 return [a[HUGE], a[1], a[2]]; |
95 } | 93 } |
96 | 94 |
97 compare('constant index on empty list with huge index', | 95 compare( |
98 fault1, fault2, fault3); | 96 'constant index on empty list with huge index', fault1, fault2, fault3); |
99 } | 97 } |
100 | 98 |
101 constantIndexNonempty() { | 99 constantIndexNonempty() { |
102 // Single dynamic receiver indexing might go via one-shot interceptor that | 100 // Single dynamic receiver indexing might go via one-shot interceptor that |
103 // might have an accelerated path. | 101 // might have an accelerated path. |
104 fault1() => confuse([1])[1]; | 102 fault1() => confuse([1])[1]; |
105 | 103 |
106 fault2() { | 104 fault2() { |
107 var a = [1]; | 105 var a = [1]; |
108 while (confuse(false)) a.add(1); | 106 while (confuse(false)) a.add(1); |
(...skipping 21 matching lines...) Expand all Loading... |
130 // Easily inferred type and open coded indexer. | 128 // Easily inferred type and open coded indexer. |
131 return a[HUGE]; | 129 return a[HUGE]; |
132 } | 130 } |
133 | 131 |
134 fault3() { | 132 fault3() { |
135 var a = confuse([1]); | 133 var a = confuse([1]); |
136 // Multiple indexing might go via shared interceptor. | 134 // Multiple indexing might go via shared interceptor. |
137 return [a[HUGE], a[1], a[2]]; | 135 return [a[HUGE], a[1], a[2]]; |
138 } | 136 } |
139 | 137 |
140 compare('constant index on non-empty list with huge index', | 138 compare('constant index on non-empty list with huge index', fault1, fault2, |
141 fault1, fault2, fault3); | 139 fault3); |
142 } | 140 } |
143 | 141 |
144 constantIndexSetEmpty() { | 142 constantIndexSetEmpty() { |
145 fault1() { | 143 fault1() { |
146 // Single dynamic receiver indexing might go via one-shot interceptor that | 144 // Single dynamic receiver indexing might go via one-shot interceptor that |
147 // might have an accelerated path. | 145 // might have an accelerated path. |
148 confuse([])[0] = 0; | 146 confuse([])[0] = 0; |
149 } | 147 } |
150 | 148 |
151 fault2() { | 149 fault2() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 // Multiple indexing might go via shared interceptor. | 186 // Multiple indexing might go via shared interceptor. |
189 a[0] = 0; | 187 a[0] = 0; |
190 a[1] = 0; | 188 a[1] = 0; |
191 a[2] = 0; | 189 a[2] = 0; |
192 return a; | 190 return a; |
193 } | 191 } |
194 | 192 |
195 compare('constant index-set on non-empty list', fault1, fault2, fault3); | 193 compare('constant index-set on non-empty list', fault1, fault2, fault3); |
196 } | 194 } |
197 | 195 |
198 | |
199 variableIndexEmpty(index, qualifier) { | 196 variableIndexEmpty(index, qualifier) { |
200 // Single dynamic receiver indexing might go via one-shot interceptor that | 197 // Single dynamic receiver indexing might go via one-shot interceptor that |
201 // might have an accelerated path. | 198 // might have an accelerated path. |
202 fault1() => confuse([])[index]; | 199 fault1() => confuse([])[index]; |
203 | 200 |
204 fault2() { | 201 fault2() { |
205 var a = []; | 202 var a = []; |
206 while (confuse(false)) a.add(1); | 203 while (confuse(false)) a.add(1); |
207 // Easily inferred type and open coded indexer. | 204 // Easily inferred type and open coded indexer. |
208 return a[index]; | 205 return a[index]; |
(...skipping 19 matching lines...) Expand all Loading... |
228 // Easily inferred type and open coded indexer. | 225 // Easily inferred type and open coded indexer. |
229 return a[index]; | 226 return a[index]; |
230 } | 227 } |
231 | 228 |
232 fault3() { | 229 fault3() { |
233 var a = confuse([1]); | 230 var a = confuse([1]); |
234 // Multiple indexing might go via shared interceptor. | 231 // Multiple indexing might go via shared interceptor. |
235 return [a[index], a[1], a[2]]; | 232 return [a[index], a[1], a[2]]; |
236 } | 233 } |
237 | 234 |
238 compare('variable index on non-empty list $qualifier', | 235 compare( |
239 fault1, fault2, fault3); | 236 'variable index on non-empty list $qualifier', fault1, fault2, fault3); |
240 } | 237 } |
241 | 238 |
242 variableIndexSetEmpty(index, qualifier) { | 239 variableIndexSetEmpty(index, qualifier) { |
243 fault1() { | 240 fault1() { |
244 var a = confuse([]); | 241 var a = confuse([]); |
245 // Single dynamic receiver indexing might go via one-shot interceptor that | 242 // Single dynamic receiver indexing might go via one-shot interceptor that |
246 // might have an accelerated path. | 243 // might have an accelerated path. |
247 a[index] = 1; | 244 a[index] = 1; |
248 return a; | 245 return a; |
249 } | 246 } |
250 | 247 |
251 fault2() { | 248 fault2() { |
252 var a = []; | 249 var a = []; |
253 while (confuse(false)) a.add(1); | 250 while (confuse(false)) a.add(1); |
254 // Easily inferred type and open coded indexer. | 251 // Easily inferred type and open coded indexer. |
255 a[index] = 1; | 252 a[index] = 1; |
256 return a; | 253 return a; |
257 } | 254 } |
258 | 255 |
259 fault3() { | 256 fault3() { |
260 var a = confuse([]); | 257 var a = confuse([]); |
261 // Multiple indexing might go via shared interceptor. | 258 // Multiple indexing might go via shared interceptor. |
262 a[index] = 1; | 259 a[index] = 1; |
263 a[2] = 2; | 260 a[2] = 2; |
264 a[3] = 3; | 261 a[3] = 3; |
265 return a; | 262 return a; |
266 } | 263 } |
267 | 264 |
268 compare('variable index-set on empty list $qualifier', | 265 compare( |
269 fault1, fault2, fault3); | 266 'variable index-set on empty list $qualifier', fault1, fault2, fault3); |
270 } | 267 } |
271 | 268 |
272 variableIndexSetNonempty(index, qualifier) { | 269 variableIndexSetNonempty(index, qualifier) { |
273 fault1() { | 270 fault1() { |
274 var a = confuse([1]); | 271 var a = confuse([1]); |
275 // Single dynamic receiver indexing might go via one-shot interceptor that | 272 // Single dynamic receiver indexing might go via one-shot interceptor that |
276 // might have an accelerated path. | 273 // might have an accelerated path. |
277 a[index] = 1; | 274 a[index] = 1; |
278 return a; | 275 return a; |
279 } | 276 } |
280 | 277 |
281 fault2() { | 278 fault2() { |
282 var a = [1]; | 279 var a = [1]; |
283 while (confuse(false)) a.add(1); | 280 while (confuse(false)) a.add(1); |
284 // Easily inferred type and open coded indexer. | 281 // Easily inferred type and open coded indexer. |
285 a[index] = 1; | 282 a[index] = 1; |
286 return a; | 283 return a; |
287 } | 284 } |
288 | 285 |
289 fault3() { | 286 fault3() { |
290 var a = confuse([1]); | 287 var a = confuse([1]); |
291 // Multiple indexing might go via shared interceptor. | 288 // Multiple indexing might go via shared interceptor. |
292 a[index] = 1; | 289 a[index] = 1; |
293 a[2] = 2; | 290 a[2] = 2; |
294 a[3] = 3; | 291 a[3] = 3; |
295 return a; | 292 return a; |
296 } | 293 } |
297 | 294 |
298 compare('variable index-set on non-empty list $qualifier', | 295 compare('variable index-set on non-empty list $qualifier', fault1, fault2, |
299 fault1, fault2, fault3); | 296 fault3); |
300 } | 297 } |
301 | 298 |
302 | |
303 main() { | 299 main() { |
304 indexErrorContainsIndex(); | 300 indexErrorContainsIndex(); |
305 | 301 |
306 constantIndexEmpty(); | 302 constantIndexEmpty(); |
307 constantIndexHugeEmpty(); | 303 constantIndexHugeEmpty(); |
308 constantIndexNonempty(); | 304 constantIndexNonempty(); |
309 constantIndexHugeNonempty(); | 305 constantIndexHugeNonempty(); |
310 constantIndexSetEmpty(); | 306 constantIndexSetEmpty(); |
311 constantIndexSetNonempty(); | 307 constantIndexSetNonempty(); |
312 | 308 |
313 variableIndexEmpty(0, 'zero index'); | 309 variableIndexEmpty(0, 'zero index'); |
314 variableIndexEmpty(10, 'small index'); | 310 variableIndexEmpty(10, 'small index'); |
315 variableIndexEmpty(-1, 'negative index'); | 311 variableIndexEmpty(-1, 'negative index'); |
316 variableIndexEmpty(HUGE, 'huge index'); | 312 variableIndexEmpty(HUGE, 'huge index'); |
317 | 313 |
318 variableIndexNonempty(10, 'small index'); | 314 variableIndexNonempty(10, 'small index'); |
319 variableIndexNonempty(-1, 'negative index'); | 315 variableIndexNonempty(-1, 'negative index'); |
320 variableIndexNonempty(HUGE, 'huge index'); | 316 variableIndexNonempty(HUGE, 'huge index'); |
321 | 317 |
322 variableIndexSetEmpty(0, 'zero index'); | 318 variableIndexSetEmpty(0, 'zero index'); |
323 variableIndexSetEmpty(10, 'small index'); | 319 variableIndexSetEmpty(10, 'small index'); |
324 variableIndexSetEmpty(-1, 'negative index'); | 320 variableIndexSetEmpty(-1, 'negative index'); |
325 variableIndexSetEmpty(HUGE, 'huge index'); | 321 variableIndexSetEmpty(HUGE, 'huge index'); |
326 | 322 |
327 variableIndexSetNonempty(10, 'small index'); | 323 variableIndexSetNonempty(10, 'small index'); |
328 variableIndexSetNonempty(-1, 'negative index'); | 324 variableIndexSetNonempty(-1, 'negative index'); |
329 variableIndexSetNonempty(HUGE, 'huge index'); | 325 variableIndexSetNonempty(HUGE, 'huge index'); |
330 } | 326 } |
OLD | NEW |