regress-222029-002.js (2605B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 * 8 * Date: 13 Oct 2003 9 * SUMMARY: Make our f.caller property match IE's wrt f.apply and f.call 10 * See http://bugzilla.mozilla.org/show_bug.cgi?id=222029 11 * 12 * Below, when gg calls f via |f.call|, we have this call chain: 13 * 14 * calls calls 15 * gg() ---------> Function.prototype.call() ---------> f() 16 * 17 * 18 * The question this bug addresses is, "What should we say |f.caller| is?" 19 * 20 * Before this fix, SpiderMonkey said it was |Function.prototype.call|. 21 * After this fix, SpiderMonkey emulates IE and says |gg| instead. 22 * 23 */ 24 //----------------------------------------------------------------------------- 25 var UBound = 0; 26 var BUGNUMBER = 222029; 27 var summary = "Make our f.caller property match IE's wrt f.apply and f.call"; 28 var status = ''; 29 var statusitems = []; 30 var actual = ''; 31 var actualvalues = []; 32 var expect= ''; 33 var expectedvalues = []; 34 35 /* 36 * Try to confuse the engine by adding a |p| property to everything! 37 */ 38 var p = 'global'; 39 var o = {p:'object'}; 40 41 42 function f(obj) 43 { 44 return f.caller.p ; 45 } 46 47 48 /* 49 * Call |f| directly 50 */ 51 function g(obj) 52 { 53 var p = 'local'; 54 return f(obj); 55 } 56 g.p = "hello"; 57 58 59 /* 60 * Call |f| via |f.call| 61 */ 62 function gg(obj) 63 { 64 var p = 'local'; 65 return f.call(obj, obj); 66 } 67 gg.p = "hello"; 68 69 70 /* 71 * Call |f| via |f.apply| 72 */ 73 function ggg(obj) 74 { 75 var p = 'local'; 76 return f.apply(obj, [obj]); 77 } 78 ggg.p = "hello"; 79 80 81 /* 82 * Shadow |p| on |Function.prototype.call|, |Function.prototype.apply|. 83 * In Sections 2 and 3 below, we no longer expect to recover this value - 84 */ 85 Function.prototype.call.p = "goodbye"; 86 Function.prototype.apply.p = "goodbye"; 87 88 89 90 status = inSection(1); 91 actual = g(o); 92 expect = "hello"; 93 addThis(); 94 95 status = inSection(2); 96 actual = gg(o); 97 expect = "hello"; 98 addThis(); 99 100 status = inSection(3); 101 actual = ggg(o); 102 expect = "hello"; 103 addThis(); 104 105 106 107 108 //----------------------------------------------------------------------------- 109 test(); 110 //----------------------------------------------------------------------------- 111 112 113 114 function addThis() 115 { 116 statusitems[UBound] = status; 117 actualvalues[UBound] = actual; 118 expectedvalues[UBound] = expect; 119 UBound++; 120 } 121 122 123 function test() 124 { 125 printBugNumber(BUGNUMBER); 126 printStatus(summary); 127 128 for (var i=0; i<UBound; i++) 129 { 130 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); 131 } 132 }