1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 1. Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // 2. Redistributions in binary form must reproduce the above copyright 10 // notice, this list of conditions and the following disclaimer in the 11 // documentation and/or other materials provided with the distribution. 12 // 13 // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24 description( 25 "This test checks that toString() round-trip on a function that has prefix, postfix and typeof operators applied to group expression will not remove the grouping. Also checks that evaluation of such a expression produces run-time exception" 26 ); 27 28 function postfix_should_preserve_parens(x, y, z) { 29 (x, y)++; 30 return y; 31 } 32 33 function prefix_should_preserve_parens(x, y, z) { 34 ++(x, y); 35 return x; 36 37 } 38 39 function both_should_preserve_parens(x, y, z) { 40 ++(x, y)--; 41 return x; 42 43 } 44 45 function postfix_should_preserve_parens_multi(x, y, z) { 46 (((x, y)))--; 47 return x; 48 } 49 50 function prefix_should_preserve_parens_multi(x, y, z) { 51 --(((x, y))); 52 return x; 53 } 54 55 function both_should_preserve_parens_multi(x, y, z) { 56 ++(((x, y)))--; 57 return x; 58 } 59 60 function postfix_should_preserve_parens_multi1(x, y, z) { 61 (((x)), y)--; 62 return x; 63 } 64 65 function prefix_should_preserve_parens_multi1(x, y, z) { 66 --(((x)), y); 67 return x; 68 } 69 70 function prefix_should_preserve_parens_multi2(x, y, z) { 71 var z = 0; 72 --(((x), y), z); 73 return x; 74 } 75 76 function postfix_should_preserve_parens_multi2(x, y, z) { 77 var z = 0; 78 (((x), y) ,z)++; 79 return x; 80 } 81 82 // if these return a variable (such as y) instead of 83 // the result of typeof, this means that the parenthesis 84 // got lost somewhere. 85 function typeof_should_preserve_parens(x, y, z) { 86 return typeof (x, y); 87 } 88 89 function typeof_should_preserve_parens1(x, y, z) { 90 return typeof ((x, y)); 91 } 92 93 function typeof_should_preserve_parens2(x, y, z) { 94 var z = 33; 95 return typeof (z, (x, y)); 96 } 97 98 function typeof_should_preserve_parens_multi(x, y, z) { 99 var z = 33; 100 return typeof ((z,(((x, y))))); 101 } 102 103 unevalf = function(x) { return '(' + x.toString() + ')'; }; 104 105 function testToString(fn) { 106 // check that toString result evaluates to code that can be evaluated 107 // this doesn't actually reveal the bug that this test is testing 108 shouldBe("unevalf(eval(unevalf("+fn+")))", "unevalf(" + fn + ")"); 109 110 // check that grouping operator is still there (this test reveals the bug 111 // but will create possible false negative if toString output changes in 112 // the future) 113 shouldBeTrue("/.*\\(+x\\)*, y\\)/.test(unevalf("+fn+"))"); 114 115 } 116 117 function testToStringAndRTFailure(fn) 118 { 119 testToString(fn); 120 121 // check that function call produces run-time exception 122 shouldThrow(""+fn+ "(1, 2, 3);"); 123 124 // check that function call produces run-time exception after eval(unevalf) 125 shouldThrow("eval(unevalf("+fn+ "))(1, 2, 3);"); 126 } 127 128 function testToStringAndReturn(fn, p1, p2, retval) 129 { 130 131 testToString(fn); 132 133 // check that function call produces correct result 134 shouldBe("" + fn + "(" + p1 + ", " + p2 +");", retval); 135 136 // check that function call produces correct result after eval(unevalf) 137 shouldBe("eval(unevalf("+fn+ "))" + "(" + p1 + ", " + p2 +");", retval); 138 } 139 140 141 testToStringAndRTFailure("prefix_should_preserve_parens"); 142 testToStringAndRTFailure("postfix_should_preserve_parens"); 143 testToStringAndRTFailure("both_should_preserve_parens"); 144 testToStringAndRTFailure("prefix_should_preserve_parens_multi"); 145 testToStringAndRTFailure("postfix_should_preserve_parens_multi"); 146 testToStringAndRTFailure("prefix_should_preserve_parens_multi1"); 147 testToStringAndRTFailure("postfix_should_preserve_parens_multi1"); 148 testToStringAndRTFailure("prefix_should_preserve_parens_multi2"); 149 testToStringAndRTFailure("postfix_should_preserve_parens_multi2"); 150 151 testToStringAndReturn("typeof_should_preserve_parens", "'a'", 1, "'number'"); 152 testToStringAndReturn("typeof_should_preserve_parens1", "'a'", 1, "'number'"); 153 testToStringAndReturn("typeof_should_preserve_parens2", "'a'", 1, "'number'"); 154 testToStringAndReturn("typeof_should_preserve_parens_multi", "'a'", 1, "'number'"); 155