blob: fd235f997bf0264b079b946d2d07790960cb6aa2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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});