cross-global-implicit-this.js (3760B)
1 // |reftest| skip-if(!xulRuntime.shell) -- needs evaluate() 2 // Any copyright is dedicated to the Public Domain. 3 // http://creativecommons.org/licenses/publicdomain/ 4 5 //----------------------------------------------------------------------------- 6 var BUGNUMBER = 671947; 7 var summary = "Unqualified function invocation uses the global object of the called property as |this|"; 8 9 print(BUGNUMBER + ": " + summary); 10 11 /************** 12 * BEGIN TEST * 13 **************/ 14 15 this.name = "o"; 16 17 function f() { 18 return this ? this.name : "t"; 19 } 20 function g() { 21 "use strict"; 22 return this ? this.name : "u"; 23 } 24 function h() { 25 return this ? this.name : "v"; 26 } 27 28 var sb = newGlobal(); 29 sb.parent = this; 30 sb.name = "i"; 31 sb.f = f; 32 sb.g = g; 33 34 sb.evaluate( 35 '\n' + 36 ' this.a = { name: "a", f: f, g: g };\n' + 37 ' this.b = { name: "b", f: f, g: g };\n' + 38 ' Object.defineProperty(this, "h", { get: (function(){ return parent.h; })});\n' + 39 ' Object.defineProperty(a, "h", { get: (function(){ return parent.h; })});\n' + 40 ' Object.defineProperty(b, "h", { get: (function(){ return parent.h; })});\n' + 41 ''); 42 43 44 // Three of the first four cases pass undefined (promoted inside the callee to 45 // the callee's global object). a.f() is the one exception, which passes the 46 // base, a, as the this object. 47 assertEq(sb.evaluate('(function(){return f();})();'), "o"); 48 assertEq(sb.evaluate('(function(){return (1,f)();})();'), "o"); 49 assertEq(sb.evaluate('(function(){return a.f();})();'), "a"); 50 assertEq(sb.evaluate('(function(){return eval("f()");})();'), "o"); 51 52 // Same cases as above, but wrapped in a with. The first and last of these cases 53 // pass b, the object scoped by the with, as the this value. a.f() still passes 54 // the explicit base, a. (1,f)() is a little tricksier - this passes undefined 55 // (promoted to the callee global object) since the comma operator calls 56 // GetValue on the reference (see ES5 11.14.). 57 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return f();})(); }})();'), "b"); 58 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return (1,f)();})(); }})();'), "o"); 59 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return a.f();})(); }})();'), "a"); 60 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("f()");})(); }})();'), "b"); 61 62 // Same tests as above, but with a strict callee. We expect the same results, 63 // except undefined this is not replaced with the global object. 64 assertEq(sb.evaluate('(function(){return g();})();'), "u"); 65 assertEq(sb.evaluate('(function(){return (1,g)();})();'), "u"); 66 assertEq(sb.evaluate('(function(){return a.g();})();'), "a"); 67 assertEq(sb.evaluate('(function(){return eval("g()");})();'), "u"); 68 assertEq(sb.evaluate('(function(){with(b){ return g(); }})();'), "b"); 69 assertEq(sb.evaluate('(function(){with(b){ return (1,g)(); }})();'), "u"); 70 assertEq(sb.evaluate('(function(){with(b){ return a.g(); }})();'), "a"); 71 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("g()");})(); }})();'), "b"); 72 73 /* Same as the first set, but h is a getter property. */ 74 assertEq(sb.evaluate('(function(){return h();})();'), "o"); 75 assertEq(sb.evaluate('(function(){return (1,h)();})();'), "o"); 76 assertEq(sb.evaluate('(function(){return a.h();})();'), "a"); 77 assertEq(sb.evaluate('(function(){return eval("h()");})();'), "o"); 78 assertEq(sb.evaluate('(function(){with(b){ return h(); }})();'), "b"); 79 assertEq(sb.evaluate('(function(){with(b){ return (1,h)(); }})();'), "o"); 80 assertEq(sb.evaluate('(function(){with(b){ return a.h(); }})();'), "a"); 81 assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("h()");})(); }})();'), "b"); 82 83 if (typeof reportCompare === "function"); 84 reportCompare(true, true);