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 7function 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 22var counters; 23var test_realm; 24var cfg; 25 26 27function GetDescriptor() { 28 var code = 'Object.getOwnPropertyDescriptor(global, "x")'; 29 var desc = Realm.eval(test_realm, code); 30// PrintDesc(desc); 31 return desc; 32} 33 34function 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 44function TearDown() { 45 Realm.dispose(test_realm); 46 print("OK"); 47} 48 49 50function AddStrict(code, cfg) { 51 return cfg.strict ? '"use strict"; ' + code : code; 52} 53 54function ForceMutablePropertyCellType() { 55 Realm.eval(test_realm, 'global.x = {}; global.x = undefined;'); 56} 57 58function DeclareVar() { 59 var code = 'var x;'; 60 return Realm.eval(test_realm, AddStrict(code, cfg)); 61} 62 63function DefineVar(v) { 64 var code = 'var x = ' + v; 65 return Realm.eval(test_realm, AddStrict(code, cfg)); 66} 67 68function 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 78function 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 86function 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 97function 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. 107function LoadStoreLoop() { 108 var code = 'for(var x = 0; x < 13; x++);'; 109 return Realm.eval(test_realm, AddStrict(code, cfg)); 110} 111 112function 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 123function 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 134function SetX_(v) { 135 var code = 136 'global.x_ = ' + v + '; '; 137 return Realm.eval(test_realm, code); 138} 139 140function 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 152function 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 164function 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('StoreVar(42)'); 456 assertEquals(42, LoadVar()); 457 assertThrows('LoadStoreLoop()'); 458 assertEquals(42, LoadVar()); 459 TearDown(); 460 })(); 461 462 463 (function() { 464 SetUp(); 465 cfg = {optimize: opt_cfg.optimize, strict: true}; 466 ForceMutablePropertyCellType(); 467 DefineLoadVar(); 468 DefineStoreVar(); 469 DefineRWAccessorProperty(); 470 assertEquals(0, counters.get_count); 471 assertEquals(0, counters.set_count); 472 assertEquals(true, GetDescriptor().configurable); 473 474 assertEquals(undefined, LoadVar()); 475 assertEquals(1, counters.get_count); 476 assertEquals(0, counters.set_count); 477 478 DefineVar(153); 479 assertEquals(true, GetDescriptor().configurable); 480 assertEquals(1, counters.get_count); 481 assertEquals(1, counters.set_count); 482 483 assertEquals(153, LoadVar()); 484 assertEquals(2, counters.get_count); 485 assertEquals(1, counters.set_count); 486 487 assertEquals(113, StoreVar(113)); 488 assertEquals(2, counters.get_count); 489 assertEquals(2, counters.set_count); 490 491 assertEquals(113, LoadVar()); 492 assertEquals(3, counters.get_count); 493 assertEquals(2, counters.set_count); 494 495 LoadStoreLoop(); 496 assertEquals(30, counters.get_count); 497 assertEquals(16, counters.set_count); 498 499 assertEquals(13, LoadVar()); 500 assertEquals(31, counters.get_count); 501 assertEquals(16, counters.set_count); 502 503 // Now reconfigure to data property. 504 DefineRWDataProperty(); 505 assertEquals(42, GetDescriptor().value); 506 assertEquals(42, LoadVar()); 507 assertEquals(113, StoreVar(113)); 508 assertEquals(31, counters.get_count); 509 assertEquals(16, counters.set_count); 510 511 TearDown(); 512 })(); 513 514 515 (function() { 516 SetUp(); 517 cfg = {optimize: opt_cfg.optimize, strict: true}; 518 ForceMutablePropertyCellType(); 519 DefineLoadVar(); 520 DefineStoreVar(); 521 DefineROAccessorProperty(); 522 assertEquals(0, counters.get_count); 523 assertEquals(0, counters.set_count); 524 assertEquals(true, GetDescriptor().configurable); 525 526 assertEquals(undefined, LoadVar()); 527 assertEquals(1, counters.get_count); 528 assertEquals(0, counters.set_count); 529 530 SetX_(42); 531 assertEquals(42, LoadVar()); 532 assertEquals(2, counters.get_count); 533 assertEquals(0, counters.set_count); 534 535 assertThrows('DefineVar(153)'); 536 assertEquals(true, GetDescriptor().configurable); 537 assertEquals(2, counters.get_count); 538 assertEquals(0, counters.set_count); 539 540 assertEquals(42, LoadVar()); 541 assertEquals(3, counters.get_count); 542 assertEquals(0, counters.set_count); 543 544 assertThrows('StoreVar(113)'); 545 assertEquals(3, counters.get_count); 546 assertEquals(0, counters.set_count); 547 548 assertEquals(42, LoadVar()); 549 assertEquals(4, counters.get_count); 550 assertEquals(0, counters.set_count); 551 552 assertThrows('LoadStoreLoop()'); 553 assertEquals(4, counters.get_count); 554 assertEquals(0, counters.set_count); 555 556 assertEquals(42, LoadVar()); 557 assertEquals(5, counters.get_count); 558 assertEquals(0, counters.set_count); 559 560 // Now reconfigure to data property. 561 DefineRWDataProperty(); 562 assertEquals(42, GetDescriptor().value); 563 assertEquals(42, LoadVar()); 564 assertEquals(113, StoreVar(113)); 565 assertEquals(5, counters.get_count); 566 assertEquals(0, counters.set_count); 567 568 TearDown(); 569 })(); 570 571} // testSuite 572 573 574testSuite({optimize: false}); 575testSuite({optimize: true}); 576