| 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 |