//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

// Switches: -bgJit- -maxInterpretCount:2

// Test 1: Invalidate constructor cache by changing the constructor's prototype property.
WScript.Echo("Test 1:");

var SimpleObject1 = function () {
    this.a = 0;
    this.b = 1;
}

var proto1a = { p: 100 };
var proto1b = { p: 200 };

SimpleObject1.prototype = proto1a;

var test1 = function () {
    var o = new SimpleObject1();
    o.x = 10;
    o.y = 11;
    return o;
}

var oa1 = new Array();

// Run twice in the interpreter to populate add property caches and kick off JIT compilation.
oa1.push(test1());
oa1.push(test1());

// Run once along the happy path.
oa1.push(test1());

// Now change the prototype object to invalidate the constructor cache and cause a bailout.
SimpleObject1.prototype = proto1b;

oa1.push(test1());

// Run a few more times (bailing out every time) to force a re-JIT.  After re-JIT the optimization
// should be disabled because the constructor cache is now marked as polymorphic.

oa1.push(test1());
oa1.push(test1());
oa1.push(test1());
oa1.push(test1());
oa1.push(test1());

for (var i = 0; i < oa1.length; i++) {
    var o = oa1[i];
    WScript.Echo("oa1[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }");
}
WScript.Echo("");

// Test 2: Invalidate the constructor cache by making one of the properties added in the
// constructor read-only
WScript.Echo("Test 2:");

var SimpleObject2 = function () {
    this.a = 0;
    this.b = 1;
    this.c = 2;
}

var proto2a = { p: 100 };

SimpleObject2.prototype = proto2a;

var test2 = function () {
    var o = new SimpleObject2();
    o.x = 10;
    o.y = 11;
    return o;
}

var oa2 = new Array();

// Run twice in the interpreter to populate add property caches and kick off JIT compilation.
oa2.push(test2());
oa2.push(test2());

// Run once along the happy path.
oa2.push(test2());

// Now invalidate the constructor cache by making one of the properties added in the constructor
// read-only.
Object.defineProperty(proto2a, "a", { value: 101, writable: false });

oa2.push(test2());

// Run a few more times (bailing out every time) to force a re-JIT.  After re-JIT, we should no longer
// have the offending property access object type specialized, and thus protected by the ctor guard.
oa2.push(test2());
oa2.push(test2());
oa2.push(test2());
oa2.push(test2());
oa2.push(test2());

for (var i = 0; i < oa2.length; i++) {
    var o = oa2[i];
    WScript.Echo("oa2[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }");
}
WScript.Echo("");

// Test 3: Invalidate the constructor cache by making one of the properties added after the
// constructor read-only
WScript.Echo("Test 3:");

var SimpleObject3 = function () {
    this.a = 0;
    this.b = 1;
}

var proto3a = { p: 100 };

SimpleObject3.prototype = proto3a;

var test3 = function () {
    var o = new SimpleObject3();
    o.x = 10;
    o.y = 11;
    return o;
}

var oa3 = new Array();

// Run twice in the interpreter to populate add property caches and kick off JIT compilation.
oa3.push(test3());
oa3.push(test3());

// Run once along the happy path.
oa3.push(test3());

// Now invalidate the constructor cache by making one of the properties added in the constructor
// read-only.
Object.defineProperty(proto3a, "x", { value: 102, writable: false });

oa3.push(test3());

// Run a few more times (bailing out every time) to force a re-JIT.  After re-JIT, we should no longer
// have the offending property access object type specialized, and thus protected by the ctor guard.
oa3.push(test3());
oa3.push(test3());
oa3.push(test3());
oa3.push(test3());
oa3.push(test3());

for (var i = 0; i < oa3.length; i++) {
    var o = oa3[i];
    WScript.Echo("oa3[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }");
}
WScript.Echo("");

// Test 4: Invalidate constructor cache by changing the constructor's prototype property.
WScript.Echo("Test 4:");

var SimpleObject4 = function () {
    this.a = this.p + 0;
    this.b = this.p + 1;
    this.c = this.p + 2;
    this.d = this.p + 3;
    this.e = this.p + 4;
    this.f = this.p + 5;
    this.g = this.p + 6;
    this.h = this.p + 7;
    this.i = this.p + 8;
    this.j = this.p + 9;
}

var proto4a = { p: 100 };
var proto4b = Object.create(proto4a);

SimpleObject4.prototype = proto4b;

var test4 = function () {
    var o = new SimpleObject4();
    o.x = o.p + 10;
    o.y = o.p + 11;
    return o;
}

var oa4 = new Array();

// Run twice in the interpreter to populate add property caches and kick off JIT compilation.
oa4.push(test4());
oa4.push(test4());

// Run once along the happy path.
oa4.push(test4());

// Now change the prototype object to invalidate the constructor cache and cause a bailout.
proto4b.p = 200;

oa4.push(test4());

// Run a few more times (bailing out every time) to force a re-JIT.  After re-JIT, we should no longer
// have the offending property access object type specialized, and thus protected by the ctor guard.
// This time all the other property operations should remain object type specialized, because the type
// of the object created is not affected by this change to the prototype chain.
oa4.push(test4());
oa4.push(test4());
oa4.push(test4());
oa4.push(test4());
oa4.push(test4());

for (var i = 0; i < oa4.length; i++) {
    var o = oa4[i];
    WScript.Echo("oa4[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + ", i: " + o.i + ", j: " + o.j + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }");
}
WScript.Echo("");
