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 "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