41405c0470
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}
201 lines
4.6 KiB
JavaScript
201 lines
4.6 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(),
|
|
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 literals = [0, NaN, true, "string"];
|
|
|
|
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 });
|
|
}
|
|
|
|
let dummyAccessorProto = {};
|
|
for (let key of goodKeys) {
|
|
Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
|
|
}
|
|
|
|
// Attempting to access a property on an object with no defined properties
|
|
// should throw.
|
|
for (let object of getObjects().concat(literals)) {
|
|
for (let func of readStrong) {
|
|
assertStrongSemantics(func, object);
|
|
}
|
|
for (let func of readSloppy) {
|
|
assertSloppySemantics(func, object);
|
|
}
|
|
}
|
|
for (let object of getObjects()) {
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
// Properties with accessor descriptors missing 'get' should throw on access.
|
|
for (let desc of badAccessorDescs) {
|
|
for (let key of goodKeys) {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// The same behaviour should be expected for bad accessor properties on the
|
|
// prototype chain.
|
|
for (let object of getObjects()) {
|
|
object.__proto__ = dummyAccessorProto;
|
|
for (let func of readStrong) {
|
|
assertStrongSemantics(func, object);
|
|
}
|
|
for (let func of readSloppy) {
|
|
assertSloppySemantics(func, object);
|
|
}
|
|
}
|
|
})();
|