Chromium Code Reviews| Index: test/mjsunit/strong/load-element-mutate-backing-store.js |
| diff --git a/test/mjsunit/strong/load-element-mutate-backing-store.js b/test/mjsunit/strong/load-element-mutate-backing-store.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d6cccdbd5b3e48616e7c57ec3ab64ccd49b87564 |
| --- /dev/null |
| +++ b/test/mjsunit/strong/load-element-mutate-backing-store.js |
| @@ -0,0 +1,220 @@ |
| +// Copyright 2015 the V8 project authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// Flags: --strong-mode --allow-natives-syntax |
| + |
| +// TODO(conradw): Track implementation of strong bit for other objects, add |
|
rossberg
2015/06/10 08:28:08
See above
conradw
2015/06/10 12:03:22
Done.
|
| +// tests. |
| + |
| +function getObjects() { |
|
rossberg
2015/06/10 08:28:08
See above
conradw
2015/06/10 12:03:23
Done.
|
| + "use strict"; |
| + return [ |
| + {}, |
| + [], |
| + (function(){}), |
| + (class Foo {}) |
| + ]; |
| +} |
| + |
| +function readFromObjectElementSloppy(o) { |
| + return o[0]; |
| +} |
| + |
| +function readFromObjectElementSparseSloppy(o) { |
| + return o[100000]; |
| +} |
| + |
| +function readFromObjectElementNonSmiSloppy(o) { |
| + return o[3000000000]; |
| +} |
| + |
| +function readFromObjectNonIndexSloppy(o) { |
| + return o[5000000000]; |
| +} |
| + |
| +function readFromObjectElementVarSloppy(o) { |
| + var a = 0; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectElementSparseVarSloppy(o) { |
| + var a = 100000; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectElementNonSmiVarSloppy(o) { |
| + var a = 3000000000; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectNonIndexVarSloppy(o) { |
| + var a = 5000000000; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectElementStrong(o) { |
| + "use strong"; |
| + return o[0]; |
| +} |
| + |
| +function readFromObjectElementSparseStrong(o) { |
| + "use strong"; |
| + return o[100000]; |
| +} |
| + |
| +function readFromObjectElementNonSmiStrong(o) { |
| + "use strong"; |
| + return o[3000000000]; |
| +} |
| + |
| +function readFromObjectNonIndexStrong(o) { |
| + "use strong"; |
| + return o[5000000000]; |
| +} |
| + |
| +function readFromObjectElementLetStrong(o) { |
| + "use strong"; |
| + let a = 0; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectElementSparseLetStrong(o) { |
| + "use strong"; |
| + let a = 100000; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectElementNonSmiLetStrong(o) { |
| + "use strong"; |
| + let a = 3000000000; |
| + return o[a]; |
| +} |
| + |
| +function readFromObjectNonIndexLetStrong(o) { |
| + "use strong"; |
| + let a = 5000000000; |
| + return o[a]; |
| +} |
| + |
| +function getDescs(x) { |
| + return [ |
| + {value: x}, |
| + {configurable: true, value: x}, |
| + {configurable: true, enumerable: true, writable: true, value: x}, |
| + {configurable: true, enumerable: true, get: (function() {return x}) }, |
| + ]; |
| +} |
| + |
| +function assertStrongSemantics(func, object) { |
| + %DeoptimizeFunction(func); |
| + %ClearFunctionTypeFeedback(func); |
| + assertThrows(function(){func(object)}, TypeError); |
| + assertThrows(function(){func(object)}, TypeError); |
| + assertThrows(function(){func(object)}, TypeError); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(object)}, TypeError); |
| + %DeoptimizeFunction(func); |
| + assertThrows(function(){func(object)}, TypeError); |
| +} |
| + |
| +function assertSloppySemantics(func, object) { |
| + %DeoptimizeFunction(func); |
| + %ClearFunctionTypeFeedback(func); |
| + assertDoesNotThrow(function(){func(object)}); |
| + assertDoesNotThrow(function(){func(object)}); |
| + assertDoesNotThrow(function(){func(object)}); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertDoesNotThrow(function(){func(object)}); |
| + %DeoptimizeFunction(func); |
| + assertDoesNotThrow(function(){func(object)}); |
| +} |
| + |
| +(function () { |
| + "use strict"; |
| + |
| + let goodKeys = [ |
| + "0", |
| + "100000", |
| + "3000000000", |
| + "5000000000" |
| + ] |
| + |
| + let badKeys = [ |
| + "bar", |
| + "1", |
| + "100001", |
| + "3000000001", |
| + "5000000001" |
| + ]; |
| + |
| + let values = [ |
| + "string", |
| + 1, |
| + 100001, |
| + 30000000001, |
| + 50000000001, |
| + NaN, |
| + {}, |
| + undefined |
| + ]; |
| + |
| + let badAccessorDescs = [ |
| + { set: (function(){}) }, |
| + { configurable: true, set: (function(){}) }, |
| + { configurable: true, enumerable: true, set: (function(){}) } |
| + ]; |
| + |
| + let readSloppy = [ |
| + readFromObjectElementSloppy, |
| + readFromObjectElementSparseSloppy, |
| + readFromObjectElementNonSmiSloppy, |
| + readFromObjectNonIndexSloppy, |
| + readFromObjectElementVarSloppy, |
| + readFromObjectElementSparseVarSloppy, |
| + readFromObjectElementNonSmiVarSloppy, |
| + readFromObjectNonIndexVarSloppy |
| + ]; |
| + |
| + let readStrong = [ |
| + readFromObjectElementStrong, |
| + readFromObjectElementSparseStrong, |
| + readFromObjectElementNonSmiStrong, |
| + readFromObjectNonIndexStrong, |
| + readFromObjectElementLetStrong, |
| + readFromObjectElementSparseLetStrong, |
| + readFromObjectElementNonSmiLetStrong, |
| + readFromObjectNonIndexLetStrong |
| + ]; |
| + |
| + let dummyProto = {}; |
| + for (let key of goodKeys) { |
| + Object.defineProperty(dummyProto, key, { value: undefined }); |
| + } |
| + |
| + // After altering the backing store, accessing a missing property should still |
| + // throw. |
| + for (let key of badKeys) { |
| + for (let value of values) { |
| + for (let desc of getDescs(value)) { |
| + for (let object of getObjects()) { |
| + Object.defineProperty(object, key, desc); |
| + for (let func of readStrong) { |
|
rossberg
2015/06/10 08:28:08
Yeah, a quintuple loop like this is probably produ
conradw
2015/06/10 12:03:23
On reflection, I may have overstated how bad the t
|
| + assertStrongSemantics(func, object); |
| + } |
| + for (let func of readSloppy) { |
| + assertSloppySemantics(func, object); |
| + } |
| + // Accessing a property which is on the prototype chain of the object |
| + // should not throw. |
| + object.__proto__ = dummyProto; |
| + for (let key of goodKeys) { |
| + for (let func of readStrong.concat(readSloppy)) { |
| + assertSloppySemantics(func, object); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + } |
| +})(); |