Home | History | Annotate | Download | only in compiler
      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