bf84766a2c
Adds a helper macro "CloneIfMutablePrimitive", which tests if the operand is a MutableHeapNumber, and if so, clones it, otherwise returning the original value. Also modifies the signature of "CopyPropertyArrayValues" to take a "DestroySource" enum, indicating whether or not the resulting object is supplanting the source object or not, and removes all default parameters from that macro (which were not used anyways). This corrects the issue reported in chromium:901301, where StaNamedOwnProperty was replacing the value of a MutableHeapNumber referenced by both the cloned object and the source object. BUG=chromium:901301, v8:7611 R=cbruni@chromium.org, jkummerow@chromium.org Change-Id: I43df1ddc84dfa4840e680b6affeba452ce0b6629 Reviewed-on: https://chromium-review.googlesource.com/c/1318096 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#57304}
124 lines
3.0 KiB
JavaScript
124 lines
3.0 KiB
JavaScript
// Copyright 2018 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.
|
|
|
|
(function testDoubleElements() {
|
|
function f(src) { return {...src}; }
|
|
var src = [1.5];
|
|
src[0] = 1;
|
|
|
|
// Uninitialized
|
|
assertEquals({ 0: 1 }, f(src));
|
|
|
|
src[0] = 1.3;
|
|
|
|
// Monomorphic
|
|
assertEquals({ 0: 1.3 }, f(src));
|
|
})();
|
|
|
|
(function testInObjectProperties() {
|
|
function f(src) { return {...src}; }
|
|
function C() { this.foo = "foo"; }
|
|
var src;
|
|
for (var i = 0; i < 10; ++i) {
|
|
src = new C();
|
|
}
|
|
|
|
// Uninitialized
|
|
assertEquals({ foo: "foo" }, f(src));
|
|
|
|
// Monomorphic
|
|
assertEquals({ foo: "foo" }, f(src));
|
|
})();
|
|
|
|
(function testInObjectProperties2() {
|
|
function f(src) { return {...src}; }
|
|
function C() {
|
|
this.foo = "foo";
|
|
this.p0 = "0";
|
|
this.p1 = "1";
|
|
this.p2 = "2";
|
|
this.p3 = "3";
|
|
}
|
|
var src;
|
|
for (var i = 0; i < 10; ++i) {
|
|
src = new C();
|
|
}
|
|
|
|
// Uninitialized
|
|
assertEquals({ foo: "foo", p0: "0", p1: "1", p2: "2", p3: "3" }, f(src));
|
|
|
|
// Monomorphic
|
|
assertEquals({ foo: "foo", p0: "0", p1: "1", p2: "2", p3: "3" }, f(src));
|
|
})();
|
|
|
|
(function testPolymorphicToMegamorphic() {
|
|
function f(src) { return {...src}; }
|
|
function C1() {
|
|
this.foo = "foo";
|
|
this.p0 = "0";
|
|
this.p1 = "1";
|
|
this.p2 = "2";
|
|
this.p3 = "3";
|
|
}
|
|
function C2() {
|
|
this.p0 = "0";
|
|
this.p1 = "1";
|
|
this[0] = 0;
|
|
}
|
|
function C3() {
|
|
this.x = 774;
|
|
this.y = 663;
|
|
this.rgb = 0xFF00FF;
|
|
}
|
|
function C4() {
|
|
this.qqq = {};
|
|
this.v_1 = [];
|
|
this.name = "C4";
|
|
this.constructor = C4;
|
|
}
|
|
|
|
// Uninitialized
|
|
assertEquals({ foo: "foo", p0: "0", p1: "1", p2: "2", p3: "3" }, f(new C1()));
|
|
|
|
// Monomorphic
|
|
assertEquals({ foo: "foo", p0: "0", p1: "1", p2: "2", p3: "3" }, f(new C1()));
|
|
|
|
// Polymorphic (2)
|
|
assertEquals({ 0: 0, p0: "0", p1: "1" }, f(new C2()));
|
|
assertEquals({ 0: 0, p0: "0", p1: "1" }, f(new C2()));
|
|
|
|
// Polymorphic (3)
|
|
assertEquals({ x: 774, y: 663, rgb: 0xFF00FF }, f(new C3()));
|
|
assertEquals({ x: 774, y: 663, rgb: 0xFF00FF }, f(new C3()));
|
|
|
|
// Polymorphic (4)
|
|
assertEquals({ qqq: {}, v_1: [], name: "C4", constructor: C4 }, f(new C4()));
|
|
assertEquals({ qqq: {}, v_1: [], name: "C4", constructor: C4 }, f(new C4()));
|
|
|
|
// Megamorphic
|
|
assertEquals({ boop: 1 }, f({ boop: 1 }));
|
|
})();
|
|
|
|
// There are 2 paths in CloneObjectIC's handler which need to handle double
|
|
// fields specially --- in object properties, and copying the property array.
|
|
function testMutableInlineProperties() {
|
|
function inobject() { "use strict"; this.x = 1.1; }
|
|
const src = new inobject();
|
|
const x0 = src.x;
|
|
const clone = { ...src, x: x0 + 1 };
|
|
assertEquals(x0, src.x);
|
|
assertEquals({ x: 2.1 }, clone);
|
|
}
|
|
testMutableInlineProperties()
|
|
|
|
function testMutableOutOfLineProperties() {
|
|
const src = { a: 1, b: 2, c: 3 };
|
|
src.x = 2.3;
|
|
const x0 = src.x;
|
|
const clone = { ...src, x: x0 + 1 };
|
|
assertEquals(x0, src.x);
|
|
assertEquals({ a: 1, b: 2, c: 3, x: 3.3 }, clone);
|
|
}
|
|
testMutableOutOfLineProperties();
|