Home | History | Annotate | Download | only in cctest
      1 // Copyright 2015 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 "src/ast/ast.h"
      8 #include "src/ast/ast-expression-visitor.h"
      9 #include "src/ast/scopes.h"
     10 #include "src/parsing/parser.h"
     11 #include "src/parsing/rewriter.h"
     12 #include "src/type-cache.h"
     13 #include "src/typing-asm.h"
     14 #include "test/cctest/cctest.h"
     15 #include "test/cctest/expression-type-collector.h"
     16 #include "test/cctest/expression-type-collector-macros.h"
     17 
     18 // Macros for function types.
     19 #define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(zone), zone))
     20 #define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone))
     21 #define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone))
     22 #define FUNC_D_TYPE Bounds(Type::Function(cache.kAsmDouble, zone))
     23 #define FUNC_D2D_TYPE \
     24   Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, zone))
     25 #define FUNC_N2F_TYPE \
     26   Bounds(Type::Function(cache.kAsmFloat, Type::Number(zone), zone))
     27 #define FUNC_I2I_TYPE \
     28   Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone))
     29 #define FUNC_II2D_TYPE \
     30   Bounds(Type::Function(cache.kAsmDouble, cache.kAsmInt, cache.kAsmInt, zone))
     31 #define FUNC_II2I_TYPE \
     32   Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, cache.kAsmInt, zone))
     33 #define FUNC_DD2D_TYPE                                                        \
     34   Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, cache.kAsmDouble, \
     35                         zone))
     36 #define FUNC_NN2N_TYPE                                          \
     37   Bounds(Type::Function(Type::Number(zone), Type::Number(zone), \
     38                         Type::Number(zone), zone))
     39 #define FUNC_N2N_TYPE \
     40   Bounds(Type::Function(Type::Number(zone), Type::Number(zone), zone))
     41 
     42 // Macros for array types.
     43 #define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kAsmDouble, zone))
     44 #define FUNC_I2I_ARRAY_TYPE                                                 \
     45   Bounds(Type::Array(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone), \
     46                      zone))
     47 
     48 using namespace v8::internal;
     49 
     50 namespace {
     51 
     52 std::string Validate(Zone* zone, const char* source,
     53                      ZoneVector<ExpressionTypeEntry>* types) {
     54   i::Isolate* isolate = CcTest::i_isolate();
     55   i::Factory* factory = isolate->factory();
     56 
     57   i::Handle<i::String> source_code =
     58       factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
     59 
     60   i::Handle<i::Script> script = factory->NewScript(source_code);
     61 
     62   i::ParseInfo info(zone, script);
     63   i::Parser parser(&info);
     64   parser.set_allow_harmony_sloppy(true);
     65   info.set_global();
     66   info.set_lazy(false);
     67   info.set_allow_lazy_parsing(false);
     68   info.set_toplevel(true);
     69 
     70   CHECK(i::Compiler::ParseAndAnalyze(&info));
     71 
     72   FunctionLiteral* root =
     73       info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
     74   AsmTyper typer(isolate, zone, *script, root);
     75   if (typer.Validate()) {
     76     ExpressionTypeCollector(isolate, root, types).Run();
     77     return "";
     78   } else {
     79     return typer.error_message();
     80   }
     81 }
     82 
     83 }  // namespace
     84 
     85 
     86 TEST(ValidateMinimum) {
     87   const char test_function[] =
     88       "function GeometricMean(stdlib, foreign, buffer) {\n"
     89       "  \"use asm\";\n"
     90       "\n"
     91       "  var exp = stdlib.Math.exp;\n"
     92       "  var log = stdlib.Math.log;\n"
     93       "  var values = new stdlib.Float64Array(buffer);\n"
     94       "\n"
     95       "  function logSum(start, end) {\n"
     96       "    start = start|0;\n"
     97       "    end = end|0;\n"
     98       "\n"
     99       "    var sum = 0.0, p = 0, q = 0;\n"
    100       "\n"
    101       "    // asm.js forces byte addressing of the heap by requiring shifting "
    102       "by 3\n"
    103       "    for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {\n"
    104       "      sum = sum + +log(values[p>>3]);\n"
    105       "    }\n"
    106       "\n"
    107       "    return +sum;\n"
    108       "  }\n"
    109       "\n"
    110       " function geometricMean(start, end) {\n"
    111       "    start = start|0;\n"
    112       "    end = end|0;\n"
    113       "\n"
    114       "    return +exp(+logSum(start, end) / +((end - start)|0));\n"
    115       "  }\n"
    116       "\n"
    117       "  return { geometricMean: geometricMean };\n"
    118       "}\n";
    119 
    120   v8::V8::Initialize();
    121   HandleAndZoneScope handles;
    122   Zone* zone = handles.main_zone();
    123   ZoneVector<ExpressionTypeEntry> types(zone);
    124   CHECK_EQ("", Validate(zone, test_function, &types));
    125   TypeCache cache;
    126 
    127   CHECK_TYPES_BEGIN {
    128     // Module.
    129     CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
    130       // function logSum
    131       CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
    132         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    133           CHECK_VAR(start, Bounds(cache.kAsmInt));
    134           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    135             CHECK_VAR(start, Bounds(cache.kAsmInt));
    136             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    137           }
    138         }
    139         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    140           CHECK_VAR(end, Bounds(cache.kAsmInt));
    141           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    142             CHECK_VAR(end, Bounds(cache.kAsmInt));
    143             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    144           }
    145         }
    146         CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
    147           CHECK_VAR(sum, Bounds(cache.kAsmDouble));
    148           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    149         }
    150         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    151           CHECK_VAR(p, Bounds(cache.kAsmInt));
    152           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    153         }
    154         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    155           CHECK_VAR(q, Bounds(cache.kAsmInt));
    156           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    157         }
    158         // for (p = start << 3, q = end << 3;
    159         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
    160           CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    161             CHECK_VAR(p, Bounds(cache.kAsmInt));
    162             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    163               CHECK_VAR(start, Bounds(cache.kAsmInt));
    164               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    165             }
    166           }
    167           CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    168             CHECK_VAR(q, Bounds(cache.kAsmInt));
    169             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    170               CHECK_VAR(end, Bounds(cache.kAsmInt));
    171               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    172             }
    173           }
    174         }
    175         // (p|0) < (q|0);
    176         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
    177           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    178             CHECK_VAR(p, Bounds(cache.kAsmInt));
    179             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    180           }
    181           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    182             CHECK_VAR(q, Bounds(cache.kAsmInt));
    183             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    184           }
    185         }
    186         // p = (p + 8)|0) {\n"
    187         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    188           CHECK_VAR(p, Bounds(cache.kAsmInt));
    189           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    190             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
    191               CHECK_VAR(p, Bounds(cache.kAsmInt));
    192               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    193             }
    194             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    195           }
    196         }
    197         // sum = sum + +log(values[p>>3]);
    198         CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
    199           CHECK_VAR(sum, Bounds(cache.kAsmDouble));
    200           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    201             CHECK_VAR(sum, Bounds(cache.kAsmDouble));
    202             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    203               CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
    204                 CHECK_VAR(log, FUNC_D2D_TYPE);
    205                 CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
    206                   CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
    207                   CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    208                     CHECK_VAR(p, Bounds(cache.kAsmSigned));
    209                     CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    210                   }
    211                 }
    212               }
    213               CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    214             }
    215           }
    216         }
    217         // return +sum;
    218         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    219           CHECK_VAR(sum, Bounds(cache.kAsmDouble));
    220           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    221         }
    222       }
    223       // function geometricMean
    224       CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
    225         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    226           CHECK_VAR(start, Bounds(cache.kAsmInt));
    227           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    228             CHECK_VAR(start, Bounds(cache.kAsmInt));
    229             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    230           }
    231         }
    232         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    233           CHECK_VAR(end, Bounds(cache.kAsmInt));
    234           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    235             CHECK_VAR(end, Bounds(cache.kAsmInt));
    236             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    237           }
    238         }
    239         // return +exp(+logSum(start, end) / +((end - start)|0));
    240         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    241           CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
    242             CHECK_VAR(exp, FUNC_D2D_TYPE);
    243             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    244               CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    245                 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
    246                   CHECK_VAR(logSum, FUNC_II2D_TYPE);
    247                   CHECK_VAR(start, Bounds(cache.kAsmInt));
    248                   CHECK_VAR(end, Bounds(cache.kAsmInt));
    249                 }
    250                 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    251               }
    252               CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    253                 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    254                   CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
    255                     CHECK_VAR(end, Bounds(cache.kAsmInt));
    256                     CHECK_VAR(start, Bounds(cache.kAsmInt));
    257                   }
    258                   CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    259                 }
    260                 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    261               }
    262             }
    263           }
    264           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    265         }
    266       }
    267       // "use asm";
    268       CHECK_EXPR(Literal, Bounds(Type::String(zone)));
    269       // var exp = stdlib.Math.exp;
    270       CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
    271         CHECK_VAR(exp, FUNC_D2D_TYPE);
    272         CHECK_EXPR(Property, FUNC_D2D_TYPE) {
    273           CHECK_EXPR(Property, Bounds::Unbounded()) {
    274             CHECK_VAR(stdlib, Bounds::Unbounded());
    275             CHECK_EXPR(Literal, Bounds::Unbounded());
    276           }
    277           CHECK_EXPR(Literal, Bounds::Unbounded());
    278         }
    279       }
    280       // var log = stdlib.Math.log;
    281       CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
    282         CHECK_VAR(log, FUNC_D2D_TYPE);
    283         CHECK_EXPR(Property, FUNC_D2D_TYPE) {
    284           CHECK_EXPR(Property, Bounds::Unbounded()) {
    285             CHECK_VAR(stdlib, Bounds::Unbounded());
    286             CHECK_EXPR(Literal, Bounds::Unbounded());
    287           }
    288           CHECK_EXPR(Literal, Bounds::Unbounded());
    289         }
    290       }
    291       // var values = new stdlib.Float64Array(buffer);
    292       CHECK_EXPR(Assignment, FLOAT64_ARRAY_TYPE) {
    293         CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
    294         CHECK_EXPR(CallNew, FLOAT64_ARRAY_TYPE) {
    295           CHECK_EXPR(Property, Bounds::Unbounded()) {
    296             CHECK_VAR(stdlib, Bounds::Unbounded());
    297             CHECK_EXPR(Literal, Bounds::Unbounded());
    298           }
    299           CHECK_VAR(buffer, Bounds::Unbounded());
    300         }
    301       }
    302       // return { geometricMean: geometricMean };
    303       CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
    304         CHECK_VAR(geometricMean, FUNC_II2D_TYPE);
    305       }
    306     }
    307   }
    308   CHECK_TYPES_END
    309 }
    310 
    311 
    312 TEST(MissingUseAsm) {
    313   const char test_function[] =
    314       "function foo() {\n"
    315       "  function bar() {}\n"
    316       "  return { bar: bar };\n"
    317       "}\n";
    318   v8::V8::Initialize();
    319   HandleAndZoneScope handles;
    320   Zone* zone = handles.main_zone();
    321   ZoneVector<ExpressionTypeEntry> types(zone);
    322   CHECK_EQ("asm: line 1: missing \"use asm\"\n",
    323            Validate(zone, test_function, &types));
    324 }
    325 
    326 
    327 TEST(WrongUseAsm) {
    328   const char test_function[] =
    329       "function foo() {\n"
    330       "  \"use wasm\"\n"
    331       "  function bar() {}\n"
    332       "  return { bar: bar };\n"
    333       "}\n";
    334   v8::V8::Initialize();
    335   HandleAndZoneScope handles;
    336   Zone* zone = handles.main_zone();
    337   ZoneVector<ExpressionTypeEntry> types(zone);
    338   CHECK_EQ("asm: line 1: missing \"use asm\"\n",
    339            Validate(zone, test_function, &types));
    340 }
    341 
    342 
    343 TEST(MissingReturnExports) {
    344   const char test_function[] =
    345       "function foo() {\n"
    346       "  \"use asm\"\n"
    347       "  function bar() {}\n"
    348       "}\n";
    349   v8::V8::Initialize();
    350   HandleAndZoneScope handles;
    351   Zone* zone = handles.main_zone();
    352   ZoneVector<ExpressionTypeEntry> types(zone);
    353   CHECK_EQ("asm: line 2: last statement in module is not a return\n",
    354            Validate(zone, test_function, &types));
    355 }
    356 
    357 
    358 #define HARNESS_STDLIB()                 \
    359   "var Infinity = stdlib.Infinity;\n"    \
    360   "var NaN = stdlib.NaN;\n"              \
    361   "var acos = stdlib.Math.acos;\n"       \
    362   "var asin = stdlib.Math.asin;\n"       \
    363   "var atan = stdlib.Math.atan;\n"       \
    364   "var cos = stdlib.Math.cos;\n"         \
    365   "var sin = stdlib.Math.sin;\n"         \
    366   "var tan = stdlib.Math.tan;\n"         \
    367   "var exp = stdlib.Math.exp;\n"         \
    368   "var log = stdlib.Math.log;\n"         \
    369   "var ceil = stdlib.Math.ceil;\n"       \
    370   "var floor = stdlib.Math.floor;\n"     \
    371   "var sqrt = stdlib.Math.sqrt;\n"       \
    372   "var min = stdlib.Math.min;\n"         \
    373   "var max = stdlib.Math.max;\n"         \
    374   "var atan2 = stdlib.Math.atan2;\n"     \
    375   "var pow = stdlib.Math.pow;\n"         \
    376   "var abs = stdlib.Math.abs;\n"         \
    377   "var imul = stdlib.Math.imul;\n"       \
    378   "var fround = stdlib.Math.fround;\n"   \
    379   "var E = stdlib.Math.E;\n"             \
    380   "var LN10 = stdlib.Math.LN10;\n"       \
    381   "var LN2 = stdlib.Math.LN2;\n"         \
    382   "var LOG2E = stdlib.Math.LOG2E;\n"     \
    383   "var LOG10E = stdlib.Math.LOG10E;\n"   \
    384   "var PI = stdlib.Math.PI;\n"           \
    385   "var SQRT1_2 = stdlib.Math.SQRT1_2;\n" \
    386   "var SQRT2 = stdlib.Math.SQRT2;\n"
    387 
    388 
    389 #define HARNESS_HEAP()                           \
    390   "var u8 = new stdlib.Uint8Array(buffer);\n"    \
    391   "var i8 = new stdlib.Int8Array(buffer);\n"     \
    392   "var u16 = new stdlib.Uint16Array(buffer);\n"  \
    393   "var i16 = new stdlib.Int16Array(buffer);\n"   \
    394   "var u32 = new stdlib.Uint32Array(buffer);\n"  \
    395   "var i32 = new stdlib.Int32Array(buffer);\n"   \
    396   "var f32 = new stdlib.Float32Array(buffer);\n" \
    397   "var f64 = new stdlib.Float64Array(buffer);\n"
    398 
    399 
    400 #define HARNESS_PREAMBLE()                           \
    401   const char test_function[] =                       \
    402       "function Module(stdlib, foreign, buffer) {\n" \
    403       "\"use asm\";\n" HARNESS_STDLIB() HARNESS_HEAP()
    404 
    405 
    406 #define HARNESS_POSTAMBLE() \
    407   "return { foo: foo };\n"  \
    408   "}\n";
    409 
    410 
    411 #define CHECK_VAR_MATH_SHORTCUT(name, type)       \
    412   CHECK_EXPR(Assignment, type) {                  \
    413     CHECK_VAR(name, type);                        \
    414     CHECK_EXPR(Property, type) {                  \
    415       CHECK_EXPR(Property, Bounds::Unbounded()) { \
    416         CHECK_VAR(stdlib, Bounds::Unbounded());   \
    417         CHECK_EXPR(Literal, Bounds::Unbounded()); \
    418       }                                           \
    419       CHECK_EXPR(Literal, Bounds::Unbounded());   \
    420     }                                             \
    421   }
    422 
    423 
    424 #define CHECK_VAR_SHORTCUT(name, type)          \
    425   CHECK_EXPR(Assignment, type) {                \
    426     CHECK_VAR(name, type);                      \
    427     CHECK_EXPR(Property, type) {                \
    428       CHECK_VAR(stdlib, Bounds::Unbounded());   \
    429       CHECK_EXPR(Literal, Bounds::Unbounded()); \
    430     }                                           \
    431   }
    432 
    433 
    434 #define CHECK_VAR_NEW_SHORTCUT(name, type)        \
    435   CHECK_EXPR(Assignment, type) {                  \
    436     CHECK_VAR(name, type);                        \
    437     CHECK_EXPR(CallNew, type) {                   \
    438       CHECK_EXPR(Property, Bounds::Unbounded()) { \
    439         CHECK_VAR(stdlib, Bounds::Unbounded());   \
    440         CHECK_EXPR(Literal, Bounds::Unbounded()); \
    441       }                                           \
    442       CHECK_VAR(buffer, Bounds::Unbounded());     \
    443     }                                             \
    444   }
    445 
    446 
    447 namespace {
    448 
    449 void CheckStdlibShortcuts1(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
    450                            size_t& index, int& depth, TypeCache& cache) {
    451   // var exp = stdlib.*;
    452   CHECK_VAR_SHORTCUT(Infinity, Bounds(cache.kAsmDouble));
    453   CHECK_VAR_SHORTCUT(NaN, Bounds(cache.kAsmDouble));
    454   // var x = stdlib.Math.x;
    455   CHECK_VAR_MATH_SHORTCUT(acos, FUNC_D2D_TYPE);
    456   CHECK_VAR_MATH_SHORTCUT(asin, FUNC_D2D_TYPE);
    457   CHECK_VAR_MATH_SHORTCUT(atan, FUNC_D2D_TYPE);
    458   CHECK_VAR_MATH_SHORTCUT(cos, FUNC_D2D_TYPE);
    459   CHECK_VAR_MATH_SHORTCUT(sin, FUNC_D2D_TYPE);
    460   CHECK_VAR_MATH_SHORTCUT(tan, FUNC_D2D_TYPE);
    461   CHECK_VAR_MATH_SHORTCUT(exp, FUNC_D2D_TYPE);
    462   CHECK_VAR_MATH_SHORTCUT(log, FUNC_D2D_TYPE);
    463 
    464   CHECK_VAR_MATH_SHORTCUT(ceil, FUNC_N2N_TYPE);
    465   CHECK_VAR_MATH_SHORTCUT(floor, FUNC_N2N_TYPE);
    466   CHECK_VAR_MATH_SHORTCUT(sqrt, FUNC_N2N_TYPE);
    467 
    468   CHECK_VAR_MATH_SHORTCUT(min, FUNC_NN2N_TYPE);
    469   CHECK_VAR_MATH_SHORTCUT(max, FUNC_NN2N_TYPE);
    470 
    471   CHECK_VAR_MATH_SHORTCUT(atan2, FUNC_DD2D_TYPE);
    472   CHECK_VAR_MATH_SHORTCUT(pow, FUNC_DD2D_TYPE);
    473 
    474   CHECK_VAR_MATH_SHORTCUT(abs, FUNC_N2N_TYPE);
    475   CHECK_VAR_MATH_SHORTCUT(imul, FUNC_II2I_TYPE);
    476   CHECK_VAR_MATH_SHORTCUT(fround, FUNC_N2F_TYPE);
    477 }
    478 
    479 
    480 void CheckStdlibShortcuts2(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
    481                            size_t& index, int& depth, TypeCache& cache) {
    482   // var exp = stdlib.Math.*; (D * 12)
    483   CHECK_VAR_MATH_SHORTCUT(E, Bounds(cache.kAsmDouble));
    484   CHECK_VAR_MATH_SHORTCUT(LN10, Bounds(cache.kAsmDouble));
    485   CHECK_VAR_MATH_SHORTCUT(LN2, Bounds(cache.kAsmDouble));
    486   CHECK_VAR_MATH_SHORTCUT(LOG2E, Bounds(cache.kAsmDouble));
    487   CHECK_VAR_MATH_SHORTCUT(LOG10E, Bounds(cache.kAsmDouble));
    488   CHECK_VAR_MATH_SHORTCUT(PI, Bounds(cache.kAsmDouble));
    489   CHECK_VAR_MATH_SHORTCUT(SQRT1_2, Bounds(cache.kAsmDouble));
    490   CHECK_VAR_MATH_SHORTCUT(SQRT2, Bounds(cache.kAsmDouble));
    491   // var values = new stdlib.*Array(buffer);
    492   CHECK_VAR_NEW_SHORTCUT(u8, Bounds(cache.kUint8Array));
    493   CHECK_VAR_NEW_SHORTCUT(i8, Bounds(cache.kInt8Array));
    494   CHECK_VAR_NEW_SHORTCUT(u16, Bounds(cache.kUint16Array));
    495   CHECK_VAR_NEW_SHORTCUT(i16, Bounds(cache.kInt16Array));
    496   CHECK_VAR_NEW_SHORTCUT(u32, Bounds(cache.kUint32Array));
    497   CHECK_VAR_NEW_SHORTCUT(i32, Bounds(cache.kInt32Array));
    498   CHECK_VAR_NEW_SHORTCUT(f32, Bounds(cache.kFloat32Array));
    499   CHECK_VAR_NEW_SHORTCUT(f64, Bounds(cache.kFloat64Array));
    500 }
    501 
    502 }  // namespace
    503 
    504 
    505 #define CHECK_FUNC_TYPES_BEGIN(func)                   \
    506   HARNESS_PREAMBLE()                                   \
    507   func "\n" HARNESS_POSTAMBLE();                       \
    508                                                        \
    509   v8::V8::Initialize();                                \
    510   HandleAndZoneScope handles;                          \
    511   Zone* zone = handles.main_zone();                    \
    512   ZoneVector<ExpressionTypeEntry> types(zone);         \
    513   CHECK_EQ("", Validate(zone, test_function, &types)); \
    514   TypeCache cache;                                     \
    515                                                        \
    516   CHECK_TYPES_BEGIN {                                  \
    517     /* Module. */                                      \
    518     CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
    519 #define CHECK_FUNC_TYPES_END_1()                           \
    520   /* "use asm"; */                                         \
    521   CHECK_EXPR(Literal, Bounds(Type::String(zone)));         \
    522   /* stdlib shortcuts. */                                  \
    523   CheckStdlibShortcuts1(zone, types, index, depth, cache); \
    524   CheckStdlibShortcuts2(zone, types, index, depth, cache);
    525 
    526 
    527 #define CHECK_FUNC_TYPES_END_2()                   \
    528   /* return { foo: foo }; */                       \
    529   CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { \
    530     CHECK_VAR(foo, FUNC_V_TYPE);                   \
    531   }                                                \
    532   }                                                \
    533   }                                                \
    534   CHECK_TYPES_END
    535 
    536 
    537 #define CHECK_FUNC_TYPES_END \
    538   CHECK_FUNC_TYPES_END_1();  \
    539   CHECK_FUNC_TYPES_END_2();
    540 
    541 
    542 #define CHECK_FUNC_ERROR(func, message)        \
    543   HARNESS_PREAMBLE()                           \
    544   func "\n" HARNESS_POSTAMBLE();               \
    545                                                \
    546   v8::V8::Initialize();                        \
    547   HandleAndZoneScope handles;                  \
    548   Zone* zone = handles.main_zone();            \
    549   ZoneVector<ExpressionTypeEntry> types(zone); \
    550   CHECK_EQ(message, Validate(zone, test_function, &types));
    551 
    552 
    553 TEST(BareHarness) {
    554   CHECK_FUNC_TYPES_BEGIN("function foo() {}") {
    555     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {}
    556   }
    557   CHECK_FUNC_TYPES_END
    558 }
    559 
    560 
    561 TEST(ReturnVoid) {
    562   CHECK_FUNC_TYPES_BEGIN(
    563       "function bar() { return; }\n"
    564       "function foo() { bar(); }") {
    565     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    566       // return undefined;
    567       CHECK_EXPR(Literal, Bounds(Type::Undefined(zone)));
    568     }
    569     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    570       CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
    571         CHECK_VAR(bar, FUNC_V_TYPE);
    572       }
    573     }
    574   }
    575   CHECK_FUNC_TYPES_END
    576 }
    577 
    578 
    579 TEST(EmptyBody) {
    580   CHECK_FUNC_TYPES_BEGIN(
    581       "function bar() { }\n"
    582       "function foo() { bar(); }") {
    583     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE);
    584     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    585       CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
    586         CHECK_VAR(bar, FUNC_V_TYPE);
    587       }
    588     }
    589   }
    590   CHECK_FUNC_TYPES_END
    591 }
    592 
    593 
    594 TEST(DoesNothing) {
    595   CHECK_FUNC_TYPES_BEGIN(
    596       "function bar() { var x = 1.0; }\n"
    597       "function foo() { bar(); }") {
    598     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    599       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
    600         CHECK_VAR(x, Bounds(cache.kAsmDouble));
    601         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    602       }
    603     }
    604     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    605       CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
    606         CHECK_VAR(bar, FUNC_V_TYPE);
    607       }
    608     }
    609   }
    610   CHECK_FUNC_TYPES_END
    611 }
    612 
    613 
    614 TEST(ReturnInt32Literal) {
    615   CHECK_FUNC_TYPES_BEGIN(
    616       "function bar() { return 1; }\n"
    617       "function foo() { bar(); }") {
    618     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    619       // return 1;
    620       CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
    621     }
    622     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    623       CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
    624         CHECK_VAR(bar, FUNC_I_TYPE);
    625       }
    626     }
    627   }
    628   CHECK_FUNC_TYPES_END
    629 }
    630 
    631 
    632 TEST(ReturnFloat64Literal) {
    633   CHECK_FUNC_TYPES_BEGIN(
    634       "function bar() { return 1.0; }\n"
    635       "function foo() { bar(); }") {
    636     CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
    637       // return 1.0;
    638       CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    639     }
    640     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    641       CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
    642         CHECK_VAR(bar, FUNC_D_TYPE);
    643       }
    644     }
    645   }
    646   CHECK_FUNC_TYPES_END
    647 }
    648 
    649 
    650 TEST(ReturnFloat32Literal) {
    651   CHECK_FUNC_TYPES_BEGIN(
    652       "function bar() { return fround(1.0); }\n"
    653       "function foo() { bar(); }") {
    654     CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
    655       // return fround(1.0);
    656       CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
    657         CHECK_VAR(fround, FUNC_N2F_TYPE);
    658         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    659       }
    660     }
    661     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    662       CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(bar, FUNC_F_TYPE); }
    663     }
    664   }
    665   CHECK_FUNC_TYPES_END
    666 }
    667 
    668 
    669 TEST(ReturnFloat64Var) {
    670   CHECK_FUNC_TYPES_BEGIN(
    671       "function bar() { var x = 1.0; return +x; }\n"
    672       "function foo() { bar(); }") {
    673     CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
    674       // return 1.0;
    675       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
    676         CHECK_VAR(x, Bounds(cache.kAsmDouble));
    677         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    678       }
    679       // return 1.0;
    680       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
    681         CHECK_VAR(x, Bounds(cache.kAsmDouble));
    682         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    683       }
    684     }
    685     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
    686       CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
    687         CHECK_VAR(bar, FUNC_D_TYPE);
    688       }
    689     }
    690   }
    691   CHECK_FUNC_TYPES_END
    692 }
    693 
    694 
    695 TEST(Addition2) {
    696   CHECK_FUNC_TYPES_BEGIN(
    697       "function bar() { var x = 1; var y = 2; return (x+y)|0; }\n"
    698       "function foo() { bar(); }") {
    699     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    700       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    701         CHECK_VAR(x, Bounds(cache.kAsmInt));
    702         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    703       }
    704       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    705         CHECK_VAR(y, Bounds(cache.kAsmInt));
    706         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    707       }
    708       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    709         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
    710           CHECK_VAR(x, Bounds(cache.kAsmInt));
    711           CHECK_VAR(y, Bounds(cache.kAsmInt));
    712         }
    713         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    714       }
    715     }
    716     CHECK_SKIP();
    717   }
    718   CHECK_FUNC_TYPES_END
    719 }
    720 
    721 
    722 #define TEST_COMPARE_OP(name, op)                                  \
    723   TEST(name) {                                                     \
    724     CHECK_FUNC_TYPES_BEGIN("function bar() { return (0 " op        \
    725                            " 0)|0; }\n"                            \
    726                            "function foo() { bar(); }") {          \
    727       CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {                   \
    728         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {    \
    729           CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { \
    730             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));         \
    731             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));         \
    732           }                                                        \
    733           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));           \
    734         }                                                          \
    735       }                                                            \
    736       CHECK_SKIP();                                                \
    737     }                                                              \
    738     CHECK_FUNC_TYPES_END                                           \
    739   }
    740 
    741 
    742 TEST_COMPARE_OP(EqOperator, "==")
    743 TEST_COMPARE_OP(LtOperator, "<")
    744 TEST_COMPARE_OP(LteOperator, "<=")
    745 TEST_COMPARE_OP(GtOperator, ">")
    746 TEST_COMPARE_OP(GteOperator, ">=")
    747 
    748 
    749 TEST(NeqOperator) {
    750   CHECK_FUNC_TYPES_BEGIN(
    751       "function bar() { return (0 != 0)|0; }\n"
    752       "function foo() { bar(); }") {
    753     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    754       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    755         CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
    756           CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
    757             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    758             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    759           }
    760         }
    761         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    762       }
    763     }
    764     CHECK_SKIP();
    765   }
    766   CHECK_FUNC_TYPES_END
    767 }
    768 
    769 
    770 TEST(NotOperator) {
    771   CHECK_FUNC_TYPES_BEGIN(
    772       "function bar() { var x = 0; return (!x)|0; }\n"
    773       "function foo() { bar(); }") {
    774     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    775       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    776         CHECK_VAR(x, Bounds(cache.kAsmInt));
    777         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    778       }
    779       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    780         CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
    781           CHECK_VAR(x, Bounds(cache.kAsmInt));
    782         }
    783         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    784       }
    785     }
    786     CHECK_SKIP();
    787   }
    788   CHECK_FUNC_TYPES_END
    789 }
    790 
    791 
    792 TEST(InvertOperator) {
    793   CHECK_FUNC_TYPES_BEGIN(
    794       "function bar() { var x = 0; return (~x)|0; }\n"
    795       "function foo() { bar(); }") {
    796     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    797       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    798         CHECK_VAR(x, Bounds(cache.kAsmInt));
    799         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    800       }
    801       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    802         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    803           CHECK_VAR(x, Bounds(cache.kAsmInt));
    804           CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
    805         }
    806         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    807       }
    808     }
    809     CHECK_SKIP();
    810   }
    811   CHECK_FUNC_TYPES_END
    812 }
    813 
    814 
    815 TEST(InvertConversion) {
    816   CHECK_FUNC_TYPES_BEGIN(
    817       "function bar() { var x = 0.0; return (~~x)|0; }\n"
    818       "function foo() { bar(); }") {
    819     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    820       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
    821         CHECK_VAR(x, Bounds(cache.kAsmDouble));
    822         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
    823       }
    824       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    825         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    826           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    827             CHECK_VAR(x, Bounds(cache.kAsmDouble));
    828             CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
    829           }
    830           CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
    831         }
    832         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    833       }
    834     }
    835     CHECK_SKIP();
    836   }
    837   CHECK_FUNC_TYPES_END
    838 }
    839 
    840 
    841 TEST(Ternary) {
    842   CHECK_FUNC_TYPES_BEGIN(
    843       "function bar() { var x = 1; var y = 1; return (x?y:5)|0; }\n"
    844       "function foo() { bar(); }") {
    845     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    846       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    847         CHECK_VAR(x, Bounds(cache.kAsmInt));
    848         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    849       }
    850       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    851         CHECK_VAR(y, Bounds(cache.kAsmInt));
    852         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    853       }
    854       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    855         CHECK_EXPR(Conditional, Bounds(cache.kAsmInt)) {
    856           CHECK_VAR(x, Bounds(cache.kAsmInt));
    857           CHECK_VAR(y, Bounds(cache.kAsmInt));
    858           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    859         }
    860         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    861       }
    862     }
    863     CHECK_SKIP();
    864   }
    865   CHECK_FUNC_TYPES_END
    866 }
    867 
    868 
    869 #define TEST_INT_BIN_OP(name, op)                                      \
    870   TEST(name) {                                                         \
    871     CHECK_FUNC_TYPES_BEGIN("function bar() { var x = 0; return (x " op \
    872                            " 123)|0; }\n"                              \
    873                            "function foo() { bar(); }") {              \
    874       CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {                       \
    875         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {                \
    876           CHECK_VAR(x, Bounds(cache.kAsmInt));                         \
    877           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));               \
    878         }                                                              \
    879         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {        \
    880           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {      \
    881             CHECK_VAR(x, Bounds(cache.kAsmInt));                       \
    882             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));             \
    883           }                                                            \
    884           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));               \
    885         }                                                              \
    886       }                                                                \
    887       CHECK_SKIP();                                                    \
    888     }                                                                  \
    889     CHECK_FUNC_TYPES_END                                               \
    890   }
    891 
    892 
    893 TEST_INT_BIN_OP(AndOperator, "&")
    894 TEST_INT_BIN_OP(OrOperator, "|")
    895 TEST_INT_BIN_OP(XorOperator, "^")
    896 
    897 
    898 TEST(SignedCompare) {
    899   CHECK_FUNC_TYPES_BEGIN(
    900       "function bar() { var x = 1; var y = 1; return ((x|0) < (y|0))|0; }\n"
    901       "function foo() { bar(); }") {
    902     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    903       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    904         CHECK_VAR(x, Bounds(cache.kAsmInt));
    905         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    906       }
    907       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    908         CHECK_VAR(y, Bounds(cache.kAsmInt));
    909         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    910       }
    911       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    912         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
    913           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    914             CHECK_VAR(x, Bounds(cache.kAsmInt));
    915             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    916           }
    917           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    918             CHECK_VAR(y, Bounds(cache.kAsmInt));
    919             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    920           }
    921         }
    922         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    923       }
    924     }
    925     CHECK_SKIP();
    926   }
    927   CHECK_FUNC_TYPES_END
    928 }
    929 
    930 
    931 TEST(SignedCompareConst) {
    932   CHECK_FUNC_TYPES_BEGIN(
    933       "function bar() { var x = 1; var y = 1; return ((x|0) < (1<<31))|0; }\n"
    934       "function foo() { bar(); }") {
    935     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    936       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    937         CHECK_VAR(x, Bounds(cache.kAsmInt));
    938         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    939       }
    940       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    941         CHECK_VAR(y, Bounds(cache.kAsmInt));
    942         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    943       }
    944       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    945         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
    946           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    947             CHECK_VAR(x, Bounds(cache.kAsmInt));
    948             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    949           }
    950           CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
    951         }
    952         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    953       }
    954     }
    955     CHECK_SKIP();
    956   }
    957   CHECK_FUNC_TYPES_END
    958 }
    959 
    960 
    961 TEST(UnsignedCompare) {
    962   CHECK_FUNC_TYPES_BEGIN(
    963       "function bar() { var x = 1; var y = 1; return ((x>>>0) < (y>>>0))|0; }\n"
    964       "function foo() { bar(); }") {
    965     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    966       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    967         CHECK_VAR(x, Bounds(cache.kAsmInt));
    968         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    969       }
    970       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
    971         CHECK_VAR(y, Bounds(cache.kAsmInt));
    972         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    973       }
    974       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
    975         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
    976           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
    977             CHECK_VAR(x, Bounds(cache.kAsmInt));
    978             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    979           }
    980           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
    981             CHECK_VAR(y, Bounds(cache.kAsmInt));
    982             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    983           }
    984         }
    985         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
    986       }
    987     }
    988     CHECK_SKIP();
    989   }
    990   CHECK_FUNC_TYPES_END
    991 }
    992 
    993 
    994 TEST(UnsignedCompareConst0) {
    995   CHECK_FUNC_TYPES_BEGIN(
    996       "function bar() { var x = 1; var y = 1; return ((x>>>0) < (0>>>0))|0; }\n"
    997       "function foo() { bar(); }") {
    998     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
    999       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1000         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1001         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1002       }
   1003       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1004         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1005         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1006       }
   1007       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1008         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
   1009           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
   1010             CHECK_VAR(x, Bounds(cache.kAsmInt));
   1011             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1012           }
   1013           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1014         }
   1015         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1016       }
   1017     }
   1018     CHECK_SKIP();
   1019   }
   1020   CHECK_FUNC_TYPES_END
   1021 }
   1022 
   1023 
   1024 TEST(UnsignedCompareConst1) {
   1025   CHECK_FUNC_TYPES_BEGIN(
   1026       "function bar() { var x = 1; var y = 1; return ((x>>>0) < "
   1027       "(0xffffffff>>>0))|0; }\n"
   1028       "function foo() { bar(); }") {
   1029     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
   1030       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1031         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1032         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1033       }
   1034       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1035         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1036         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1037       }
   1038       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1039         CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
   1040           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
   1041             CHECK_VAR(x, Bounds(cache.kAsmInt));
   1042             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1043           }
   1044           CHECK_EXPR(Literal, Bounds(cache.kAsmUnsigned));
   1045         }
   1046         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1047       }
   1048     }
   1049     CHECK_SKIP();
   1050   }
   1051   CHECK_FUNC_TYPES_END
   1052 }
   1053 
   1054 
   1055 TEST(UnsignedDivide) {
   1056   CHECK_FUNC_TYPES_BEGIN(
   1057       "function bar() { var x = 1; var y = 1; return ((x>>>0) / (y>>>0))|0; }\n"
   1058       "function foo() { bar(); }") {
   1059     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
   1060       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1061         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1062         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1063       }
   1064       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1065         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1066         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1067       }
   1068       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1069         CHECK_EXPR(BinaryOperation, Bounds(Type::None(zone), Type::Any(zone))) {
   1070           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
   1071             CHECK_VAR(x, Bounds(cache.kAsmInt));
   1072             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1073           }
   1074           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
   1075             CHECK_VAR(y, Bounds(cache.kAsmInt));
   1076             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1077           }
   1078         }
   1079         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1080       }
   1081     }
   1082     CHECK_SKIP();
   1083   }
   1084   CHECK_FUNC_TYPES_END
   1085 }
   1086 
   1087 
   1088 TEST(UnsignedFromFloat64) {
   1089   CHECK_FUNC_ERROR(
   1090       "function bar() { var x = 1.0; return (x>>>0)|0; }\n"
   1091       "function foo() { bar(); }",
   1092       "asm: line 39: left bitwise operand expected to be an integer\n");
   1093 }
   1094 
   1095 
   1096 TEST(AndFloat64) {
   1097   CHECK_FUNC_ERROR(
   1098       "function bar() { var x = 1.0; return (x&0)|0; }\n"
   1099       "function foo() { bar(); }",
   1100       "asm: line 39: left bitwise operand expected to be an integer\n");
   1101 }
   1102 
   1103 
   1104 TEST(TypeMismatchAddInt32Float64) {
   1105   CHECK_FUNC_ERROR(
   1106       "function bar() { var x = 1.0; var y = 0; return (x + y)|0; }\n"
   1107       "function foo() { bar(); }",
   1108       "asm: line 39: ill-typed arithmetic operation\n");
   1109 }
   1110 
   1111 
   1112 TEST(TypeMismatchSubInt32Float64) {
   1113   CHECK_FUNC_ERROR(
   1114       "function bar() { var x = 1.0; var y = 0; return (x - y)|0; }\n"
   1115       "function foo() { bar(); }",
   1116       "asm: line 39: ill-typed arithmetic operation\n");
   1117 }
   1118 
   1119 
   1120 TEST(TypeMismatchDivInt32Float64) {
   1121   CHECK_FUNC_ERROR(
   1122       "function bar() { var x = 1.0; var y = 0; return (x / y)|0; }\n"
   1123       "function foo() { bar(); }",
   1124       "asm: line 39: ill-typed arithmetic operation\n");
   1125 }
   1126 
   1127 
   1128 TEST(TypeMismatchModInt32Float64) {
   1129   CHECK_FUNC_ERROR(
   1130       "function bar() { var x = 1.0; var y = 0; return (x % y)|0; }\n"
   1131       "function foo() { bar(); }",
   1132       "asm: line 39: ill-typed arithmetic operation\n");
   1133 }
   1134 
   1135 
   1136 TEST(ModFloat32) {
   1137   CHECK_FUNC_ERROR(
   1138       "function bar() { var x = fround(1.0); return (x % x)|0; }\n"
   1139       "function foo() { bar(); }",
   1140       "asm: line 39: ill-typed arithmetic operation\n");
   1141 }
   1142 
   1143 
   1144 TEST(TernaryMismatchInt32Float64) {
   1145   CHECK_FUNC_ERROR(
   1146       "function bar() { var x = 1; var y = 0.0; return (1 ? x : y)|0; }\n"
   1147       "function foo() { bar(); }",
   1148       "asm: line 39: then and else expressions in ? must have the same type\n");
   1149 }
   1150 
   1151 
   1152 TEST(TernaryMismatchIntish) {
   1153   CHECK_FUNC_ERROR(
   1154       "function bar() { var x = 1; var y = 0; return (1 ? x + x : y)|0; }\n"
   1155       "function foo() { bar(); }",
   1156       "asm: line 39: invalid type in ? then expression\n");
   1157 }
   1158 
   1159 
   1160 TEST(TernaryMismatchInt32Float32) {
   1161   CHECK_FUNC_ERROR(
   1162       "function bar() { var x = 1; var y = 2; return (x?fround(y):x)|0; }\n"
   1163       "function foo() { bar(); }",
   1164       "asm: line 39: then and else expressions in ? must have the same type\n");
   1165 }
   1166 
   1167 
   1168 TEST(TernaryBadCondition) {
   1169   CHECK_FUNC_ERROR(
   1170       "function bar() { var x = 1; var y = 2.0; return (y?x:1)|0; }\n"
   1171       "function foo() { bar(); }",
   1172       "asm: line 39: condition must be of type int\n");
   1173 }
   1174 
   1175 
   1176 TEST(FroundFloat32) {
   1177   CHECK_FUNC_TYPES_BEGIN(
   1178       "function bar() { var x = 1; return fround(x); }\n"
   1179       "function foo() { bar(); }") {
   1180     CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
   1181       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1182         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1183         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1184       }
   1185       CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1186         CHECK_VAR(fround, FUNC_N2F_TYPE);
   1187         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1188       }
   1189     }
   1190     CHECK_SKIP();
   1191   }
   1192   CHECK_FUNC_TYPES_END
   1193 }
   1194 
   1195 
   1196 TEST(Addition4) {
   1197   CHECK_FUNC_TYPES_BEGIN(
   1198       "function bar() { var x = 1; var y = 2; return (x+y+x+y)|0; }\n"
   1199       "function foo() { bar(); }") {
   1200     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
   1201       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1202         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1203         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1204       }
   1205       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1206         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1207         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1208       }
   1209       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1210         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
   1211           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
   1212             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
   1213               CHECK_VAR(x, Bounds(cache.kAsmInt));
   1214               CHECK_VAR(y, Bounds(cache.kAsmInt));
   1215             }
   1216             CHECK_VAR(x, Bounds(cache.kAsmInt));
   1217           }
   1218           CHECK_VAR(y, Bounds(cache.kAsmInt));
   1219         }
   1220         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1221       }
   1222     }
   1223     CHECK_SKIP();
   1224   }
   1225   CHECK_FUNC_TYPES_END
   1226 }
   1227 
   1228 
   1229 TEST(Multiplication2) {
   1230   CHECK_FUNC_ERROR(
   1231       "function bar() { var x = 1; var y = 2; return (x*y)|0; }\n"
   1232       "function foo() { bar(); }",
   1233       "asm: line 39: direct integer multiply forbidden\n");
   1234 }
   1235 
   1236 
   1237 TEST(Division4) {
   1238   CHECK_FUNC_ERROR(
   1239       "function bar() { var x = 1; var y = 2; return (x/y/x/y)|0; }\n"
   1240       "function foo() { bar(); }",
   1241       "asm: line 39: too many consecutive multiplicative ops\n");
   1242 }
   1243 
   1244 
   1245 TEST(CompareToStringLeft) {
   1246   CHECK_FUNC_ERROR(
   1247       "function bar() { var x = 1; return ('hi' > x)|0; }\n"
   1248       "function foo() { bar(); }",
   1249       "asm: line 39: bad type on left side of comparison\n");
   1250 }
   1251 
   1252 
   1253 TEST(CompareToStringRight) {
   1254   CHECK_FUNC_ERROR(
   1255       "function bar() { var x = 1; return (x < 'hi')|0; }\n"
   1256       "function foo() { bar(); }",
   1257       "asm: line 39: bad type on right side of comparison\n");
   1258 }
   1259 
   1260 
   1261 TEST(CompareMismatchInt32Float64) {
   1262   CHECK_FUNC_ERROR(
   1263       "function bar() { var x = 1; var y = 2.0; return (x < y)|0; }\n"
   1264       "function foo() { bar(); }",
   1265       "asm: line 39: left and right side of comparison must match\n");
   1266 }
   1267 
   1268 
   1269 TEST(CompareMismatchInt32Uint32) {
   1270   CHECK_FUNC_ERROR(
   1271       "function bar() { var x = 1; var y = 2; return ((x|0) < (y>>>0))|0; }\n"
   1272       "function foo() { bar(); }",
   1273       "asm: line 39: left and right side of comparison must match\n");
   1274 }
   1275 
   1276 
   1277 TEST(CompareMismatchInt32Float32) {
   1278   CHECK_FUNC_ERROR(
   1279       "function bar() { var x = 1; var y = 2; return (x < fround(y))|0; }\n"
   1280       "function foo() { bar(); }",
   1281       "asm: line 39: left and right side of comparison must match\n");
   1282 }
   1283 
   1284 
   1285 TEST(Float64ToInt32) {
   1286   CHECK_FUNC_TYPES_BEGIN(
   1287       "function bar() { var x = 1; var y = 0.0; x = ~~y; }\n"
   1288       "function foo() { bar(); }") {
   1289     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1290       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1291         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1292         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1293       }
   1294       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1295         CHECK_VAR(y, Bounds(cache.kAsmDouble));
   1296         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1297       }
   1298       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1299         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1300         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1301           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1302             CHECK_VAR(y, Bounds(cache.kAsmDouble));
   1303             CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   1304           }
   1305           CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   1306         }
   1307       }
   1308     }
   1309     CHECK_SKIP();
   1310   }
   1311   CHECK_FUNC_TYPES_END
   1312 }
   1313 
   1314 
   1315 TEST(Load1) {
   1316   CHECK_FUNC_TYPES_BEGIN(
   1317       "function bar() { var x = 1; var y = i8[x>>0]|0; }\n"
   1318       "function foo() { bar(); }") {
   1319     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1320       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1321         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1322         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1323       }
   1324       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1325         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1326         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1327           CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
   1328             CHECK_VAR(i8, Bounds(cache.kInt8Array));
   1329             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1330               CHECK_VAR(x, Bounds(cache.kAsmSigned));
   1331               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1332             }
   1333           }
   1334           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1335         }
   1336       }
   1337     }
   1338     CHECK_SKIP();
   1339   }
   1340   CHECK_FUNC_TYPES_END
   1341 }
   1342 
   1343 
   1344 TEST(LoadDouble) {
   1345   CHECK_FUNC_TYPES_BEGIN(
   1346       "function bar() { var x = 1; var y = 0.0; y = +f64[x>>3]; }\n"
   1347       "function foo() { bar(); }") {
   1348     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1349       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1350         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1351         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1352       }
   1353       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1354         CHECK_VAR(y, Bounds(cache.kAsmDouble));
   1355         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1356       }
   1357       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1358         CHECK_VAR(y, Bounds(cache.kAsmDouble));
   1359         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
   1360           CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
   1361             CHECK_VAR(f64, Bounds(cache.kFloat64Array));
   1362             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1363               CHECK_VAR(x, Bounds(cache.kAsmSigned));
   1364               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1365             }
   1366           }
   1367           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1368         }
   1369       }
   1370     }
   1371     CHECK_SKIP();
   1372   }
   1373   CHECK_FUNC_TYPES_END
   1374 }
   1375 
   1376 
   1377 TEST(Store1) {
   1378   CHECK_FUNC_TYPES_BEGIN(
   1379       "function bar() { var x = 1; i8[x>>0] = 0; }\n"
   1380       "function foo() { bar(); }") {
   1381     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1382       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1383         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1384         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1385       }
   1386       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1387         CHECK_EXPR(Property, Bounds::Unbounded()) {
   1388           CHECK_VAR(i8, Bounds(cache.kInt8Array));
   1389           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1390             CHECK_VAR(x, Bounds(cache.kAsmSigned));
   1391             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1392           }
   1393         }
   1394         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1395       }
   1396     }
   1397     CHECK_SKIP();
   1398   }
   1399   CHECK_FUNC_TYPES_END
   1400 }
   1401 
   1402 
   1403 TEST(StoreFloat) {
   1404   CHECK_FUNC_TYPES_BEGIN(
   1405       "function bar() { var x = fround(1.0); "
   1406       "f32[0] = fround(x + fround(1.0)); }\n"
   1407       "function foo() { bar(); }") {
   1408     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1409       CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
   1410         CHECK_VAR(x, Bounds(cache.kAsmFloat));
   1411         CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1412           CHECK_VAR(fround, FUNC_N2F_TYPE);
   1413           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1414         }
   1415       }
   1416       CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
   1417         CHECK_EXPR(Property, Bounds::Unbounded()) {
   1418           CHECK_VAR(f32, Bounds(cache.kFloat32Array));
   1419           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1420         }
   1421         CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1422           CHECK_VAR(fround, FUNC_N2F_TYPE);
   1423           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
   1424             CHECK_VAR(x, Bounds(cache.kAsmFloat));
   1425             CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1426               CHECK_VAR(fround, FUNC_N2F_TYPE);
   1427               CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1428             }
   1429           }
   1430         }
   1431       }
   1432     }
   1433     CHECK_SKIP();
   1434   }
   1435   CHECK_FUNC_TYPES_END
   1436 }
   1437 
   1438 
   1439 TEST(Load1Constant) {
   1440   CHECK_FUNC_TYPES_BEGIN(
   1441       "function bar() { var x = 1; var y = i8[5]|0; }\n"
   1442       "function foo() { bar(); }") {
   1443     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1444       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1445         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1446         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1447       }
   1448       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1449         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1450         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1451           CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
   1452             CHECK_VAR(i8, Bounds(cache.kInt8Array));
   1453             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1454           }
   1455           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1456         }
   1457       }
   1458     }
   1459     CHECK_SKIP();
   1460   }
   1461   CHECK_FUNC_TYPES_END
   1462 }
   1463 
   1464 
   1465 TEST(FunctionTables) {
   1466   CHECK_FUNC_TYPES_BEGIN(
   1467       "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
   1468       "function func2(x) { x = x | 0; return (x * 25) | 0; }\n"
   1469       "var table1 = [func1, func2];\n"
   1470       "function bar(x, y) { x = x | 0; y = y | 0;\n"
   1471       "   return table1[x & 1](y)|0; }\n"
   1472       "function foo() { bar(1, 2); }") {
   1473     CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
   1474       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1475         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1476         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1477           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1478           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1479         }
   1480       }
   1481       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1482         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
   1483           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1484           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1485         }
   1486         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1487       }
   1488     }
   1489     CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
   1490       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1491         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1492         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1493           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1494           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1495         }
   1496       }
   1497       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1498         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
   1499           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1500           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1501         }
   1502         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1503       }
   1504     }
   1505     CHECK_EXPR(FunctionLiteral, FUNC_II2I_TYPE) {
   1506       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1507         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1508         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1509           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1510           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1511         }
   1512       }
   1513       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1514         CHECK_VAR(y, Bounds(cache.kAsmInt));
   1515         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1516           CHECK_VAR(y, Bounds(cache.kAsmInt));
   1517           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1518         }
   1519       }
   1520       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1521         CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
   1522           CHECK_EXPR(Property, FUNC_I2I_TYPE) {
   1523             CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
   1524             CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1525               CHECK_VAR(x, Bounds(cache.kAsmSigned));
   1526               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1527             }
   1528           }
   1529           CHECK_VAR(y, Bounds(cache.kAsmInt));
   1530         }
   1531         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1532       }
   1533     }
   1534     CHECK_SKIP();
   1535   }
   1536   CHECK_FUNC_TYPES_END_1();
   1537   CHECK_EXPR(Assignment, FUNC_I2I_ARRAY_TYPE) {
   1538     CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
   1539     CHECK_EXPR(ArrayLiteral, FUNC_I2I_ARRAY_TYPE) {
   1540       CHECK_VAR(func1, FUNC_I2I_TYPE);
   1541       CHECK_VAR(func2, FUNC_I2I_TYPE);
   1542     }
   1543   }
   1544   CHECK_FUNC_TYPES_END_2();
   1545 }
   1546 
   1547 
   1548 TEST(BadFunctionTable) {
   1549   CHECK_FUNC_ERROR(
   1550       "function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
   1551       "var table1 = [func1, 1];\n"
   1552       "function bar(x, y) { x = x | 0; y = y | 0;\n"
   1553       "   return table1[x & 1](y)|0; }\n"
   1554       "function foo() { bar(1, 2); }",
   1555       "asm: line 40: array component expected to be a function\n");
   1556 }
   1557 
   1558 
   1559 TEST(MissingParameterTypes) {
   1560   CHECK_FUNC_ERROR(
   1561       "function bar(x) { var y = 1; }\n"
   1562       "function foo() { bar(2); }",
   1563       "asm: line 39: missing parameter type annotations\n");
   1564 }
   1565 
   1566 
   1567 TEST(InvalidTypeAnnotationBinaryOpDiv) {
   1568   CHECK_FUNC_ERROR(
   1569       "function bar(x) { x = x / 4; }\n"
   1570       "function foo() { bar(2); }",
   1571       "asm: line 39: invalid type annotation on binary op\n");
   1572 }
   1573 
   1574 
   1575 TEST(InvalidTypeAnnotationBinaryOpMul) {
   1576   CHECK_FUNC_ERROR(
   1577       "function bar(x) { x = x * 4.0; }\n"
   1578       "function foo() { bar(2); }",
   1579       "asm: line 39: invalid type annotation on binary op\n");
   1580 }
   1581 
   1582 
   1583 TEST(InvalidArgumentCount) {
   1584   CHECK_FUNC_ERROR(
   1585       "function bar(x) { return fround(4, 5); }\n"
   1586       "function foo() { bar(); }",
   1587       "asm: line 39: invalid argument count calling function\n");
   1588 }
   1589 
   1590 
   1591 TEST(InvalidTypeAnnotationArity) {
   1592   CHECK_FUNC_ERROR(
   1593       "function bar(x) { x = max(x); }\n"
   1594       "function foo() { bar(3); }",
   1595       "asm: line 39: only fround allowed on expression annotations\n");
   1596 }
   1597 
   1598 
   1599 TEST(InvalidTypeAnnotationOnlyFround) {
   1600   CHECK_FUNC_ERROR(
   1601       "function bar(x) { x = sin(x); }\n"
   1602       "function foo() { bar(3); }",
   1603       "asm: line 39: only fround allowed on expression annotations\n");
   1604 }
   1605 
   1606 
   1607 TEST(InvalidTypeAnnotation) {
   1608   CHECK_FUNC_ERROR(
   1609       "function bar(x) { x = (x+x)(x); }\n"
   1610       "function foo() { bar(3); }",
   1611       "asm: line 39: invalid type annotation\n");
   1612 }
   1613 
   1614 
   1615 TEST(WithStatement) {
   1616   CHECK_FUNC_ERROR(
   1617       "function bar() { var x = 0; with (x) { x = x + 1; } }\n"
   1618       "function foo() { bar(); }",
   1619       "asm: line 39: bad with statement\n");
   1620 }
   1621 
   1622 
   1623 TEST(NestedFunction) {
   1624   CHECK_FUNC_ERROR(
   1625       "function bar() { function x() { return 1; } }\n"
   1626       "function foo() { bar(); }",
   1627       "asm: line 39: function declared inside another\n");
   1628 }
   1629 
   1630 
   1631 TEST(UnboundVariable) {
   1632   CHECK_FUNC_ERROR(
   1633       "function bar() { var x = y; }\n"
   1634       "function foo() { bar(); }",
   1635       "asm: line 39: unbound variable\n");
   1636 }
   1637 
   1638 
   1639 TEST(EqStrict) {
   1640   CHECK_FUNC_ERROR(
   1641       "function bar() { return (0 === 0)|0; }\n"
   1642       "function foo() { bar(); }",
   1643       "asm: line 39: illegal comparison operator\n");
   1644 }
   1645 
   1646 
   1647 TEST(NeStrict) {
   1648   CHECK_FUNC_ERROR(
   1649       "function bar() { return (0 !== 0)|0; }\n"
   1650       "function foo() { bar(); }",
   1651       "asm: line 39: illegal comparison operator\n");
   1652 }
   1653 
   1654 
   1655 TEST(InstanceOf) {
   1656   CHECK_FUNC_ERROR(
   1657       "function bar() { return (0 instanceof 0)|0; }\n"
   1658       "function foo() { bar(); }",
   1659       "asm: line 39: illegal comparison operator\n");
   1660 }
   1661 
   1662 
   1663 TEST(InOperator) {
   1664   CHECK_FUNC_ERROR(
   1665       "function bar() { return (0 in 0)|0; }\n"
   1666       "function foo() { bar(); }",
   1667       "asm: line 39: illegal comparison operator\n");
   1668 }
   1669 
   1670 
   1671 TEST(LogicalAndOperator) {
   1672   CHECK_FUNC_ERROR(
   1673       "function bar() { return (0 && 0)|0; }\n"
   1674       "function foo() { bar(); }",
   1675       "asm: line 39: illegal logical operator\n");
   1676 }
   1677 
   1678 
   1679 TEST(LogicalOrOperator) {
   1680   CHECK_FUNC_ERROR(
   1681       "function bar() { return (0 || 0)|0; }\n"
   1682       "function foo() { bar(); }",
   1683       "asm: line 39: illegal logical operator\n");
   1684 }
   1685 
   1686 
   1687 TEST(BadLiteral) {
   1688   CHECK_FUNC_ERROR(
   1689       "function bar() { return true | 0; }\n"
   1690       "function foo() { bar(); }",
   1691       "asm: line 39: illegal literal\n");
   1692 }
   1693 
   1694 
   1695 TEST(MismatchedReturnTypeLiteral) {
   1696   CHECK_FUNC_ERROR(
   1697       "function bar() { if(1) { return 1; } return 1.0; }\n"
   1698       "function foo() { bar(); }",
   1699       "asm: line 39: return type does not match function signature\n");
   1700 }
   1701 
   1702 
   1703 TEST(MismatchedReturnTypeExpression) {
   1704   CHECK_FUNC_ERROR(
   1705       "function bar() {\n"
   1706       "  var x = 1; var y = 1.0; if(1) { return x; } return +y; }\n"
   1707       "function foo() { bar(); }",
   1708       "asm: line 40: return type does not match function signature\n");
   1709 }
   1710 
   1711 
   1712 TEST(AssignToFloatishToF64) {
   1713   CHECK_FUNC_ERROR(
   1714       "function bar() { var v = fround(1.0); f32[0] = v + fround(1.0); }\n"
   1715       "function foo() { bar(); }",
   1716       "asm: line 39: intish or floatish assignment\n");
   1717 }
   1718 
   1719 
   1720 TEST(ForeignFunction) {
   1721   CHECK_FUNC_TYPES_BEGIN(
   1722       "var baz = foreign.baz;\n"
   1723       "function bar() { return baz(1, 2)|0; }\n"
   1724       "function foo() { bar(); }") {
   1725     CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
   1726       CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1727         CHECK_EXPR(Call, Bounds(Type::Number(zone))) {
   1728           CHECK_VAR(baz, Bounds(Type::Any(zone)));
   1729           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1730           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1731         }
   1732         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1733       }
   1734     }
   1735     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1736       CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
   1737         CHECK_VAR(bar, FUNC_I_TYPE);
   1738       }
   1739     }
   1740   }
   1741   CHECK_FUNC_TYPES_END_1()
   1742   CHECK_EXPR(Assignment, Bounds(Type::Any(zone))) {
   1743     CHECK_VAR(baz, Bounds(Type::Any(zone)));
   1744     CHECK_EXPR(Property, Bounds(Type::Any(zone))) {
   1745       CHECK_VAR(foreign, Bounds::Unbounded());
   1746       CHECK_EXPR(Literal, Bounds::Unbounded());
   1747     }
   1748   }
   1749   CHECK_FUNC_TYPES_END_2()
   1750 }
   1751 
   1752 
   1753 TEST(BadExports) {
   1754   HARNESS_PREAMBLE()
   1755   "function foo() {};\n"
   1756   "return {foo: foo, bar: 1};"
   1757   "}\n";
   1758 
   1759   v8::V8::Initialize();
   1760   HandleAndZoneScope handles;
   1761   Zone* zone = handles.main_zone();
   1762   ZoneVector<ExpressionTypeEntry> types(zone);
   1763   CHECK_EQ("asm: line 40: non-function in function table\n",
   1764            Validate(zone, test_function, &types));
   1765 }
   1766 
   1767 
   1768 TEST(NestedHeapAssignment) {
   1769   CHECK_FUNC_ERROR(
   1770       "function bar() { var x = 0; i8[x = 1] = 2; }\n"
   1771       "function foo() { bar(); }",
   1772       "asm: line 39: expected >> in heap access\n");
   1773 }
   1774 
   1775 
   1776 TEST(BadArrayAssignment) {
   1777   CHECK_FUNC_ERROR(
   1778       "function bar() { i8[0] = 0.0; }\n"
   1779       "function foo() { bar(); }",
   1780       "asm: line 39: illegal type in assignment\n");
   1781 }
   1782 
   1783 
   1784 TEST(BadStandardFunctionCallOutside) {
   1785   CHECK_FUNC_ERROR(
   1786       "var s0 = sin(0);\n"
   1787       "function bar() { }\n"
   1788       "function foo() { bar(); }",
   1789       "asm: line 39: calls forbidden outside function bodies\n");
   1790 }
   1791 
   1792 
   1793 TEST(BadFunctionCallOutside) {
   1794   CHECK_FUNC_ERROR(
   1795       "function bar() { return 0.0; }\n"
   1796       "var s0 = bar(0);\n"
   1797       "function foo() { bar(); }",
   1798       "asm: line 40: calls forbidden outside function bodies\n");
   1799 }
   1800 
   1801 
   1802 TEST(NestedVariableAssignment) {
   1803   CHECK_FUNC_TYPES_BEGIN(
   1804       "function bar() { var x = 0; x = x = 4; }\n"
   1805       "function foo() { bar(); }") {
   1806     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1807       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1808         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1809         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1810       }
   1811       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1812         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1813         CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1814           CHECK_VAR(x, Bounds(cache.kAsmInt));
   1815           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1816         }
   1817       }
   1818     }
   1819     CHECK_SKIP();
   1820   }
   1821   CHECK_FUNC_TYPES_END
   1822 }
   1823 
   1824 
   1825 TEST(NestedAssignmentInHeap) {
   1826   CHECK_FUNC_TYPES_BEGIN(
   1827       "function bar() { var x = 0; i8[(x = 1) >> 0] = 2; }\n"
   1828       "function foo() { bar(); }") {
   1829     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1830       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1831         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1832         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1833       }
   1834       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1835         CHECK_EXPR(Property, Bounds::Unbounded()) {
   1836           CHECK_VAR(i8, Bounds(cache.kInt8Array));
   1837           CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1838             CHECK_EXPR(Assignment, Bounds(cache.kAsmSigned)) {
   1839               CHECK_VAR(x, Bounds(cache.kAsmInt));
   1840               CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1841             }
   1842             CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1843           }
   1844         }
   1845         CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   1846       }
   1847     }
   1848     CHECK_SKIP();
   1849   }
   1850   CHECK_FUNC_TYPES_END
   1851 }
   1852 
   1853 
   1854 TEST(NegativeDouble) {
   1855   CHECK_FUNC_TYPES_BEGIN(
   1856       "function bar() { var x = -123.2; }\n"
   1857       "function foo() { bar(); }") {
   1858     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1859       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1860         CHECK_VAR(x, Bounds(cache.kAsmDouble));
   1861         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1862       }
   1863     }
   1864     CHECK_SKIP();
   1865   }
   1866   CHECK_FUNC_TYPES_END
   1867 }
   1868 
   1869 
   1870 TEST(NegativeInteger) {
   1871   CHECK_FUNC_TYPES_BEGIN(
   1872       "function bar() { var x = -123; }\n"
   1873       "function foo() { bar(); }") {
   1874     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1875       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1876         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1877         CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   1878       }
   1879     }
   1880     CHECK_SKIP();
   1881   }
   1882   CHECK_FUNC_TYPES_END
   1883 }
   1884 
   1885 
   1886 TEST(AbsFunction) {
   1887   CHECK_FUNC_TYPES_BEGIN(
   1888       "function bar() { var x = -123.0; x = abs(x); }\n"
   1889       "function foo() { bar(); }") {
   1890     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1891       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1892         CHECK_VAR(x, Bounds(cache.kAsmDouble));
   1893         CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1894       }
   1895       CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
   1896         CHECK_VAR(x, Bounds(cache.kAsmDouble));
   1897         CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
   1898           CHECK_VAR(abs, FUNC_N2N_TYPE);
   1899           CHECK_VAR(x, Bounds(cache.kAsmDouble));
   1900         }
   1901       }
   1902     }
   1903     CHECK_SKIP();
   1904   }
   1905   CHECK_FUNC_TYPES_END
   1906 }
   1907 
   1908 
   1909 TEST(CeilFloat) {
   1910   CHECK_FUNC_TYPES_BEGIN(
   1911       "function bar() { var x = fround(3.1); x = ceil(x); }\n"
   1912       "function foo() { bar(); }") {
   1913     CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
   1914       CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
   1915         CHECK_VAR(x, Bounds(cache.kAsmFloat));
   1916         CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1917           CHECK_VAR(fround, FUNC_N2F_TYPE);
   1918           CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
   1919         }
   1920       }
   1921       CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
   1922         CHECK_VAR(x, Bounds(cache.kAsmFloat));
   1923         CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
   1924           CHECK_VAR(ceil, FUNC_N2N_TYPE);
   1925           CHECK_VAR(x, Bounds(cache.kAsmFloat));
   1926         }
   1927       }
   1928     }
   1929     CHECK_SKIP();
   1930   }
   1931   CHECK_FUNC_TYPES_END
   1932 }
   1933 
   1934 
   1935 TEST(TypeConsistency) {
   1936   v8::V8::Initialize();
   1937   TypeCache cache;
   1938   // Check the consistency of each of the main Asm.js types.
   1939   CHECK(cache.kAsmFixnum->Is(cache.kAsmFixnum));
   1940   CHECK(cache.kAsmFixnum->Is(cache.kAsmSigned));
   1941   CHECK(cache.kAsmFixnum->Is(cache.kAsmUnsigned));
   1942   CHECK(cache.kAsmFixnum->Is(cache.kAsmInt));
   1943   CHECK(!cache.kAsmFixnum->Is(cache.kAsmFloat));
   1944   CHECK(!cache.kAsmFixnum->Is(cache.kAsmDouble));
   1945 
   1946   CHECK(cache.kAsmSigned->Is(cache.kAsmSigned));
   1947   CHECK(cache.kAsmSigned->Is(cache.kAsmInt));
   1948   CHECK(!cache.kAsmSigned->Is(cache.kAsmFixnum));
   1949   CHECK(!cache.kAsmSigned->Is(cache.kAsmUnsigned));
   1950   CHECK(!cache.kAsmSigned->Is(cache.kAsmFloat));
   1951   CHECK(!cache.kAsmSigned->Is(cache.kAsmDouble));
   1952 
   1953   CHECK(cache.kAsmUnsigned->Is(cache.kAsmUnsigned));
   1954   CHECK(cache.kAsmUnsigned->Is(cache.kAsmInt));
   1955   CHECK(!cache.kAsmUnsigned->Is(cache.kAsmSigned));
   1956   CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFixnum));
   1957   CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFloat));
   1958   CHECK(!cache.kAsmUnsigned->Is(cache.kAsmDouble));
   1959 
   1960   CHECK(cache.kAsmInt->Is(cache.kAsmInt));
   1961   CHECK(!cache.kAsmInt->Is(cache.kAsmUnsigned));
   1962   CHECK(!cache.kAsmInt->Is(cache.kAsmSigned));
   1963   CHECK(!cache.kAsmInt->Is(cache.kAsmFixnum));
   1964   CHECK(!cache.kAsmInt->Is(cache.kAsmFloat));
   1965   CHECK(!cache.kAsmInt->Is(cache.kAsmDouble));
   1966 
   1967   CHECK(cache.kAsmFloat->Is(cache.kAsmFloat));
   1968   CHECK(!cache.kAsmFloat->Is(cache.kAsmInt));
   1969   CHECK(!cache.kAsmFloat->Is(cache.kAsmUnsigned));
   1970   CHECK(!cache.kAsmFloat->Is(cache.kAsmSigned));
   1971   CHECK(!cache.kAsmFloat->Is(cache.kAsmFixnum));
   1972   CHECK(!cache.kAsmFloat->Is(cache.kAsmDouble));
   1973 
   1974   CHECK(cache.kAsmDouble->Is(cache.kAsmDouble));
   1975   CHECK(!cache.kAsmDouble->Is(cache.kAsmInt));
   1976   CHECK(!cache.kAsmDouble->Is(cache.kAsmUnsigned));
   1977   CHECK(!cache.kAsmDouble->Is(cache.kAsmSigned));
   1978   CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum));
   1979   CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat));
   1980 }
   1981 
   1982 
   1983 TEST(SwitchTest) {
   1984   CHECK_FUNC_TYPES_BEGIN(
   1985       "function switcher(x) {\n"
   1986       "  x = x|0;\n"
   1987       "  switch (x|0) {\n"
   1988       "    case 1: return 23;\n"
   1989       "    case 2: return 43;\n"
   1990       "    default: return 66;\n"
   1991       "  }\n"
   1992       "  return 0;\n"
   1993       "}\n"
   1994       "function foo() { switcher(1); }") {
   1995     CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
   1996       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   1997         CHECK_VAR(x, Bounds(cache.kAsmInt));
   1998         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   1999           CHECK_VAR(x, Bounds(cache.kAsmInt));
   2000           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   2001         }
   2002       }
   2003       CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
   2004         CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt));
   2005         CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
   2006           CHECK_VAR(x, Bounds(cache.kAsmInt));
   2007           CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   2008         }
   2009       }
   2010       CHECK_EXPR(Literal, Bounds(Type::Undefined(zone)));
   2011       CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
   2012       // case 1: return 23;
   2013       CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   2014       CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   2015       // case 2: return 43;
   2016       CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
   2017       CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   2018       // default: return 66;
   2019       CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   2020       // return 0;
   2021       CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
   2022     }
   2023     CHECK_SKIP();
   2024   }
   2025   CHECK_FUNC_TYPES_END
   2026 }
   2027 
   2028 
   2029 TEST(BadSwitchRange) {
   2030   CHECK_FUNC_ERROR(
   2031       "function bar() { switch (1) { case -1: case 0x7fffffff: } }\n"
   2032       "function foo() { bar(); }",
   2033       "asm: line 39: case range too large\n");
   2034 }
   2035 
   2036 
   2037 TEST(DuplicateSwitchCase) {
   2038   CHECK_FUNC_ERROR(
   2039       "function bar() { switch (1) { case 0: case 0: } }\n"
   2040       "function foo() { bar(); }",
   2041       "asm: line 39: duplicate case value\n");
   2042 }
   2043 
   2044 
   2045 TEST(BadSwitchOrder) {
   2046   CHECK_FUNC_ERROR(
   2047       "function bar() { switch (1) { default: case 0: } }\n"
   2048       "function foo() { bar(); }",
   2049       "asm: line 39: default case out of order\n");
   2050 }
   2051