PR-URL: https://github.com/nodejs/node/pull/49639 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
177 lines
5.9 KiB
JavaScript
177 lines
5.9 KiB
JavaScript
// Copyright 2023 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
|
|
|
|
// Test that cloning the empty object yields the same shape in monomorphic
|
|
// state.
|
|
(function() {
|
|
function clone(o) {
|
|
return {...o};
|
|
}
|
|
|
|
const o = {};
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%PrepareFunctionForOptimization(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%OptimizeFunctionOnNextCall(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
})();
|
|
|
|
// Test that cloning an object with a single data field yields the same shape
|
|
// in monomorphic state.
|
|
(function() {
|
|
function clone(o) {
|
|
return {...o};
|
|
}
|
|
|
|
const o = {a: "a"};
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%PrepareFunctionForOptimization(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%OptimizeFunctionOnNextCall(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
})();
|
|
|
|
// Test that cloning fast mode objects yields the same shape in polymorphic state.
|
|
(function() {
|
|
function clone(o) {
|
|
return {...o};
|
|
}
|
|
|
|
const o0 = {};
|
|
const o1 = {a: "a"};
|
|
const o2 = {a: "a", b: "b"};
|
|
assertTrue(%HaveSameMap(o0, clone(o0)));
|
|
assertTrue(%HaveSameMap(o1, clone(o1)));
|
|
assertTrue(%HaveSameMap(o2, clone(o2)));
|
|
%PrepareFunctionForOptimization(clone);
|
|
assertTrue(%HaveSameMap(o0, clone(o0)));
|
|
assertTrue(%HaveSameMap(o1, clone(o1)));
|
|
assertTrue(%HaveSameMap(o2, clone(o2)));
|
|
assertTrue(%HaveSameMap(o0, clone(o0)));
|
|
assertTrue(%HaveSameMap(o1, clone(o1)));
|
|
assertTrue(%HaveSameMap(o2, clone(o2)));
|
|
%OptimizeFunctionOnNextCall(clone);
|
|
assertTrue(%HaveSameMap(o0, clone(o0)));
|
|
assertTrue(%HaveSameMap(o1, clone(o1)));
|
|
assertTrue(%HaveSameMap(o2, clone(o2)));
|
|
})();
|
|
|
|
// Test that cloning the empty object with `null` prototype (in fast mode)
|
|
// yields the same shape in monomorphic state.
|
|
(function() {
|
|
function clone(o) {
|
|
return {...o, __proto__: null};
|
|
}
|
|
|
|
const o = {};
|
|
Object.setPrototypeOf(o, null);
|
|
assertTrue(%HasFastProperties(o));
|
|
assertNull(Object.getPrototypeOf(o));
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%PrepareFunctionForOptimization(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
%OptimizeFunctionOnNextCall(clone);
|
|
assertTrue(%HaveSameMap(o, clone(o)));
|
|
})();
|
|
|
|
// Test that different CloneObjectICs produce the same shape for the same
|
|
// object literal inputs with non-default property attributes.
|
|
(function() {
|
|
function clone1(o) {
|
|
return {...o};
|
|
}
|
|
function clone2(o) {
|
|
return {...o};
|
|
}
|
|
|
|
const o1 = {x: "x", y: "y", z: "z"};
|
|
Object.defineProperty(o1, 'x', {configurable:false, writable:false});
|
|
Object.defineProperty(o1, 'y', {configurable:false});
|
|
Object.defineProperty(o1, 'z', {writable:false});
|
|
assertTrue(%HasFastProperties(o1));
|
|
|
|
const o2 = {a: 1, b: 2, c: 3, d: 4};
|
|
Object.defineProperty(o2, 'c', {writable:false});
|
|
Object.defineProperty(o2, 'd', {configurable:false});
|
|
assertTrue(%HasFastProperties(o2));
|
|
|
|
for (const o of [o1, o2]) {
|
|
for (const clone of [clone1, clone2]) {
|
|
const c = clone(o);
|
|
assertFalse(%HaveSameMap(o, c));
|
|
assertEquals(Object.keys(o), Object.keys(c));
|
|
for (const key of Object.keys(c)) {
|
|
const d = Object.getOwnPropertyDescriptor(c, key);
|
|
assertTrue(d.configurable);
|
|
assertTrue(d.enumerable);
|
|
assertTrue(d.writable);
|
|
assertEquals(d.value, o[key]);
|
|
}
|
|
}
|
|
}
|
|
assertTrue(%HaveSameMap(clone1(o1), {x: "x", y: "y", z: "z"}));
|
|
assertTrue(%HaveSameMap(clone2(o2), {a: 1, b: 2, c: 3, d: 4}));
|
|
%PrepareFunctionForOptimization(clone1);
|
|
%PrepareFunctionForOptimization(clone2);
|
|
assertTrue(%HaveSameMap(clone1(o1), clone2(o1)));
|
|
assertTrue(%HaveSameMap(clone1(o1), clone2(o1)));
|
|
assertTrue(%HaveSameMap(clone1(o2), clone2(o2)));
|
|
assertTrue(%HaveSameMap(clone1(o2), clone2(o2)));
|
|
assertTrue(%HaveSameMap(clone1(o1), {x: "x", y: "y", z: "z"}));
|
|
assertTrue(%HaveSameMap(clone2(o2), {a: 1, b: 2, c: 3, d: 4}));
|
|
%OptimizeFunctionOnNextCall(clone1);
|
|
%OptimizeFunctionOnNextCall(clone2);
|
|
assertTrue(%HaveSameMap(clone1(o1), clone2(o1)));
|
|
assertTrue(%HaveSameMap(clone1(o2), clone2(o2)));
|
|
assertTrue(%HaveSameMap(clone1(o1), {x: "x", y: "y", z: "z"}));
|
|
assertTrue(%HaveSameMap(clone2(o2), {a: 1, b: 2, c: 3, d: 4}));
|
|
})();
|
|
|
|
// Test that different CloneObjectICs produce the same shape for trivial
|
|
// constructor instances in monomorphic state.
|
|
(function() {
|
|
function clone1(o) {
|
|
return {...o};
|
|
}
|
|
function clone2(o) {
|
|
return {...o};
|
|
}
|
|
|
|
class A {
|
|
constructor() {
|
|
this.a = 1;
|
|
this.b = 2;
|
|
this.c = 3;
|
|
this.d = 4;
|
|
}
|
|
};
|
|
for (let i = 0; i < 10; ++i) new A(); // Finish slack tracking
|
|
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone2(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone2(new A())));
|
|
%PrepareFunctionForOptimization(clone1);
|
|
%PrepareFunctionForOptimization(clone2);
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone2(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone2(new A())));
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone2(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone2(new A())));
|
|
%OptimizeFunctionOnNextCall(clone1);
|
|
%OptimizeFunctionOnNextCall(clone2);
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone1(new A()), clone2(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone1(new A())));
|
|
assertTrue(%HaveSameMap(clone2(new A()), clone2(new A())));
|
|
})();
|