Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 5 | #include "test/cctest/compiler/function-tester.h" |
| 6 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 7 | namespace v8 { |
| 8 | namespace internal { |
| 9 | namespace compiler { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | } |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 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 | } |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 384 | |
| 385 | } // namespace compiler |
| 386 | } // namespace internal |
| 387 | } // namespace v8 |