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 'Tests whether eval() works inside statements that read and modify a value.' 26 ); 27 28 function multTest() 29 { 30 var x = 1; 31 x *= eval('2'); 32 return x == 2; 33 } 34 35 function divTest() 36 { 37 var x = 2; 38 x /= eval('2'); 39 return x == 1; 40 } 41 42 function addTest() 43 { 44 var x = 0; 45 x += eval('1'); 46 return x == 1; 47 } 48 49 function subTest() 50 { 51 var x = 0; 52 x -= eval('1'); 53 return x == -1; 54 } 55 56 function lshiftTest() 57 { 58 var x = 1; 59 x <<= eval('1'); 60 return x == 2; 61 } 62 63 function rshiftTest() 64 { 65 var x = 1; 66 x >>= eval('1'); 67 return x == 0; 68 } 69 70 function urshiftTest() 71 { 72 var x = 1; 73 x >>>= eval('1'); 74 return x == 0; 75 } 76 77 function andTest() 78 { 79 var x = 1; 80 x &= eval('1'); 81 return x == 1; 82 } 83 84 function xorTest() 85 { 86 var x = 0; 87 x ^= eval('1'); 88 return x == 1; 89 } 90 91 function orTest() 92 { 93 var x = 0; 94 x |= eval('1'); 95 return x == 1; 96 } 97 98 function modTest() 99 { 100 var x = 4; 101 x %= eval('3'); 102 return x == 1; 103 } 104 105 function preIncTest() 106 { 107 var x = { value: 0 }; 108 ++eval('x').value; 109 return x.value == 1; 110 } 111 112 function preDecTest() 113 { 114 var x = { value: 0 }; 115 --eval('x').value; 116 return x.value == -1; 117 } 118 119 function postIncTest() 120 { 121 var x = { value: 0 }; 122 eval('x').value++; 123 return x.value == 1; 124 } 125 126 function postDecTest() 127 { 128 var x = { value: 0 }; 129 eval('x').value--; 130 return x.value == -1; 131 } 132 133 function primitiveThisTest() 134 { 135 // Test that conversion of this is persistant over multiple calls to eval, 136 // even where 'this' is not directly used within the function. 137 eval('this.value = "Seekrit message";'); 138 return eval('this.value') === "Seekrit message"; 139 } 140 141 function strictThisTest() 142 { 143 // In a strict mode function primitive this values are not converted, so 144 // the property access in the first eval is writing a value to a temporary 145 // object. This throws, per section 8.7.2. 146 "use strict"; 147 eval('this.value = "Seekrit message";'); 148 return eval('this.value') === undefined; 149 } 150 151 shouldBeTrue('multTest();'); 152 shouldBeTrue('divTest();'); 153 shouldBeTrue('addTest();'); 154 shouldBeTrue('subTest();'); 155 shouldBeTrue('lshiftTest();'); 156 shouldBeTrue('rshiftTest();'); 157 shouldBeTrue('urshiftTest();'); 158 shouldBeTrue('andTest();'); 159 shouldBeTrue('xorTest();'); 160 shouldBeTrue('orTest();'); 161 shouldBeTrue('modTest();'); 162 163 shouldBeTrue('preIncTest();'); 164 shouldBeTrue('preDecTest();'); 165 shouldBeTrue('postIncTest();'); 166 shouldBeTrue('postDecTest();'); 167 168 shouldBeTrue('primitiveThisTest.call(1);'); 169 shouldThrow('strictThisTest.call(1);'); 170