ac7c82f905
Bug: v8:8801,v8:8394,v8:9183 Change-Id: If6a4f39991f222337f1c49bd0439e9669d89b030 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1660486 Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Commit-Queue: Mythri Alle <mythria@chromium.org> Auto-Submit: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#62181}
578 lines
15 KiB
JavaScript
578 lines
15 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: --allow-natives-syntax
|
|
|
|
function PrintDesc(desc, s) {
|
|
var json;
|
|
if (desc) {
|
|
json = JSON.stringify(desc);
|
|
} else {
|
|
json = "<no such property>";
|
|
}
|
|
if (s === undefined) {
|
|
print(json);
|
|
} else {
|
|
print(s + ": " + json);
|
|
}
|
|
}
|
|
|
|
|
|
var counters;
|
|
var test_realm;
|
|
var cfg;
|
|
|
|
|
|
function GetDescriptor() {
|
|
var code = 'Object.getOwnPropertyDescriptor(global, "x")';
|
|
var desc = Realm.eval(test_realm, code);
|
|
// PrintDesc(desc);
|
|
return desc;
|
|
}
|
|
|
|
function SetUp() {
|
|
counters = {};
|
|
Realm.shared = {counters: counters};
|
|
test_realm = Realm.create();
|
|
Realm.eval(test_realm, 'var global = Realm.global(Realm.current());');
|
|
print("=====================");
|
|
print("Test realm: " + test_realm);
|
|
assertEquals(undefined, GetDescriptor());
|
|
}
|
|
|
|
function TearDown() {
|
|
Realm.dispose(test_realm);
|
|
print("OK");
|
|
}
|
|
|
|
|
|
function AddStrict(code, cfg) {
|
|
return cfg.strict ? '"use strict"; ' + code : code;
|
|
}
|
|
|
|
function ForceMutablePropertyCellType() {
|
|
Realm.eval(test_realm, 'global.x = {}; global.x = undefined;');
|
|
}
|
|
|
|
function DeclareVar() {
|
|
var code = 'var x;';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineVar(v) {
|
|
var code = 'var x = ' + v;
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineLoadVar() {
|
|
var name = 'LoadVar_' + test_realm;
|
|
var code =
|
|
'var x;' +
|
|
'function ' + name + '() {' +
|
|
' return x;' +
|
|
'};' +
|
|
(cfg.optimize ? '%PrepareFunctionForOptimization(' + name + ');' : '');
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function LoadVar() {
|
|
var name = 'LoadVar_' + test_realm;
|
|
var code =
|
|
(cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') +
|
|
name + '();';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineStoreVar() {
|
|
var name = 'StoreVar_' + test_realm;
|
|
var code = 'var g = (Function("return this"))();' +
|
|
'var x;' +
|
|
'function ' + name + '(v) {' +
|
|
// ' %DebugPrint(g);' +
|
|
' return x = v;' +
|
|
'};' +
|
|
(cfg.optimize ? '%PrepareFunctionForOptimization(' + name + ');' : '');
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function StoreVar(v) {
|
|
var name = 'StoreVar_' + test_realm;
|
|
var code =
|
|
(cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') +
|
|
name + '(' + v + ');';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
// It does 13 iterations which results in 27 loads
|
|
// and 14 stores.
|
|
function LoadStoreLoop() {
|
|
var code = 'for(var x = 0; x < 13; x++);';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineRWDataProperty() {
|
|
var code =
|
|
'Object.defineProperty(global, "x", { ' +
|
|
' value: 42, ' +
|
|
' writable: true, ' +
|
|
' enumerable: true, ' +
|
|
' configurable: true ' +
|
|
'});';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineRODataProperty() {
|
|
var code =
|
|
'Object.defineProperty(global, "x", { ' +
|
|
' value: 42, ' +
|
|
' writable: false, ' +
|
|
' enumerable: true, ' +
|
|
' configurable: true ' +
|
|
'});';
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function SetX_(v) {
|
|
var code =
|
|
'global.x_ = ' + v + '; ';
|
|
return Realm.eval(test_realm, code);
|
|
}
|
|
|
|
function DefineRWAccessorProperty() {
|
|
var code =
|
|
'Object.defineProperty(global, "x", {' +
|
|
' get: function() { Realm.shared.counters.get_count++; return this.x_; },' +
|
|
' set: function(v) { Realm.shared.counters.set_count++; this.x_ = v; },' +
|
|
' enumerable: true, configurable: true' +
|
|
'});';
|
|
counters.get_count = 0;
|
|
counters.set_count = 0;
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
function DefineROAccessorProperty() {
|
|
var code =
|
|
'Object.defineProperty(global, "x", {' +
|
|
' get: function() { Realm.shared.counters.get_count++; return this.x_; },' +
|
|
' enumerable: true, configurable: true' +
|
|
'});';
|
|
counters.get_count = 0;
|
|
counters.set_count = 0;
|
|
return Realm.eval(test_realm, AddStrict(code, cfg));
|
|
}
|
|
|
|
|
|
function testSuite(opt_cfg) {
|
|
//
|
|
// Non strict.
|
|
//
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: false};
|
|
DeclareVar();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(false, GetDescriptor().configurable);
|
|
|
|
// Force property cell type to kMutable.
|
|
DefineVar(undefined);
|
|
DefineVar(153);
|
|
assertEquals(false, GetDescriptor().configurable);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(113, LoadVar());
|
|
LoadStoreLoop();
|
|
assertEquals(13, LoadVar());
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: false};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRWDataProperty();
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
DefineVar(153);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(113, LoadVar());
|
|
LoadStoreLoop();
|
|
assertEquals(13, LoadVar());
|
|
|
|
// Now reconfigure to accessor.
|
|
DefineRWAccessorProperty();
|
|
assertEquals(undefined, GetDescriptor().value);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
LoadStoreLoop();
|
|
assertEquals(28, counters.get_count);
|
|
assertEquals(14, counters.set_count);
|
|
|
|
assertEquals(13, LoadVar());
|
|
assertEquals(29, counters.get_count);
|
|
assertEquals(14, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: false};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRODataProperty();
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
DefineVar(153);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(42, LoadVar());
|
|
LoadStoreLoop();
|
|
assertEquals(42, LoadVar());
|
|
|
|
// Now reconfigure to accessor property.
|
|
DefineRWAccessorProperty();
|
|
assertEquals(undefined, GetDescriptor().value);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
LoadStoreLoop();
|
|
assertEquals(28, counters.get_count);
|
|
assertEquals(14, counters.set_count);
|
|
|
|
assertEquals(13, LoadVar());
|
|
assertEquals(29, counters.get_count);
|
|
assertEquals(14, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: false};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRWAccessorProperty();
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
DefineVar(153);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(1, counters.set_count);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(1, counters.set_count);
|
|
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(2, counters.set_count);
|
|
|
|
assertEquals(113, LoadVar());
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(2, counters.set_count);
|
|
|
|
LoadStoreLoop();
|
|
assertEquals(30, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
assertEquals(13, LoadVar());
|
|
assertEquals(31, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
// Now reconfigure to data property.
|
|
DefineRWDataProperty();
|
|
assertEquals(42, GetDescriptor().value);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(31, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: false};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineROAccessorProperty();
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
SetX_(42);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
DefineVar(153);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(4, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
LoadStoreLoop();
|
|
assertEquals(5, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(6, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
// Now reconfigure to data property.
|
|
DefineRWDataProperty();
|
|
assertEquals(42, GetDescriptor().value);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(6, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
//
|
|
// Strict.
|
|
//
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: true};
|
|
DeclareVar();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(false, GetDescriptor().configurable);
|
|
|
|
// Force property cell type to kMutable.
|
|
DefineVar(undefined);
|
|
DefineVar(153);
|
|
assertEquals(false, GetDescriptor().configurable);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(113, LoadVar());
|
|
LoadStoreLoop();
|
|
assertEquals(13, LoadVar());
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: true};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRWDataProperty();
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
DefineVar(153);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(113, LoadVar());
|
|
LoadStoreLoop();
|
|
assertEquals(13, LoadVar());
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: true};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRWDataProperty();
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(true, GetDescriptor().writable);
|
|
assertEquals(113, StoreVar(113));
|
|
|
|
DefineRODataProperty();
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(false, GetDescriptor().writable);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertThrows('DefineVar(153)');
|
|
assertEquals(42, LoadVar());
|
|
assertThrows('StoreVar(113)');
|
|
assertThrows('StoreVar(113)');
|
|
assertEquals(42, LoadVar());
|
|
assertThrows('StoreVar(42)');
|
|
assertEquals(42, LoadVar());
|
|
assertThrows('LoadStoreLoop()');
|
|
assertEquals(42, LoadVar());
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: true};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineRWAccessorProperty();
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
DefineVar(153);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(1, counters.set_count);
|
|
|
|
assertEquals(153, LoadVar());
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(1, counters.set_count);
|
|
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(2, counters.set_count);
|
|
|
|
assertEquals(113, LoadVar());
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(2, counters.set_count);
|
|
|
|
LoadStoreLoop();
|
|
assertEquals(30, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
assertEquals(13, LoadVar());
|
|
assertEquals(31, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
// Now reconfigure to data property.
|
|
DefineRWDataProperty();
|
|
assertEquals(42, GetDescriptor().value);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(31, counters.get_count);
|
|
assertEquals(16, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
|
|
(function() {
|
|
SetUp();
|
|
cfg = {optimize: opt_cfg.optimize, strict: true};
|
|
ForceMutablePropertyCellType();
|
|
DefineLoadVar();
|
|
DefineStoreVar();
|
|
DefineROAccessorProperty();
|
|
assertEquals(0, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
|
|
assertEquals(undefined, LoadVar());
|
|
assertEquals(1, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
SetX_(42);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertThrows('DefineVar(153)');
|
|
assertEquals(true, GetDescriptor().configurable);
|
|
assertEquals(2, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertThrows('StoreVar(113)');
|
|
assertEquals(3, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(4, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertThrows('LoadStoreLoop()');
|
|
assertEquals(4, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(5, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
// Now reconfigure to data property.
|
|
DefineRWDataProperty();
|
|
assertEquals(42, GetDescriptor().value);
|
|
assertEquals(42, LoadVar());
|
|
assertEquals(113, StoreVar(113));
|
|
assertEquals(5, counters.get_count);
|
|
assertEquals(0, counters.set_count);
|
|
|
|
TearDown();
|
|
})();
|
|
|
|
} // testSuite
|
|
|
|
|
|
testSuite({optimize: false});
|
|
testSuite({optimize: true});
|