diff options
Diffstat (limited to 'js/src/jit-test/tests/basic/testWatchRecursion.js')
-rw-r--r-- | js/src/jit-test/tests/basic/testWatchRecursion.js | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/basic/testWatchRecursion.js b/js/src/jit-test/tests/basic/testWatchRecursion.js new file mode 100644 index 000000000..e5d5877df --- /dev/null +++ b/js/src/jit-test/tests/basic/testWatchRecursion.js @@ -0,0 +1,63 @@ +// Test that the watch handler is not called recursively for the same object +// and property. +(function() { + var obj1 = {}, obj2 = {}; + var handler_entry_count = 0; + var handler_exit_count = 0; + + obj1.watch('x', handler); + obj1.watch('y', handler); + obj2.watch('x', handler); + obj1.x = 1; + assertEq(handler_entry_count, 3); + assertEq(handler_exit_count, 3); + + function handler(id) { + handler_entry_count++; + assertEq(handler_exit_count, 0); + switch (true) { + case this === obj1 && id === "x": + assertEq(handler_entry_count, 1); + obj2.x = 3; + assertEq(handler_exit_count, 2); + break; + case this === obj2 && id === "x": + assertEq(handler_entry_count, 2); + obj1.y = 4; + assertEq(handler_exit_count, 1); + break; + default: + assertEq(this, obj1); + assertEq(id, "y"); + assertEq(handler_entry_count, 3); + + // We expect no more watch handler invocations + obj1.x = 5; + obj1.y = 6; + obj2.x = 7; + assertEq(handler_exit_count, 0); + break; + } + ++handler_exit_count; + assertEq(handler_entry_count, 3); + } +})(); + + +// Test that run-away recursion in watch handlers is properly handled. +(function() { + var obj = {}; + var i = 0; + try { + handler(); + throw new Error("Unreachable"); + } catch(e) { + assertEq(e instanceof InternalError, true); + } + + function handler() { + var prop = "a" + ++i; + obj.watch(prop, handler); + obj[prop] = 2; + } +})(); |