michael@0: michael@0: // Test various code paths associated with fused getprop/poly inlining. michael@0: michael@0: function A(a) { this.a = a; } michael@0: A.prototype.foo = function (x) { return (x % 3) + this.a; }; michael@0: michael@0: function B(b) { this.b = b; } michael@0: B.prototype.foo = function (x) { return (x % 3) + this.b + 1; }; michael@0: michael@0: // c.foo() for some (c instanceof C) should always hit the fallback michael@0: // path of any fused poly inline cache created for it. michael@0: function C(c) { this.c = c; } michael@0: var GLOBX = {'x': function (x) { michael@0: if (x > 29500) michael@0: throw new Error("ERROR"); michael@0: return 2; michael@0: }}; michael@0: function C_foo1(x) { michael@0: return (x % 3) + this.c + GLOBX.x(x) + 1; michael@0: } michael@0: function C_foo2(x) { michael@0: return (x % 3) + this.c + GLOBX.x(x) + 2; michael@0: } michael@0: C.prototype.foo = C_foo1; michael@0: michael@0: // Create an array of As, Bs, and Cs. michael@0: function makeArray(n) { michael@0: var classes = [A, B, C]; michael@0: var arr = []; michael@0: for (var i = 0; i < n; i++) { michael@0: arr.push(new classes[i % 3](i % 3)); michael@0: } michael@0: return arr; michael@0: } michael@0: michael@0: // Call foo on them, sum up results into first elem of resultArray michael@0: function runner(arr, resultArray, len) { michael@0: for (var i = 0; i < len; i++) { michael@0: // This changes the type of returned value from C.foo(), leading to michael@0: // a bailout fater the call obj.foo() below. michael@0: var obj = arr[i]; michael@0: resultArray[0] += obj.foo(i); michael@0: } michael@0: } michael@0: michael@0: // Make an array of instance. michael@0: var resultArray = [0]; michael@0: var arr = makeArray(30000); michael@0: michael@0: // Run runner for a bit with C.prototype.foo being C_foo1 michael@0: runner(arr, resultArray, 100); michael@0: michael@0: // Run runner for a bit with C.prototype.foo being C_foo2 michael@0: C.prototype.foo = C_foo2; michael@0: runner(arr, resultArray, 100); michael@0: michael@0: // Run runner for a bit longer to force GLOBX.x to raise michael@0: // an error inside a call to C.prototype.foo within runner. michael@0: var gotError = false; michael@0: try { michael@0: runner(arr, resultArray, 30000); michael@0: } catch(err) { michael@0: gotError = true; michael@0: } michael@0: michael@0: // Check results. michael@0: assertEq(gotError, true); michael@0: assertEq(resultArray[0], 108859);