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: --allow-natives-syntax |
| 6 |
| 7 function PrintDesc(desc, s) { |
| 8 var json; |
| 9 if (desc) { |
| 10 json = JSON.stringify(desc); |
| 11 } else { |
| 12 json = "<no such property>"; |
| 13 } |
| 14 if (s === undefined) { |
| 15 print(json); |
| 16 } else { |
| 17 print(s + ": " + json); |
| 18 } |
| 19 } |
| 20 |
| 21 |
| 22 var counters; |
| 23 var test_realm; |
| 24 var cfg; |
| 25 |
| 26 |
| 27 function GetDescriptor() { |
| 28 var code = 'Object.getOwnPropertyDescriptor(global, "x")'; |
| 29 var desc = Realm.eval(test_realm, code); |
| 30 // PrintDesc(desc); |
| 31 return desc; |
| 32 } |
| 33 |
| 34 function SetUp() { |
| 35 counters = {}; |
| 36 Realm.shared = {counters: counters}; |
| 37 test_realm = Realm.create(); |
| 38 Realm.eval(test_realm, 'var global = Realm.global(Realm.current());'); |
| 39 print("====================="); |
| 40 print("Test realm: " + test_realm); |
| 41 assertEquals(undefined, GetDescriptor()); |
| 42 } |
| 43 |
| 44 function TearDown() { |
| 45 Realm.dispose(test_realm); |
| 46 print("OK"); |
| 47 } |
| 48 |
| 49 |
| 50 function AddStrict(code, cfg) { |
| 51 return cfg.strict ? '"use strict"; ' + code : code; |
| 52 } |
| 53 |
| 54 function ForceMutablePropertyCellType() { |
| 55 Realm.eval(test_realm, 'global.x = {}; global.x = undefined;'); |
| 56 } |
| 57 |
| 58 function DeclareVar() { |
| 59 var code = 'var x;'; |
| 60 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 61 } |
| 62 |
| 63 function DefineVar(v) { |
| 64 var code = 'var x = ' + v; |
| 65 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 66 } |
| 67 |
| 68 function DefineLoadVar() { |
| 69 var name = 'LoadVar_' + test_realm; |
| 70 var code = |
| 71 'var x;' + |
| 72 'function ' + name + '() {' + |
| 73 ' return x;' + |
| 74 '};'; |
| 75 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 76 } |
| 77 |
| 78 function LoadVar() { |
| 79 var name = 'LoadVar_' + test_realm; |
| 80 var code = |
| 81 (cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') + |
| 82 name + '();'; |
| 83 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 84 } |
| 85 |
| 86 function DefineStoreVar() { |
| 87 var name = 'StoreVar_' + test_realm; |
| 88 var code = 'var g = (Function("return this"))();' + |
| 89 'var x;' + |
| 90 'function ' + name + '(v) {' + |
| 91 // ' %DebugPrint(g);' + |
| 92 ' return x = v;' + |
| 93 '};'; |
| 94 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 95 } |
| 96 |
| 97 function StoreVar(v) { |
| 98 var name = 'StoreVar_' + test_realm; |
| 99 var code = |
| 100 (cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') + |
| 101 name + '(' + v + ');'; |
| 102 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 103 } |
| 104 |
| 105 // It does 13 iterations which results in 27 loads |
| 106 // and 14 stores. |
| 107 function LoadStoreLoop() { |
| 108 var code = 'for(var x = 0; x < 13; x++);'; |
| 109 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 110 } |
| 111 |
| 112 function DefineRWDataProperty() { |
| 113 var code = |
| 114 'Object.defineProperty(global, "x", { ' + |
| 115 ' value: 42, ' + |
| 116 ' writable: true, ' + |
| 117 ' enumerable: true, ' + |
| 118 ' configurable: true ' + |
| 119 '});'; |
| 120 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 121 } |
| 122 |
| 123 function DefineRODataProperty() { |
| 124 var code = |
| 125 'Object.defineProperty(global, "x", { ' + |
| 126 ' value: 42, ' + |
| 127 ' writable: false, ' + |
| 128 ' enumerable: true, ' + |
| 129 ' configurable: true ' + |
| 130 '});'; |
| 131 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 132 } |
| 133 |
| 134 function SetX_(v) { |
| 135 var code = |
| 136 'global.x_ = ' + v + '; '; |
| 137 return Realm.eval(test_realm, code); |
| 138 } |
| 139 |
| 140 function DefineRWAccessorProperty() { |
| 141 var code = |
| 142 'Object.defineProperty(global, "x", {' + |
| 143 ' get: function() { Realm.shared.counters.get_count++; return this.x_; },
' + |
| 144 ' set: function(v) { Realm.shared.counters.set_count++; this.x_ = v; },'
+ |
| 145 ' enumerable: true, configurable: true' + |
| 146 '});'; |
| 147 counters.get_count = 0; |
| 148 counters.set_count = 0; |
| 149 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 150 } |
| 151 |
| 152 function DefineROAccessorProperty() { |
| 153 var code = |
| 154 'Object.defineProperty(global, "x", {' + |
| 155 ' get: function() { Realm.shared.counters.get_count++; return this.x_; },
' + |
| 156 ' enumerable: true, configurable: true' + |
| 157 '});'; |
| 158 counters.get_count = 0; |
| 159 counters.set_count = 0; |
| 160 return Realm.eval(test_realm, AddStrict(code, cfg)); |
| 161 } |
| 162 |
| 163 |
| 164 function testSuite(opt_cfg) { |
| 165 // |
| 166 // Non strict. |
| 167 // |
| 168 |
| 169 (function() { |
| 170 SetUp(); |
| 171 cfg = {optimize: opt_cfg.optimize, strict: false}; |
| 172 DeclareVar(); |
| 173 DefineLoadVar(); |
| 174 DefineStoreVar(); |
| 175 assertEquals(undefined, LoadVar()); |
| 176 assertEquals(false, GetDescriptor().configurable); |
| 177 |
| 178 // Force property cell type to kMutable. |
| 179 DefineVar(undefined); |
| 180 DefineVar(153); |
| 181 assertEquals(false, GetDescriptor().configurable); |
| 182 |
| 183 assertEquals(153, LoadVar()); |
| 184 assertEquals(113, StoreVar(113)); |
| 185 assertEquals(113, LoadVar()); |
| 186 LoadStoreLoop(); |
| 187 assertEquals(13, LoadVar()); |
| 188 TearDown(); |
| 189 })(); |
| 190 |
| 191 |
| 192 (function() { |
| 193 SetUp(); |
| 194 cfg = {optimize: opt_cfg.optimize, strict: false}; |
| 195 ForceMutablePropertyCellType(); |
| 196 DefineLoadVar(); |
| 197 DefineStoreVar(); |
| 198 DefineRWDataProperty(); |
| 199 assertEquals(42, LoadVar()); |
| 200 assertEquals(true, GetDescriptor().configurable); |
| 201 |
| 202 DefineVar(153); |
| 203 assertEquals(true, GetDescriptor().configurable); |
| 204 |
| 205 assertEquals(153, LoadVar()); |
| 206 assertEquals(113, StoreVar(113)); |
| 207 assertEquals(113, LoadVar()); |
| 208 LoadStoreLoop(); |
| 209 assertEquals(13, LoadVar()); |
| 210 |
| 211 // Now reconfigure to accessor. |
| 212 DefineRWAccessorProperty(); |
| 213 assertEquals(undefined, GetDescriptor().value); |
| 214 assertEquals(true, GetDescriptor().configurable); |
| 215 assertEquals(0, counters.get_count); |
| 216 assertEquals(0, counters.set_count); |
| 217 |
| 218 assertEquals(undefined, LoadVar()); |
| 219 assertEquals(1, counters.get_count); |
| 220 assertEquals(0, counters.set_count); |
| 221 |
| 222 LoadStoreLoop(); |
| 223 assertEquals(28, counters.get_count); |
| 224 assertEquals(14, counters.set_count); |
| 225 |
| 226 assertEquals(13, LoadVar()); |
| 227 assertEquals(29, counters.get_count); |
| 228 assertEquals(14, counters.set_count); |
| 229 |
| 230 TearDown(); |
| 231 })(); |
| 232 |
| 233 |
| 234 (function() { |
| 235 SetUp(); |
| 236 cfg = {optimize: opt_cfg.optimize, strict: false}; |
| 237 ForceMutablePropertyCellType(); |
| 238 DefineLoadVar(); |
| 239 DefineStoreVar(); |
| 240 DefineRODataProperty(); |
| 241 assertEquals(42, LoadVar()); |
| 242 assertEquals(true, GetDescriptor().configurable); |
| 243 |
| 244 DefineVar(153); |
| 245 |
| 246 assertEquals(42, LoadVar()); |
| 247 assertEquals(113, StoreVar(113)); |
| 248 assertEquals(42, LoadVar()); |
| 249 LoadStoreLoop(); |
| 250 assertEquals(42, LoadVar()); |
| 251 |
| 252 // Now reconfigure to accessor property. |
| 253 DefineRWAccessorProperty(); |
| 254 assertEquals(undefined, GetDescriptor().value); |
| 255 assertEquals(true, GetDescriptor().configurable); |
| 256 assertEquals(0, counters.get_count); |
| 257 assertEquals(0, counters.set_count); |
| 258 |
| 259 assertEquals(undefined, LoadVar()); |
| 260 assertEquals(1, counters.get_count); |
| 261 assertEquals(0, counters.set_count); |
| 262 |
| 263 LoadStoreLoop(); |
| 264 assertEquals(28, counters.get_count); |
| 265 assertEquals(14, counters.set_count); |
| 266 |
| 267 assertEquals(13, LoadVar()); |
| 268 assertEquals(29, counters.get_count); |
| 269 assertEquals(14, counters.set_count); |
| 270 |
| 271 TearDown(); |
| 272 })(); |
| 273 |
| 274 |
| 275 (function() { |
| 276 SetUp(); |
| 277 cfg = {optimize: opt_cfg.optimize, strict: false}; |
| 278 ForceMutablePropertyCellType(); |
| 279 DefineLoadVar(); |
| 280 DefineStoreVar(); |
| 281 DefineRWAccessorProperty(); |
| 282 assertEquals(0, counters.get_count); |
| 283 assertEquals(0, counters.set_count); |
| 284 assertEquals(true, GetDescriptor().configurable); |
| 285 |
| 286 assertEquals(undefined, LoadVar()); |
| 287 assertEquals(1, counters.get_count); |
| 288 assertEquals(0, counters.set_count); |
| 289 |
| 290 DefineVar(153); |
| 291 assertEquals(true, GetDescriptor().configurable); |
| 292 assertEquals(1, counters.get_count); |
| 293 assertEquals(1, counters.set_count); |
| 294 |
| 295 assertEquals(153, LoadVar()); |
| 296 assertEquals(2, counters.get_count); |
| 297 assertEquals(1, counters.set_count); |
| 298 |
| 299 assertEquals(113, StoreVar(113)); |
| 300 assertEquals(2, counters.get_count); |
| 301 assertEquals(2, counters.set_count); |
| 302 |
| 303 assertEquals(113, LoadVar()); |
| 304 assertEquals(3, counters.get_count); |
| 305 assertEquals(2, counters.set_count); |
| 306 |
| 307 LoadStoreLoop(); |
| 308 assertEquals(30, counters.get_count); |
| 309 assertEquals(16, counters.set_count); |
| 310 |
| 311 assertEquals(13, LoadVar()); |
| 312 assertEquals(31, counters.get_count); |
| 313 assertEquals(16, counters.set_count); |
| 314 |
| 315 // Now reconfigure to data property. |
| 316 DefineRWDataProperty(); |
| 317 assertEquals(42, GetDescriptor().value); |
| 318 assertEquals(42, LoadVar()); |
| 319 assertEquals(113, StoreVar(113)); |
| 320 assertEquals(31, counters.get_count); |
| 321 assertEquals(16, counters.set_count); |
| 322 |
| 323 TearDown(); |
| 324 })(); |
| 325 |
| 326 |
| 327 (function() { |
| 328 SetUp(); |
| 329 cfg = {optimize: opt_cfg.optimize, strict: false}; |
| 330 ForceMutablePropertyCellType(); |
| 331 DefineLoadVar(); |
| 332 DefineStoreVar(); |
| 333 DefineROAccessorProperty(); |
| 334 assertEquals(0, counters.get_count); |
| 335 assertEquals(0, counters.set_count); |
| 336 assertEquals(true, GetDescriptor().configurable); |
| 337 |
| 338 assertEquals(undefined, LoadVar()); |
| 339 assertEquals(1, counters.get_count); |
| 340 assertEquals(0, counters.set_count); |
| 341 |
| 342 SetX_(42); |
| 343 assertEquals(42, LoadVar()); |
| 344 assertEquals(2, counters.get_count); |
| 345 assertEquals(0, counters.set_count); |
| 346 |
| 347 DefineVar(153); |
| 348 assertEquals(true, GetDescriptor().configurable); |
| 349 assertEquals(2, counters.get_count); |
| 350 assertEquals(0, counters.set_count); |
| 351 |
| 352 assertEquals(42, LoadVar()); |
| 353 assertEquals(3, counters.get_count); |
| 354 assertEquals(0, counters.set_count); |
| 355 |
| 356 assertEquals(113, StoreVar(113)); |
| 357 assertEquals(3, counters.get_count); |
| 358 assertEquals(0, counters.set_count); |
| 359 |
| 360 assertEquals(42, LoadVar()); |
| 361 assertEquals(4, counters.get_count); |
| 362 assertEquals(0, counters.set_count); |
| 363 |
| 364 LoadStoreLoop(); |
| 365 assertEquals(5, counters.get_count); |
| 366 assertEquals(0, counters.set_count); |
| 367 |
| 368 assertEquals(42, LoadVar()); |
| 369 assertEquals(6, counters.get_count); |
| 370 assertEquals(0, counters.set_count); |
| 371 |
| 372 // Now reconfigure to data property. |
| 373 DefineRWDataProperty(); |
| 374 assertEquals(42, GetDescriptor().value); |
| 375 assertEquals(42, LoadVar()); |
| 376 assertEquals(113, StoreVar(113)); |
| 377 assertEquals(6, counters.get_count); |
| 378 assertEquals(0, counters.set_count); |
| 379 |
| 380 TearDown(); |
| 381 })(); |
| 382 |
| 383 |
| 384 // |
| 385 // Strict. |
| 386 // |
| 387 |
| 388 (function() { |
| 389 SetUp(); |
| 390 cfg = {optimize: opt_cfg.optimize, strict: true}; |
| 391 DeclareVar(); |
| 392 DefineLoadVar(); |
| 393 DefineStoreVar(); |
| 394 assertEquals(undefined, LoadVar()); |
| 395 assertEquals(false, GetDescriptor().configurable); |
| 396 |
| 397 // Force property cell type to kMutable. |
| 398 DefineVar(undefined); |
| 399 DefineVar(153); |
| 400 assertEquals(false, GetDescriptor().configurable); |
| 401 |
| 402 assertEquals(153, LoadVar()); |
| 403 assertEquals(113, StoreVar(113)); |
| 404 assertEquals(113, LoadVar()); |
| 405 LoadStoreLoop(); |
| 406 assertEquals(13, LoadVar()); |
| 407 TearDown(); |
| 408 })(); |
| 409 |
| 410 |
| 411 (function() { |
| 412 SetUp(); |
| 413 cfg = {optimize: opt_cfg.optimize, strict: true}; |
| 414 ForceMutablePropertyCellType(); |
| 415 DefineLoadVar(); |
| 416 DefineStoreVar(); |
| 417 DefineRWDataProperty(); |
| 418 assertEquals(42, LoadVar()); |
| 419 assertEquals(true, GetDescriptor().configurable); |
| 420 |
| 421 DefineVar(153); |
| 422 assertEquals(true, GetDescriptor().configurable); |
| 423 |
| 424 assertEquals(153, LoadVar()); |
| 425 assertEquals(113, StoreVar(113)); |
| 426 assertEquals(113, LoadVar()); |
| 427 LoadStoreLoop(); |
| 428 assertEquals(13, LoadVar()); |
| 429 TearDown(); |
| 430 })(); |
| 431 |
| 432 |
| 433 (function() { |
| 434 SetUp(); |
| 435 cfg = {optimize: opt_cfg.optimize, strict: true}; |
| 436 ForceMutablePropertyCellType(); |
| 437 DefineLoadVar(); |
| 438 DefineStoreVar(); |
| 439 DefineRWDataProperty(); |
| 440 assertEquals(true, GetDescriptor().configurable); |
| 441 assertEquals(true, GetDescriptor().writable); |
| 442 assertEquals(113, StoreVar(113)); |
| 443 |
| 444 DefineRODataProperty(); |
| 445 assertEquals(true, GetDescriptor().configurable); |
| 446 assertEquals(false, GetDescriptor().writable); |
| 447 |
| 448 assertEquals(42, LoadVar()); |
| 449 assertEquals(true, GetDescriptor().configurable); |
| 450 assertThrows('DefineVar(153)'); |
| 451 assertEquals(42, LoadVar()); |
| 452 assertThrows('StoreVar(113)'); |
| 453 assertThrows('StoreVar(113)'); |
| 454 assertEquals(42, LoadVar()); |
| 455 assertThrows('LoadStoreLoop()'); |
| 456 assertEquals(42, LoadVar()); |
| 457 TearDown(); |
| 458 })(); |
| 459 |
| 460 |
| 461 (function() { |
| 462 SetUp(); |
| 463 cfg = {optimize: opt_cfg.optimize, strict: true}; |
| 464 ForceMutablePropertyCellType(); |
| 465 DefineLoadVar(); |
| 466 DefineStoreVar(); |
| 467 DefineRWAccessorProperty(); |
| 468 assertEquals(0, counters.get_count); |
| 469 assertEquals(0, counters.set_count); |
| 470 assertEquals(true, GetDescriptor().configurable); |
| 471 |
| 472 assertEquals(undefined, LoadVar()); |
| 473 assertEquals(1, counters.get_count); |
| 474 assertEquals(0, counters.set_count); |
| 475 |
| 476 DefineVar(153); |
| 477 assertEquals(true, GetDescriptor().configurable); |
| 478 assertEquals(1, counters.get_count); |
| 479 assertEquals(1, counters.set_count); |
| 480 |
| 481 assertEquals(153, LoadVar()); |
| 482 assertEquals(2, counters.get_count); |
| 483 assertEquals(1, counters.set_count); |
| 484 |
| 485 assertEquals(113, StoreVar(113)); |
| 486 assertEquals(2, counters.get_count); |
| 487 assertEquals(2, counters.set_count); |
| 488 |
| 489 assertEquals(113, LoadVar()); |
| 490 assertEquals(3, counters.get_count); |
| 491 assertEquals(2, counters.set_count); |
| 492 |
| 493 LoadStoreLoop(); |
| 494 assertEquals(30, counters.get_count); |
| 495 assertEquals(16, counters.set_count); |
| 496 |
| 497 assertEquals(13, LoadVar()); |
| 498 assertEquals(31, counters.get_count); |
| 499 assertEquals(16, counters.set_count); |
| 500 |
| 501 // Now reconfigure to data property. |
| 502 DefineRWDataProperty(); |
| 503 assertEquals(42, GetDescriptor().value); |
| 504 assertEquals(42, LoadVar()); |
| 505 assertEquals(113, StoreVar(113)); |
| 506 assertEquals(31, counters.get_count); |
| 507 assertEquals(16, counters.set_count); |
| 508 |
| 509 TearDown(); |
| 510 })(); |
| 511 |
| 512 |
| 513 (function() { |
| 514 SetUp(); |
| 515 cfg = {optimize: opt_cfg.optimize, strict: true}; |
| 516 ForceMutablePropertyCellType(); |
| 517 DefineLoadVar(); |
| 518 DefineStoreVar(); |
| 519 DefineROAccessorProperty(); |
| 520 assertEquals(0, counters.get_count); |
| 521 assertEquals(0, counters.set_count); |
| 522 assertEquals(true, GetDescriptor().configurable); |
| 523 |
| 524 assertEquals(undefined, LoadVar()); |
| 525 assertEquals(1, counters.get_count); |
| 526 assertEquals(0, counters.set_count); |
| 527 |
| 528 SetX_(42); |
| 529 assertEquals(42, LoadVar()); |
| 530 assertEquals(2, counters.get_count); |
| 531 assertEquals(0, counters.set_count); |
| 532 |
| 533 assertThrows('DefineVar(153)'); |
| 534 assertEquals(true, GetDescriptor().configurable); |
| 535 assertEquals(2, counters.get_count); |
| 536 assertEquals(0, counters.set_count); |
| 537 |
| 538 assertEquals(42, LoadVar()); |
| 539 assertEquals(3, counters.get_count); |
| 540 assertEquals(0, counters.set_count); |
| 541 |
| 542 assertThrows('StoreVar(113)'); |
| 543 assertEquals(3, counters.get_count); |
| 544 assertEquals(0, counters.set_count); |
| 545 |
| 546 assertEquals(42, LoadVar()); |
| 547 assertEquals(4, counters.get_count); |
| 548 assertEquals(0, counters.set_count); |
| 549 |
| 550 assertThrows('LoadStoreLoop()'); |
| 551 assertEquals(4, counters.get_count); |
| 552 assertEquals(0, counters.set_count); |
| 553 |
| 554 assertEquals(42, LoadVar()); |
| 555 assertEquals(5, counters.get_count); |
| 556 assertEquals(0, counters.set_count); |
| 557 |
| 558 // Now reconfigure to data property. |
| 559 DefineRWDataProperty(); |
| 560 assertEquals(42, GetDescriptor().value); |
| 561 assertEquals(42, LoadVar()); |
| 562 assertEquals(113, StoreVar(113)); |
| 563 assertEquals(5, counters.get_count); |
| 564 assertEquals(0, counters.set_count); |
| 565 |
| 566 TearDown(); |
| 567 })(); |
| 568 |
| 569 } // testSuite |
| 570 |
| 571 |
| 572 testSuite({optimize: false}); |
| 573 testSuite({optimize: true}); |
OLD | NEW |