// Copyright 2017 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 EnsureDictionaryMode(obj, properties=1500) {
  for (let i = 0; i < properties; i++) {
    obj["x" + i] = 0;
  }
  assertFalse(%HasFastProperties(obj));
}

function EnsureAlmostDictionaryMode(obj) {
  for (let i = 0; i < 1020; i++) {
    obj["x" + i] = 0;
  }
}

function TestAddingPropertyToDictionaryPrototype() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      // The UNINITIALIZED -> PREMONOMORPHIC transition of StoreIC should
      // properly invalidate prototype chains.
      Bar.prototype.func = function() { ++bar_func_called; }
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToDictionaryPrototype();

// Same as TestAddingPropertyToDictionaryPrototype, but using o["foo"] access
// instead of o.foo.
function TestAddingPropertyToDictionaryPrototype2() {
  let foo_func_called = 0;
  let bar_func_called = 0;
  let name = "func";

  function Foo() {}
  Foo.prototype[name] = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o[name]();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      // The UNINITIALIZED -> PREMONOMORPHIC transition of KeyedStoreIC should
      // properly invalidate prototype chains.
      Bar.prototype[name] = function() { ++bar_func_called; }
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToDictionaryPrototype2();

function TestAddingPropertyToDictionaryPrototype_DefineProperty() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      // The runtime should properly invalidate prototype chains.
      Object.defineProperty(Bar.prototype, "func", {value: function() { ++bar_func_called; }});
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToDictionaryPrototype_DefineProperty();

function TestAddingPropertyToDictionaryPrototype_DictionaryAddSlowPath() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  // The magic number ensures that the next addition to the dictionary will
  // trigger the slow path.
  EnsureDictionaryMode(Bar.prototype, 2731);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      // -> slow path for dictionary add
      Bar.prototype.func = function() { ++bar_func_called; }
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToDictionaryPrototype_DictionaryAddSlowPath();

function TestAddingAccessorPropertyToDictionaryPrototype() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      Object.defineProperty(Bar.prototype, "func",
                            {get: function() { return function() { ++bar_func_called; }}});
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingAccessorPropertyToDictionaryPrototype();

function TestRemovingPropertyFromDictionaryPrototype() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);
  Bar.prototype.func = function() { ++bar_func_called; }

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Bar.
    o.func();

    // Remove the property from Bar which is a dictionary-mode prototype between
    // o and Foo. In the next iteration, it's looked up from Foo.
    if (i == 9) {
      delete Bar.prototype.func;
    }
  }

  assertEquals(1, foo_func_called);
  assertEquals(10, bar_func_called);
}

TestRemovingPropertyFromDictionaryPrototype();

// Same as TestRemovingPropertyFromDictionaryPrototype, but using o["foo"] access
// instead of o.foo.
function TestRemovingPropertyFromDictionaryPrototype2() {
  let foo_func_called = 0;
  let bar_func_called = 0;
  let name = "func";

  function Foo() {}
  Foo.prototype[name] = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);
  Bar.prototype[name] = function() { ++bar_func_called; }

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Bar.
    o[name]();

    // Remove the property from Bar which is a dictionary-mode prototype between
    // o and Foo. In the next iteration, it's looked up from Foo.
    if (i == 9) {
      delete Bar.prototype[name];
    }
  }

  assertEquals(1, foo_func_called);
  assertEquals(10, bar_func_called);
}

TestRemovingPropertyFromDictionaryPrototype2();

function TestAddingPropertyToDictionaryPrototype_Monomorphic() {
  function DoMonomorphicStoreToPrototype(p, f, do_delete=true) {
    p.func = f;
    if (do_delete) {
      delete p.func;
    }
  }

  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  function bar_func() {
    ++bar_func_called;
  }
  DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);
  DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);
  DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      DoMonomorphicStoreToPrototype(Bar.prototype, bar_func, false);
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToDictionaryPrototype_Monomorphic();

function TestAddingKeyedPropertyToDictionaryPrototype_Monomorphic() {
  function DoMonomorphicKeyedStoreToPrototype(p, name, f, do_delete=true) {
    p[name] = f;
    if (do_delete) {
      delete p[name];
    }
  }

  let foo_func_called = 0;
  let bar_func_called = 0;
  let name = "func";

  function Foo() {}
  Foo.prototype[name] = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureDictionaryMode(Bar.prototype);

  function bar_func() {
    ++bar_func_called;
  }
  DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);
  DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);
  DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);

  let o = new Bar();

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which is a dictionary-mode prototype between o
    // and Foo. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func, false);
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingKeyedPropertyToDictionaryPrototype_Monomorphic();

// Like TestAddingPropertyToDictionaryPrototype, except that the prototype isn't
// in dictionary mode yet, but turns to dictionary mode after the interesting
// property is added.
function TestAddingPropertyToAlmostDictionaryPrototype() {
  let foo_func_called = 0;
  let bar_func_called = 0;

  function Foo() {}
  Foo.prototype.func = function() { ++foo_func_called; }

  function Bar() {}
  Bar.prototype = Object.create(Foo.prototype);
  EnsureAlmostDictionaryMode(Bar.prototype);

  let o = new Bar();
  for (let i = 0; i < 2; ++i) {
    o.x0;
  }
  assertTrue(%HasFastProperties(Bar.prototype));

  for (let i = 0; i < 11; ++i) {
    // First, the property is looked up from Foo.
    o.func();

    // Add the property to Bar which will now turn permanently into dictionary
    // mode. In the next iteration, it's looked up from Bar.
    if (i == 9) {
      Bar.prototype.func = function() { ++bar_func_called; }
      assertFalse(%HasFastProperties(Bar.prototype));
    }
  }

  assertEquals(10, foo_func_called);
  assertEquals(1, bar_func_called);
}

TestAddingPropertyToAlmostDictionaryPrototype();

function TestReconfiguringDataToAccessor() {
  let setter_called = 0;

  function Bar() {}
  EnsureDictionaryMode(Bar.prototype);
  let name = "prop";
  Object.defineProperty(Bar.prototype, name,
                        {value: 1000, writable: true, configurable: true});

  for (let i = 0; i < 11; ++i) {
    let obj1 = new Bar();
    if (i < 10) {
      assertEquals(1000, obj1.prop);
    } else {
      assertEquals(3000, obj1.prop);
    }

    // Add the property into the object.
    obj1.prop = 2000;
    if (i < 10) {
      assertEquals(2000, obj1.prop);
    } else {
      assertEquals(3000, obj1.prop);
    }

    // Make "prop" an accessor property in the prototype.
    if (i == 9) {
      Object.defineProperty(Bar.prototype, name,
                            {get: () => 3000,
                             set: function(val) { ++setter_called; }});
    }
  }
  assertEquals(1, setter_called);
}

TestReconfiguringDataToAccessor();
