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 "test/cctest/compiler/function-tester.h" 6 7 namespace v8 { 8 namespace internal { 9 namespace compiler { 10 11 TEST(Conditional) { 12 FunctionTester T("(function(a) { return a ? 23 : 42; })"); 13 14 T.CheckCall(T.Val(23), T.true_value(), T.undefined()); 15 T.CheckCall(T.Val(42), T.false_value(), T.undefined()); 16 T.CheckCall(T.Val(42), T.undefined(), T.undefined()); 17 T.CheckCall(T.Val(42), T.Val(0.0), T.undefined()); 18 T.CheckCall(T.Val(23), T.Val(999), T.undefined()); 19 T.CheckCall(T.Val(23), T.Val("x"), T.undefined()); 20 } 21 22 23 TEST(LogicalAnd) { 24 FunctionTester T("(function(a,b) { return a && b; })"); 25 26 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 27 T.CheckCall(T.false_value(), T.false_value(), T.true_value()); 28 T.CheckCall(T.false_value(), T.true_value(), T.false_value()); 29 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 30 31 T.CheckCall(T.Val(999), T.Val(777), T.Val(999)); 32 T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(999)); 33 T.CheckCall(T.Val("b"), T.Val("a"), T.Val("b")); 34 } 35 36 37 TEST(LogicalOr) { 38 FunctionTester T("(function(a,b) { return a || b; })"); 39 40 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 41 T.CheckCall(T.true_value(), T.false_value(), T.true_value()); 42 T.CheckCall(T.true_value(), T.true_value(), T.false_value()); 43 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 44 45 T.CheckCall(T.Val(777), T.Val(777), T.Val(999)); 46 T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999)); 47 T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b")); 48 } 49 50 51 TEST(LogicalEffect) { 52 FunctionTester T("(function(a,b) { a && (b = a); return b; })"); 53 54 T.CheckCall(T.true_value(), T.true_value(), T.true_value()); 55 T.CheckCall(T.true_value(), T.false_value(), T.true_value()); 56 T.CheckCall(T.true_value(), T.true_value(), T.false_value()); 57 T.CheckCall(T.false_value(), T.false_value(), T.false_value()); 58 59 T.CheckCall(T.Val(777), T.Val(777), T.Val(999)); 60 T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999)); 61 T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b")); 62 } 63 64 65 TEST(IfStatement) { 66 FunctionTester T("(function(a) { if (a) { return 1; } else { return 2; } })"); 67 68 T.CheckCall(T.Val(1), T.true_value(), T.undefined()); 69 T.CheckCall(T.Val(2), T.false_value(), T.undefined()); 70 T.CheckCall(T.Val(2), T.undefined(), T.undefined()); 71 T.CheckCall(T.Val(2), T.Val(0.0), T.undefined()); 72 T.CheckCall(T.Val(1), T.Val(999), T.undefined()); 73 T.CheckCall(T.Val(1), T.Val("x"), T.undefined()); 74 } 75 76 77 TEST(DoWhileStatement) { 78 FunctionTester T("(function(a,b) { do { a+=23; } while(a < b) return a; })"); 79 80 T.CheckCall(T.Val(24), T.Val(1), T.Val(1)); 81 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 82 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 83 T.CheckCall(T.Val("str23"), T.Val("str"), T.Val("str")); 84 } 85 86 87 TEST(WhileStatement) { 88 FunctionTester T("(function(a,b) { while(a < b) { a+=23; } return a; })"); 89 90 T.CheckCall(T.Val(1), T.Val(1), T.Val(1)); 91 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 92 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 93 T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str")); 94 } 95 96 97 TEST(ForStatement) { 98 FunctionTester T("(function(a,b) { for (; a < b; a+=23) {} return a; })"); 99 100 T.CheckCall(T.Val(1), T.Val(1), T.Val(1)); 101 T.CheckCall(T.Val(24), T.Val(1), T.Val(23)); 102 T.CheckCall(T.Val(47), T.Val(1), T.Val(25)); 103 T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str")); 104 } 105 106 107 static void TestForIn(const char* code) { 108 FunctionTester T(code); 109 T.CheckCall(T.undefined(), T.undefined()); 110 T.CheckCall(T.undefined(), T.null()); 111 T.CheckCall(T.undefined(), T.NewObject("({})")); 112 T.CheckCall(T.undefined(), T.Val(1)); 113 T.CheckCall(T.Val("2"), T.Val("str")); 114 T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1})")); 115 T.CheckCall(T.Val("2"), T.NewObject("([1, 2, 3])")); 116 T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1, 'b' : 1})"), T.Val("b")); 117 T.CheckCall(T.Val("1"), T.NewObject("([1, 2, 3])"), T.Val("2")); 118 } 119 120 121 TEST(ForInStatement) { 122 // Variable assignment. 123 TestForIn( 124 "(function(a, b) {" 125 "var last;" 126 "for (var x in a) {" 127 " if (b) { delete a[b]; b = undefined; }" 128 " last = x;" 129 "}" 130 "return last;})"); 131 // Indexed assignment. 132 TestForIn( 133 "(function(a, b) {" 134 "var array = [0, 1, undefined];" 135 "for (array[2] in a) {" 136 " if (b) { delete a[b]; b = undefined; }" 137 "}" 138 "return array[2];})"); 139 // Named assignment. 140 TestForIn( 141 "(function(a, b) {" 142 "var obj = {'a' : undefined};" 143 "for (obj.a in a) {" 144 " if (b) { delete a[b]; b = undefined; }" 145 "}" 146 "return obj.a;})"); 147 } 148 149 150 TEST(ForInContinueStatement) { 151 const char* src = 152 "(function(a,b) {" 153 " var r = '-';" 154 " for (var x in a) {" 155 " r += 'A-';" 156 " if (b) continue;" 157 " r += 'B-';" 158 " }" 159 " return r;" 160 "})"; 161 FunctionTester T(src); 162 163 T.CheckCall(T.Val("-A-B-"), T.NewObject("({x:1})"), T.false_value()); 164 T.CheckCall(T.Val("-A-B-A-B-"), T.NewObject("({x:1,y:2})"), T.false_value()); 165 T.CheckCall(T.Val("-A-"), T.NewObject("({x:1})"), T.true_value()); 166 T.CheckCall(T.Val("-A-A-"), T.NewObject("({x:1,y:2})"), T.true_value()); 167 } 168 169 170 TEST(ForOfContinueStatement) { 171 const char* src = 172 "(function(a,b) {" 173 " var r = '-';" 174 " for (var x of a) {" 175 " r += x + '-';" 176 " if (b) continue;" 177 " r += 'X-';" 178 " }" 179 " return r;" 180 "})"; 181 FunctionTester T(src); 182 183 CompileRun( 184 "function wrap(v) {" 185 " var iterable = {};" 186 " function next() { return { done:!v.length, value:v.shift() }; };" 187 " iterable[Symbol.iterator] = function() { return { next:next }; };" 188 " return iterable;" 189 "}"); 190 191 T.CheckCall(T.Val("-"), T.NewObject("wrap([])"), T.true_value()); 192 T.CheckCall(T.Val("-1-2-"), T.NewObject("wrap([1,2])"), T.true_value()); 193 T.CheckCall(T.Val("-1-X-2-X-"), T.NewObject("wrap([1,2])"), T.false_value()); 194 } 195 196 197 TEST(SwitchStatement) { 198 const char* src = 199 "(function(a,b) {" 200 " var r = '-';" 201 " switch (a) {" 202 " case 'x' : r += 'X-';" 203 " case b + 'b': r += 'B-';" 204 " default : r += 'D-';" 205 " case 'y' : r += 'Y-';" 206 " }" 207 " return r;" 208 "})"; 209 FunctionTester T(src); 210 211 T.CheckCall(T.Val("-X-B-D-Y-"), T.Val("x"), T.Val("B")); 212 T.CheckCall(T.Val("-B-D-Y-"), T.Val("Bb"), T.Val("B")); 213 T.CheckCall(T.Val("-D-Y-"), T.Val("z"), T.Val("B")); 214 T.CheckCall(T.Val("-Y-"), T.Val("y"), T.Val("B")); 215 216 CompileRun("var c = 0; var o = { toString:function(){return c++} };"); 217 T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o")); 218 T.CheckCall(T.Val("-B-D-Y-"), T.Val("1b"), T.NewObject("o")); 219 T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o")); 220 } 221 222 223 TEST(BlockBreakStatement) { 224 FunctionTester T("(function(a,b) { L:{ if (a) break L; b=1; } return b; })"); 225 226 T.CheckCall(T.Val(7), T.true_value(), T.Val(7)); 227 T.CheckCall(T.Val(1), T.false_value(), T.Val(7)); 228 } 229 230 231 TEST(BlockReturnStatement) { 232 FunctionTester T("(function(a,b) { L:{ if (a) b=1; return b; } })"); 233 234 T.CheckCall(T.Val(1), T.true_value(), T.Val(7)); 235 T.CheckCall(T.Val(7), T.false_value(), T.Val(7)); 236 } 237 238 239 TEST(NestedIfConditional) { 240 FunctionTester T("(function(a,b) { if (a) { b = (b?b:7) + 1; } return b; })"); 241 242 T.CheckCall(T.Val(4), T.false_value(), T.Val(4)); 243 T.CheckCall(T.Val(6), T.true_value(), T.Val(5)); 244 T.CheckCall(T.Val(8), T.true_value(), T.undefined()); 245 } 246 247 248 TEST(NestedIfLogical) { 249 const char* src = 250 "(function(a,b) {" 251 " if (a || b) { return 1; } else { return 2; }" 252 "})"; 253 FunctionTester T(src); 254 255 T.CheckCall(T.Val(1), T.true_value(), T.true_value()); 256 T.CheckCall(T.Val(1), T.false_value(), T.true_value()); 257 T.CheckCall(T.Val(1), T.true_value(), T.false_value()); 258 T.CheckCall(T.Val(2), T.false_value(), T.false_value()); 259 T.CheckCall(T.Val(1), T.Val(1.0), T.Val(1.0)); 260 T.CheckCall(T.Val(1), T.Val(0.0), T.Val(1.0)); 261 T.CheckCall(T.Val(1), T.Val(1.0), T.Val(0.0)); 262 T.CheckCall(T.Val(2), T.Val(0.0), T.Val(0.0)); 263 } 264 265 266 TEST(NestedIfElseFor) { 267 const char* src = 268 "(function(a,b) {" 269 " if (!a) { return b - 3; } else { for (; a < b; a++); }" 270 " return a;" 271 "})"; 272 FunctionTester T(src); 273 274 T.CheckCall(T.Val(1), T.false_value(), T.Val(4)); 275 T.CheckCall(T.Val(2), T.true_value(), T.Val(2)); 276 T.CheckCall(T.Val(3), T.Val(3), T.Val(1)); 277 } 278 279 280 TEST(NestedWhileWhile) { 281 const char* src = 282 "(function(a) {" 283 " var i = a; while (false) while(false) return i;" 284 " return i;" 285 "})"; 286 FunctionTester T(src); 287 288 T.CheckCall(T.Val(2.0), T.Val(2.0), T.Val(-1.0)); 289 T.CheckCall(T.Val(65.0), T.Val(65.0), T.Val(-1.0)); 290 } 291 292 293 TEST(NestedForIf) { 294 FunctionTester T("(function(a,b) { for (; a > 1; a--) if (b) return 1; })"); 295 296 T.CheckCall(T.Val(1), T.Val(3), T.true_value()); 297 T.CheckCall(T.undefined(), T.Val(2), T.false_value()); 298 T.CheckCall(T.undefined(), T.Val(1), T.null()); 299 } 300 301 302 TEST(NestedForConditional) { 303 FunctionTester T("(function(a,b) { for (; a > 1; a--) return b ? 1 : 2; })"); 304 305 T.CheckCall(T.Val(1), T.Val(3), T.true_value()); 306 T.CheckCall(T.Val(2), T.Val(2), T.false_value()); 307 T.CheckCall(T.undefined(), T.Val(1), T.null()); 308 } 309 310 311 TEST(IfTrue) { 312 FunctionTester T("(function(a,b) { if (true) return a; return b; })"); 313 314 T.CheckCall(T.Val(55), T.Val(55), T.Val(11)); 315 T.CheckCall(T.Val(666), T.Val(666), T.Val(-444)); 316 } 317 318 319 TEST(TernaryTrue) { 320 FunctionTester T("(function(a,b) { return true ? a : b; })"); 321 322 T.CheckCall(T.Val(77), T.Val(77), T.Val(11)); 323 T.CheckCall(T.Val(111), T.Val(111), T.Val(-444)); 324 } 325 326 327 TEST(IfFalse) { 328 FunctionTester T("(function(a,b) { if (false) return a; return b; })"); 329 330 T.CheckCall(T.Val(11), T.Val(22), T.Val(11)); 331 T.CheckCall(T.Val(-555), T.Val(333), T.Val(-555)); 332 } 333 334 335 TEST(TernaryFalse) { 336 FunctionTester T("(function(a,b) { return false ? a : b; })"); 337 338 T.CheckCall(T.Val(99), T.Val(33), T.Val(99)); 339 T.CheckCall(T.Val(-99), T.Val(-33), T.Val(-99)); 340 } 341 342 343 TEST(WhileTrue) { 344 FunctionTester T("(function(a,b) { while (true) return a; return b; })"); 345 346 T.CheckCall(T.Val(551), T.Val(551), T.Val(111)); 347 T.CheckCall(T.Val(661), T.Val(661), T.Val(-444)); 348 } 349 350 351 TEST(WhileFalse) { 352 FunctionTester T("(function(a,b) { while (false) return a; return b; })"); 353 354 T.CheckCall(T.Val(115), T.Val(551), T.Val(115)); 355 T.CheckCall(T.Val(-445), T.Val(661), T.Val(-445)); 356 } 357 358 359 TEST(DoWhileTrue) { 360 FunctionTester T( 361 "(function(a,b) { do { return a; } while (true); return b; })"); 362 363 T.CheckCall(T.Val(7551), T.Val(7551), T.Val(7111)); 364 T.CheckCall(T.Val(7661), T.Val(7661), T.Val(-7444)); 365 } 366 367 368 TEST(DoWhileFalse) { 369 FunctionTester T( 370 "(function(a,b) { do { " 371 "; } while (false); return b; })"); 372 373 T.CheckCall(T.Val(8115), T.Val(8551), T.Val(8115)); 374 T.CheckCall(T.Val(-8445), T.Val(8661), T.Val(-8445)); 375 } 376 377 378 TEST(EmptyFor) { 379 FunctionTester T("(function(a,b) { if (a) for(;;) ; return b; })"); 380 381 T.CheckCall(T.Val(8126.1), T.Val(0.0), T.Val(8126.1)); 382 T.CheckCall(T.Val(1123.1), T.Val(0.0), T.Val(1123.1)); 383 } 384 385 } // namespace compiler 386 } // namespace internal 387 } // namespace v8 388