summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js')
-rw-r--r--js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js56
1 files changed, 56 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js b/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
new file mode 100644
index 000000000..85410bbd4
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
@@ -0,0 +1,56 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function make_watcher(name) {
+ return function (id, oldv, newv) {
+ print("watched " + name + "[0]");
+ };
+}
+
+var o, p;
+function f(flag) {
+ if (flag) {
+ o = arguments;
+ } else {
+ p = arguments;
+ o.watch(0, make_watcher('o'));
+ p.watch(0, make_watcher('p'));
+
+ /*
+ * Previously, the watchpoint implementation actually substituted its magic setter
+ * functions for the setters of shared shapes, and then 1) carefully ignored calls
+ * to its magic setter from unrelated objects, and 2) avoided restoring the
+ * original setter until all watchpoints on that shape had been removed.
+ *
+ * However, when the watchpoint code began using JSObject::changeProperty and
+ * js_ChangeNativePropertyAttrs to change shapes' setters, the shape tree code
+ * became conscious of the presence of watchpoints, and shared shapes between
+ * objects only when their watchpoint nature coincided. Clearing the magic setter
+ * from one object's shape would not affect other objects, because the
+ * watchpointed and non-watchpointed shapes were distinct if they were shared.
+ *
+ * Thus, the first unwatch call must go ahead and fix p's shape, even though a
+ * watchpoint exists on the same shape in o. o's watchpoint's presence shouldn't
+ * cause 'unwatch' to leave p's magic setter in place.
+ */
+
+ /* DropWatchPointAndUnlock would see o's watchpoint, and not change p's property. */
+ p.unwatch(0);
+
+ /* DropWatchPointAndUnlock would fix o's property, but not p's; p's setter would be gone. */
+ o.unwatch(0);
+
+ /* This would fail to invoke the arguments object's setter. */
+ p[0] = 4;
+
+ /* And the formal parameter would not get updated. */
+ assertEq(flag, 4);
+ }
+}
+
+f(true);
+f(false);
+
+reportCompare(true, true);