1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/v8.h" 6 7 #include "test/cctest/compiler/function-tester.h" 8 9 using namespace v8::internal; 10 using namespace v8::internal::compiler; 11 12 TEST(Conditional) { 13 FunctionTester T("(function(a) { return a ? 23 : 42; })"); 14 15 T.CheckCall(T.Val(23), T.true_value(), T.undefined()); 16 T.CheckCall(T.Val(42), T.false_value(), T.undefined()); 17 T.CheckCall(T.Val(42), T.undefined(), T.undefined()); 18 T.CheckCall(T.Val(42), T.Val(0.0), T.undefined()); 19 T.CheckCall(T.Val(23), T.Val(999), T.undefined()); 20 T.CheckCall(T.Val(23), T.Val("x"), T.undefined()); 21 } 22 23 24 TEST(LogicalAnd) { 25 FunctionTester T("(function(a,b) { return a && b; })"); 26 27 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 28 T.CheckCall(T.false_value(), T.false_value(), T.true_value()); 29 T.CheckCall(T.false_value(), T.true_value(), T.false_value()); 30 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 31 32 T.CheckCall(T.Val(999), T.Val(777), T.Val(999)); 33 T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(999)); 34 T.CheckCall(T.Val("b"), T.Val("a"), T.Val("b")); 35 } 36 37 38 TEST(LogicalOr) { 39 FunctionTester T("(function(a,b) { return a || b; })"); 40 41 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 42 T.CheckCall(T.true_value(), T.false_value(), T.true_value()); 43 T.CheckCall(T.true_value(), T.true_value(), T.false_value()); 44 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 45 46 T.CheckCall(T.Val(777), T.Val(777), T.Val(999)); 47 T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999)); 48 T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b")); 49 } 50 51 52 TEST(LogicalEffect) { 53 FunctionTester T("(function(a,b) { a && (b = a); return b; })"); 54 55 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 56 T.CheckCall(T.true_value(), T.false_value(), T.true_value()); 57 T.CheckCall(T.true_value(), T.true_value(), T.false_value()); 58 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 59 60 T.CheckCall(T.Val(777), T.Val(777), T.Val(999)); 61 T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999)); 62 T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b")); 63 } 64 65 66 TEST(IfStatement) { 67 FunctionTester T("(function(a) { if (a) { return 1; } else { return 2; } })"); 68 69 T.CheckCall(T.Val(1), T.true_value(), T.undefined()); 70 T.CheckCall(T.Val(2), T.false_value(), T.undefined()); 71 T.CheckCall(T.Val(2), T.undefined(), T.undefined()); 72 T.CheckCall(T.Val(2), T.Val(0.0), T.undefined()); 73 T.CheckCall(T.Val(1), T.Val(999), T.undefined()); 74 T.CheckCall(T.Val(1), T.Val("x"), T.undefined()); 75 } 76 77 78 TEST(DoWhileStatement) { 79 FunctionTester T("(function(a,b) { do { a+=23; } while(a < b) return a; })"); 80 81 T.CheckCall(T.Val(24), T.Val(1), T.Val(1)); 82 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 83 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 84 T.CheckCall(T.Val("str23"), T.Val("str"), T.Val("str")); 85 } 86 87 88 TEST(WhileStatement) { 89 FunctionTester T("(function(a,b) { while(a < b) { a+=23; } return a; })"); 90 91 T.CheckCall(T.Val(1), T.Val(1), T.Val(1)); 92 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 93 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 94 T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str")); 95 } 96 97 98 TEST(ForStatement) { 99 FunctionTester T("(function(a,b) { for (; a < b; a+=23) {} return a; })"); 100 101 T.CheckCall(T.Val(1), T.Val(1), T.Val(1)); 102 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 103 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 104 T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str")); 105 } 106 107 108 static void TestForIn(const char* code) { 109 FunctionTester T(code); 110 T.CheckCall(T.undefined(), T.undefined()); 111 T.CheckCall(T.undefined(), T.null()); 112 T.CheckCall(T.undefined(), T.NewObject("({})")); 113 T.CheckCall(T.undefined(), T.Val(1)); 114 T.CheckCall(T.Val("2"), T.Val("str")); 115 T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1})")); 116 T.CheckCall(T.Val("2"), T.NewObject("([1, 2, 3])")); 117 T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1, 'b' : 1})"), T.Val("b")); 118 T.CheckCall(T.Val("1"), T.NewObject("([1, 2, 3])"), T.Val("2")); 119 } 120 121 122 TEST(ForInStatement) { 123 // Variable assignment. 124 TestForIn( 125 "(function(a, b) {" 126 "var last;" 127 "for (var x in a) {" 128 " if (b) { delete a[b]; b = undefined; }" 129 " last = x;" 130 "}" 131 "return last;})"); 132 // Indexed assignment. 133 TestForIn( 134 "(function(a, b) {" 135 "var array = [0, 1, undefined];" 136 "for (array[2] in a) {" 137 " if (b) { delete a[b]; b = undefined; }" 138 "}" 139 "return array[2];})"); 140 // Named assignment. 141 TestForIn( 142 "(function(a, b) {" 143 "var obj = {'a' : undefined};" 144 "for (obj.a in a) {" 145 " if (b) { delete a[b]; b = undefined; }" 146 "}" 147 "return obj.a;})"); 148 } 149 150 151 TEST(ForInContinueStatement) { 152 const char* src = 153 "(function(a,b) {" 154 " var r = '-';" 155 " for (var x in a) {" 156 " r += 'A-';" 157 " if (b) continue;" 158 " r += 'B-';" 159 " }" 160 " return r;" 161 "})"; 162 FunctionTester T(src); 163 164 T.CheckCall(T.Val("-A-B-"), T.NewObject("({x:1})"), T.false_value()); 165 T.CheckCall(T.Val("-A-B-A-B-"), T.NewObject("({x:1,y:2})"), T.false_value()); 166 T.CheckCall(T.Val("-A-"), T.NewObject("({x:1})"), T.true_value()); 167 T.CheckCall(T.Val("-A-A-"), T.NewObject("({x:1,y:2})"), T.true_value()); 168 } 169 170 171 TEST(SwitchStatement) { 172 const char* src = 173 "(function(a,b) {" 174 " var r = '-';" 175 " switch (a) {" 176 " case 'x' : r += 'X-';" 177 " case b + 'b': r += 'B-';" 178 " default : r += 'D-';" 179 " case 'y' : r += 'Y-';" 180 " }" 181 " return r;" 182 "})"; 183 FunctionTester T(src); 184 185 T.CheckCall(T.Val("-X-B-D-Y-"), T.Val("x"), T.Val("B")); 186 T.CheckCall(T.Val("-B-D-Y-"), T.Val("Bb"), T.Val("B")); 187 T.CheckCall(T.Val("-D-Y-"), T.Val("z"), T.Val("B")); 188 T.CheckCall(T.Val("-Y-"), T.Val("y"), T.Val("B")); 189 190 CompileRun("var c = 0; var o = { toString:function(){return c++} };"); 191 T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o")); 192 T.CheckCall(T.Val("-B-D-Y-"), T.Val("1b"), T.NewObject("o")); 193 T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o")); 194 } 195 196 197 TEST(BlockBreakStatement) { 198 FunctionTester T("(function(a,b) { L:{ if (a) break L; b=1; } return b; })"); 199 200 T.CheckCall(T.Val(7), T.true_value(), T.Val(7)); 201 T.CheckCall(T.Val(1), T.false_value(), T.Val(7)); 202 } 203 204 205 TEST(BlockReturnStatement) { 206 FunctionTester T("(function(a,b) { L:{ if (a) b=1; return b; } })"); 207 208 T.CheckCall(T.Val(1), T.true_value(), T.Val(7)); 209 T.CheckCall(T.Val(7), T.false_value(), T.Val(7)); 210 } 211 212 213 TEST(NestedIfConditional) { 214 FunctionTester T("(function(a,b) { if (a) { b = (b?b:7) + 1; } return b; })"); 215 216 T.CheckCall(T.Val(4), T.false_value(), T.Val(4)); 217 T.CheckCall(T.Val(6), T.true_value(), T.Val(5)); 218 T.CheckCall(T.Val(8), T.true_value(), T.undefined()); 219 } 220 221 222 TEST(NestedIfLogical) { 223 const char* src = 224 "(function(a,b) {" 225 " if (a || b) { return 1; } else { return 2; }" 226 "})"; 227 FunctionTester T(src); 228 229 T.CheckCall(T.Val(1), T.true_value(), T.true_value()); 230 T.CheckCall(T.Val(1), T.false_value(), T.true_value()); 231 T.CheckCall(T.Val(1), T.true_value(), T.false_value()); 232 T.CheckCall(T.Val(2), T.false_value(), T.false_value()); 233 T.CheckCall(T.Val(1), T.Val(1.0), T.Val(1.0)); 234 T.CheckCall(T.Val(1), T.Val(0.0), T.Val(1.0)); 235 T.CheckCall(T.Val(1), T.Val(1.0), T.Val(0.0)); 236 T.CheckCall(T.Val(2), T.Val(0.0), T.Val(0.0)); 237 } 238 239 240 TEST(NestedIfElseFor) { 241 const char* src = 242 "(function(a,b) {" 243 " if (!a) { return b - 3; } else { for (; a < b; a++); }" 244 " return a;" 245 "})"; 246 FunctionTester T(src); 247 248 T.CheckCall(T.Val(1), T.false_value(), T.Val(4)); 249 T.CheckCall(T.Val(2), T.true_value(), T.Val(2)); 250 T.CheckCall(T.Val(3), T.Val(3), T.Val(1)); 251 } 252 253 254 TEST(NestedWhileWhile) { 255 const char* src = 256 "(function(a) {" 257 " var i = a; while (false) while(false) return i;" 258 " return i;" 259 "})"; 260 FunctionTester T(src); 261 262 T.CheckCall(T.Val(2.0), T.Val(2.0), T.Val(-1.0)); 263 T.CheckCall(T.Val(65.0), T.Val(65.0), T.Val(-1.0)); 264 } 265 266 267 TEST(NestedForIf) { 268 FunctionTester T("(function(a,b) { for (; a > 1; a--) if (b) return 1; })"); 269 270 T.CheckCall(T.Val(1), T.Val(3), T.true_value()); 271 T.CheckCall(T.undefined(), T.Val(2), T.false_value()); 272 T.CheckCall(T.undefined(), T.Val(1), T.null()); 273 } 274 275 276 TEST(NestedForConditional) { 277 FunctionTester T("(function(a,b) { for (; a > 1; a--) return b ? 1 : 2; })"); 278 279 T.CheckCall(T.Val(1), T.Val(3), T.true_value()); 280 T.CheckCall(T.Val(2), T.Val(2), T.false_value()); 281 T.CheckCall(T.undefined(), T.Val(1), T.null()); 282 } 283