summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/global-prototypes.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/global-prototypes.js')
-rw-r--r--deps/v8/test/mjsunit/global-prototypes.js354
1 files changed, 354 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/global-prototypes.js b/deps/v8/test/mjsunit/global-prototypes.js
new file mode 100644
index 0000000000..98232c2814
--- /dev/null
+++ b/deps/v8/test/mjsunit/global-prototypes.js
@@ -0,0 +1,354 @@
+// 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
+
+
+assertEquals(this.__proto__, Object.prototype);
+
+function TestAddingPropertyToGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ 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 Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Bar.prototype.func = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype();
+
+
+// Same as TestAddingPropertyToGlobalPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestAddingPropertyToGlobalPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ delete this[name];
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ 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 Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Bar.prototype[name] = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype2();
+
+
+function TestAddingPropertyToGlobalPrototype_DefineProperty() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ 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 Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, "func",
+ {
+ value: function() { ++bar_func_called; },
+ configurable:true
+ });
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_DefineProperty();
+
+
+function TestAddingAccessorPropertyToGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ 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 Global-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; }},
+ configurable: true
+ });
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingAccessorPropertyToGlobalPrototype();
+
+
+function TestRemovingPropertyFromGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+ 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 Global-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);
+}
+
+TestRemovingPropertyFromGlobalPrototype();
+
+
+// Same as TestRemovingPropertyFromGlobalPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestRemovingPropertyFromGlobalPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+ 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 Global-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);
+}
+
+TestRemovingPropertyFromGlobalPrototype2();
+
+
+function TestAddingPropertyToGlobalPrototype_MonomorphicDot() {
+ function DoMonomorphicStoreToPrototypeDot(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; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototypeDot(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 Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_MonomorphicDot();
+
+
+function TestAddingPropertyToGlobalPrototype_MonomorphicBrackets() {
+ function DoMonomorphicStoreToPrototypeBrackets(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; }
+
+ delete this[name];
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func);
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func);
+ DoMonomorphicStoreToPrototypeBrackets(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 Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_MonomorphicBrackets();
+
+
+function TestReconfiguringDataToAccessor() {
+ let setter_called = 0;
+ let name = "prop";
+
+ delete this[name];
+ this.__proto__ = Object.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ 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();