v8/test/mjsunit/strong/load-property-mutate-backing-store.js
conradw 41405c0470 Revert of Revert of [strong] Implement strong mode restrictions on property access (patchset #1 id:1 of https://codereview.chromium.org/1189153002/)
Reason for revert:
Issue was ultimately caused/fixed by https://codereview.chromium.org/1194673002/

Original issue's description:
> Revert of [strong] Implement strong mode restrictions on property access (patchset #23 id:460001 of https://codereview.chromium.org/1168093002/)
>
> Reason for revert:
> Speculative revert, maybe breaks GC-stress
>
> http://build.chromium.org/p/client.v8/builders/V8%20Linux64%20GC%20Stress%20-%20custom%20snapshot/builds/808
>
> Original issue's description:
> > [strong] Implement strong mode restrictions on property access
> >
> > Implements the strong mode proposal's restrictions on property access.
> >
> > To be fully explored in a followup: proxies, interceptors, access checks, load from super
> >
> > BUG=v8:3956
> > LOG=N
> >
> > Committed: https://crrev.com/85dbfb9a389e7b21bd2a63862202ee97fc5d7982
> > Cr-Commit-Position: refs/heads/master@{#29109}
>
> TBR=rossberg@chromium.org,mvstanton@chromium.org,mstarzinger@chromium.org,verwaest@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=v8:3956
>
> Committed: https://crrev.com/407657b706711fd5f8d417841e24b284886f3776
> Cr-Commit-Position: refs/heads/master@{#29115}

TBR=rossberg@chromium.org,mvstanton@chromium.org,mstarzinger@chromium.org,verwaest@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3956
LOG=N

Review URL: https://codereview.chromium.org/1185343005

Cr-Commit-Position: refs/heads/master@{#29122}
2015-06-18 17:17:07 +00:00

175 lines
3.9 KiB
JavaScript

// 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
function getSloppyArguments() {
return arguments;
}
function getObjects() {
"use strict";
return [
{},
Object(""),
[],
(function(){}),
(class Foo {}),
getSloppyArguments(),
arguments,
new Date(),
// TODO(conradw): uncomment once Object.defineProperty is fixed.
// new Uint32Array(0)
];
}
function readFromObjectSloppy(o) {
return o.foo;
}
function readFromObjectKeyedSloppy(o) {
return o["foo"];
}
function readFromObjectKeyedVarSloppy(o) {
var a = "foo";
return o[a];
}
function readFromObjectKeyedComputedSloppy(o) {
var a = "o";
return o["fo" + a];
}
function readFromObjectStrong(o) {
"use strong";
return o.foo;
}
function readFromObjectKeyedStrong(o) {
"use strong";
return o["foo"];
}
function readFromObjectKeyedLetStrong(o) {
"use strong";
let a = "foo";
return o[a];
}
function readFromObjectKeyedComputedStrong(o) {
"use strong";
let a = "o";
return o["fo" + a];
}
function getDescs(x) {
return [
{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 = [
"foo"
]
let badKeys = [
"bar",
"1",
"100001",
"3000000001",
"5000000001"
];
let values = [
"string",
1,
100001,
30000000001,
50000000001,
NaN,
{},
undefined
];
let badAccessorDescs = [
{ set: (function(){}) },
{ configurable: true, enumerable: true, set: (function(){}) }
];
let readSloppy = [
readFromObjectSloppy,
readFromObjectKeyedSloppy,
readFromObjectKeyedVarSloppy,
readFromObjectKeyedComputedSloppy
];
let readStrong = [
readFromObjectStrong,
readFromObjectKeyedStrong,
readFromObjectKeyedLetStrong,
readFromObjectKeyedComputedStrong
];
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) {
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);
}
}
}
}
}
}
})();