Home | History | Annotate | Download | only in wasm
      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/base/platform/elapsed-timer.h"
      6 #include "src/signature.h"
      7 
      8 #include "src/flags.h"
      9 #include "src/handles.h"
     10 #include "src/zone-containers.h"
     11 
     12 #include "src/wasm/ast-decoder.h"
     13 #include "src/wasm/decoder.h"
     14 #include "src/wasm/wasm-module.h"
     15 #include "src/wasm/wasm-opcodes.h"
     16 
     17 #include "src/compiler/wasm-compiler.h"
     18 
     19 namespace v8 {
     20 namespace internal {
     21 namespace wasm {
     22 
     23 #if DEBUG
     24 #define TRACE(...)                                    \
     25   do {                                                \
     26     if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
     27   } while (false)
     28 #else
     29 #define TRACE(...)
     30 #endif
     31 
     32 // The root of a decoded tree.
     33 struct Tree {
     34   LocalType type;     // tree type.
     35   uint32_t count;     // number of children.
     36   const byte* pc;     // start of the syntax tree.
     37   TFNode* node;       // node in the TurboFan graph.
     38   Tree* children[1];  // pointers to children.
     39 
     40   WasmOpcode opcode() const { return static_cast<WasmOpcode>(*pc); }
     41 };
     42 
     43 
     44 // A production represents an incomplete decoded tree in the LR decoder.
     45 struct Production {
     46   Tree* tree;  // the root of the syntax tree.
     47   int index;   // the current index into the children of the tree.
     48 
     49   WasmOpcode opcode() const { return static_cast<WasmOpcode>(*pc()); }
     50   const byte* pc() const { return tree->pc; }
     51   bool done() const { return index >= static_cast<int>(tree->count); }
     52   Tree* last() const { return index > 0 ? tree->children[index - 1] : nullptr; }
     53 };
     54 
     55 
     56 // An SsaEnv environment carries the current local variable renaming
     57 // as well as the current effect and control dependency in the TF graph.
     58 // It maintains a control state that tracks whether the environment
     59 // is reachable, has reached a control end, or has been merged.
     60 struct SsaEnv {
     61   enum State { kControlEnd, kUnreachable, kReached, kMerged };
     62 
     63   State state;
     64   TFNode* control;
     65   TFNode* effect;
     66   TFNode** locals;
     67 
     68   bool go() { return state >= kReached; }
     69   void Kill(State new_state = kControlEnd) {
     70     state = new_state;
     71     locals = nullptr;
     72     control = nullptr;
     73     effect = nullptr;
     74   }
     75 };
     76 
     77 
     78 // An entry in the stack of blocks during decoding.
     79 struct Block {
     80   SsaEnv* ssa_env;  // SSA renaming environment.
     81   int stack_depth;  // production stack depth.
     82 };
     83 
     84 
     85 // An entry in the stack of ifs during decoding.
     86 struct IfEnv {
     87   SsaEnv* false_env;
     88   SsaEnv* merge_env;
     89   SsaEnv** case_envs;
     90 };
     91 
     92 
     93 // Macros that build nodes only if there is a graph and the current SSA
     94 // environment is reachable from start. This avoids problems with malformed
     95 // TF graphs when decoding inputs that have unreachable code.
     96 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr)
     97 #define BUILD0(func) (build() ? builder_->func() : nullptr)
     98 
     99 
    100 // A shift-reduce-parser strategy for decoding Wasm code that uses an explicit
    101 // shift-reduce strategy with multiple internal stacks.
    102 class LR_WasmDecoder : public Decoder {
    103  public:
    104   LR_WasmDecoder(Zone* zone, TFBuilder* builder)
    105       : Decoder(nullptr, nullptr),
    106         zone_(zone),
    107         builder_(builder),
    108         trees_(zone),
    109         stack_(zone),
    110         blocks_(zone),
    111         ifs_(zone) {}
    112 
    113   TreeResult Decode(FunctionEnv* function_env, const byte* base, const byte* pc,
    114                     const byte* end) {
    115     base::ElapsedTimer decode_timer;
    116     if (FLAG_trace_wasm_decode_time) {
    117       decode_timer.Start();
    118     }
    119     trees_.clear();
    120     stack_.clear();
    121     blocks_.clear();
    122     ifs_.clear();
    123 
    124     if (end < pc) {
    125       error(pc, "function body end < start");
    126       return result_;
    127     }
    128 
    129     base_ = base;
    130     Reset(pc, end);
    131     function_env_ = function_env;
    132 
    133     InitSsaEnv();
    134     DecodeFunctionBody();
    135 
    136     Tree* tree = nullptr;
    137     if (ok()) {
    138       if (ssa_env_->go()) {
    139         if (stack_.size() > 0) {
    140           error(stack_.back().pc(), end, "fell off end of code");
    141         }
    142         AddImplicitReturnAtEnd();
    143       }
    144       if (trees_.size() == 0) {
    145         if (function_env_->sig->return_count() > 0) {
    146           error(start_, "no trees created");
    147         }
    148       } else {
    149         tree = trees_[0];
    150       }
    151     }
    152 
    153     if (ok()) {
    154       if (FLAG_trace_wasm_decode_time) {
    155         double ms = decode_timer.Elapsed().InMillisecondsF();
    156         PrintF(" - decoding took %0.3f ms\n", ms);
    157       }
    158       TRACE("wasm-decode ok\n\n");
    159     } else {
    160       TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_),
    161             startrel(error_pc_), error_msg_.get());
    162     }
    163     return toResult(tree);
    164   }
    165 
    166  private:
    167   static const size_t kErrorMsgSize = 128;
    168 
    169   Zone* zone_;
    170   TFBuilder* builder_;
    171   const byte* base_;
    172   TreeResult result_;
    173 
    174   SsaEnv* ssa_env_;
    175   FunctionEnv* function_env_;
    176 
    177   ZoneVector<Tree*> trees_;
    178   ZoneVector<Production> stack_;
    179   ZoneVector<Block> blocks_;
    180   ZoneVector<IfEnv> ifs_;
    181 
    182   inline bool build() { return builder_ && ssa_env_->go(); }
    183 
    184   void InitSsaEnv() {
    185     FunctionSig* sig = function_env_->sig;
    186     int param_count = static_cast<int>(sig->parameter_count());
    187     TFNode* start = nullptr;
    188     SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
    189     size_t size = sizeof(TFNode*) * EnvironmentCount();
    190     ssa_env->state = SsaEnv::kReached;
    191     ssa_env->locals =
    192         size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr;
    193 
    194     int pos = 0;
    195     if (builder_) {
    196       start = builder_->Start(param_count + 1);
    197       // Initialize parameters.
    198       for (int i = 0; i < param_count; i++) {
    199         ssa_env->locals[pos++] = builder_->Param(i, sig->GetParam(i));
    200       }
    201       // Initialize int32 locals.
    202       if (function_env_->local_int32_count > 0) {
    203         TFNode* zero = builder_->Int32Constant(0);
    204         for (uint32_t i = 0; i < function_env_->local_int32_count; i++) {
    205           ssa_env->locals[pos++] = zero;
    206         }
    207       }
    208       // Initialize int64 locals.
    209       if (function_env_->local_int64_count > 0) {
    210         TFNode* zero = builder_->Int64Constant(0);
    211         for (uint32_t i = 0; i < function_env_->local_int64_count; i++) {
    212           ssa_env->locals[pos++] = zero;
    213         }
    214       }
    215       // Initialize float32 locals.
    216       if (function_env_->local_float32_count > 0) {
    217         TFNode* zero = builder_->Float32Constant(0);
    218         for (uint32_t i = 0; i < function_env_->local_float32_count; i++) {
    219           ssa_env->locals[pos++] = zero;
    220         }
    221       }
    222       // Initialize float64 locals.
    223       if (function_env_->local_float64_count > 0) {
    224         TFNode* zero = builder_->Float64Constant(0);
    225         for (uint32_t i = 0; i < function_env_->local_float64_count; i++) {
    226           ssa_env->locals[pos++] = zero;
    227         }
    228       }
    229       DCHECK_EQ(function_env_->total_locals, pos);
    230       DCHECK_EQ(EnvironmentCount(), pos);
    231       builder_->set_module(function_env_->module);
    232     }
    233     ssa_env->control = start;
    234     ssa_env->effect = start;
    235     SetEnv("initial", ssa_env);
    236   }
    237 
    238   void Leaf(LocalType type, TFNode* node = nullptr) {
    239     size_t size = sizeof(Tree);
    240     Tree* tree = reinterpret_cast<Tree*>(zone_->New(size));
    241     tree->type = type;
    242     tree->count = 0;
    243     tree->pc = pc_;
    244     tree->node = node;
    245     tree->children[0] = nullptr;
    246     Reduce(tree);
    247   }
    248 
    249   void Shift(LocalType type, uint32_t count) {
    250     size_t size =
    251         sizeof(Tree) + (count == 0 ? 0 : ((count - 1) * sizeof(Tree*)));
    252     Tree* tree = reinterpret_cast<Tree*>(zone_->New(size));
    253     tree->type = type;
    254     tree->count = count;
    255     tree->pc = pc_;
    256     tree->node = nullptr;
    257     for (uint32_t i = 0; i < count; i++) tree->children[i] = nullptr;
    258     if (count == 0) {
    259       Production p = {tree, 0};
    260       Reduce(&p);
    261       Reduce(tree);
    262     } else {
    263       stack_.push_back({tree, 0});
    264     }
    265   }
    266 
    267   void Reduce(Tree* tree) {
    268     while (true) {
    269       if (stack_.size() == 0) {
    270         trees_.push_back(tree);
    271         break;
    272       }
    273       Production* p = &stack_.back();
    274       p->tree->children[p->index++] = tree;
    275       Reduce(p);
    276       if (p->done()) {
    277         tree = p->tree;
    278         stack_.pop_back();
    279       } else {
    280         break;
    281       }
    282     }
    283   }
    284 
    285   char* indentation() {
    286     static const int kMaxIndent = 64;
    287     static char bytes[kMaxIndent + 1];
    288     for (int i = 0; i < kMaxIndent; i++) bytes[i] = ' ';
    289     bytes[kMaxIndent] = 0;
    290     if (stack_.size() < kMaxIndent / 2) {
    291       bytes[stack_.size() * 2] = 0;
    292     }
    293     return bytes;
    294   }
    295 
    296   // Decodes the body of a function, producing reduced trees into {result}.
    297   void DecodeFunctionBody() {
    298     TRACE("wasm-decode %p...%p (%d bytes) %s\n",
    299           reinterpret_cast<const void*>(start_),
    300           reinterpret_cast<const void*>(limit_),
    301           static_cast<int>(limit_ - start_), builder_ ? "graph building" : "");
    302 
    303     if (pc_ >= limit_) return;  // Nothing to do.
    304 
    305     while (true) {  // decoding loop.
    306       int len = 1;
    307       WasmOpcode opcode = static_cast<WasmOpcode>(*pc_);
    308       TRACE("wasm-decode module+%-6d %s func+%d: 0x%02x %s\n", baserel(pc_),
    309             indentation(), startrel(pc_), opcode,
    310             WasmOpcodes::OpcodeName(opcode));
    311 
    312       FunctionSig* sig = WasmOpcodes::Signature(opcode);
    313       if (sig) {
    314         // A simple expression with a fixed signature.
    315         Shift(sig->GetReturn(), static_cast<uint32_t>(sig->parameter_count()));
    316         pc_ += len;
    317         if (pc_ >= limit_) {
    318           // End of code reached or exceeded.
    319           if (pc_ > limit_ && ok()) {
    320             error("Beyond end of code");
    321           }
    322           return;
    323         }
    324         continue;  // back to decoding loop.
    325       }
    326 
    327       switch (opcode) {
    328         case kExprNop:
    329           Leaf(kAstStmt);
    330           break;
    331         case kExprBlock: {
    332           int length = Operand<uint8_t>(pc_);
    333           if (length < 1) {
    334             Leaf(kAstStmt);
    335           } else {
    336             Shift(kAstEnd, length);
    337             // The break environment is the outer environment.
    338             SsaEnv* break_env = ssa_env_;
    339             PushBlock(break_env);
    340             SetEnv("block:start", Steal(break_env));
    341           }
    342           len = 2;
    343           break;
    344         }
    345         case kExprLoop: {
    346           int length = Operand<uint8_t>(pc_);
    347           if (length < 1) {
    348             Leaf(kAstStmt);
    349           } else {
    350             Shift(kAstEnd, length);
    351             // The break environment is the outer environment.
    352             SsaEnv* break_env = ssa_env_;
    353             PushBlock(break_env);
    354             SsaEnv* cont_env = Steal(break_env);
    355             // The continue environment is the inner environment.
    356             PrepareForLoop(cont_env);
    357             SetEnv("loop:start", Split(cont_env));
    358             if (ssa_env_->go()) ssa_env_->state = SsaEnv::kReached;
    359             PushBlock(cont_env);
    360             blocks_.back().stack_depth = -1;  // no production for inner block.
    361           }
    362           len = 2;
    363           break;
    364         }
    365         case kExprIf:
    366           Shift(kAstStmt, 2);
    367           break;
    368         case kExprIfElse:
    369           Shift(kAstEnd, 3);  // Result type is typeof(x) in {c ? x : y}.
    370           break;
    371         case kExprSelect:
    372           Shift(kAstStmt, 3);  // Result type is typeof(x) in {c ? x : y}.
    373           break;
    374         case kExprBr: {
    375           uint32_t depth = Operand<uint8_t>(pc_);
    376           Shift(kAstEnd, 1);
    377           if (depth >= blocks_.size()) {
    378             error("improperly nested branch");
    379           }
    380           len = 2;
    381           break;
    382         }
    383         case kExprBrIf: {
    384           uint32_t depth = Operand<uint8_t>(pc_);
    385           Shift(kAstStmt, 2);
    386           if (depth >= blocks_.size()) {
    387             error("improperly nested conditional branch");
    388           }
    389           len = 2;
    390           break;
    391         }
    392         case kExprTableSwitch: {
    393           if (!checkAvailable(5)) {
    394             error("expected #tableswitch <cases> <table>, fell off end");
    395             break;
    396           }
    397           uint16_t case_count = *reinterpret_cast<const uint16_t*>(pc_ + 1);
    398           uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc_ + 3);
    399           len = 5 + table_count * 2;
    400 
    401           if (table_count == 0) {
    402             error("tableswitch with 0 entries");
    403             break;
    404           }
    405 
    406           if (!checkAvailable(len)) {
    407             error("expected #tableswitch <cases> <table>, fell off end");
    408             break;
    409           }
    410 
    411           Shift(kAstEnd, 1 + case_count);
    412 
    413           // Verify table.
    414           for (int i = 0; i < table_count; i++) {
    415             uint16_t target =
    416                 *reinterpret_cast<const uint16_t*>(pc_ + 5 + i * 2);
    417             if (target >= 0x8000) {
    418               size_t depth = target - 0x8000;
    419               if (depth > blocks_.size()) {
    420                 error(pc_ + 5 + i * 2, "improper branch in tableswitch");
    421               }
    422             } else {
    423               if (target >= case_count) {
    424                 error(pc_ + 5 + i * 2, "invalid case target in tableswitch");
    425               }
    426             }
    427           }
    428           break;
    429         }
    430         case kExprReturn: {
    431           int count = static_cast<int>(function_env_->sig->return_count());
    432           if (count == 0) {
    433             BUILD(Return, 0, builder_->Buffer(0));
    434             ssa_env_->Kill();
    435             Leaf(kAstEnd);
    436           } else {
    437             Shift(kAstEnd, count);
    438           }
    439           break;
    440         }
    441         case kExprUnreachable: {
    442           BUILD0(Unreachable);
    443           ssa_env_->Kill(SsaEnv::kControlEnd);
    444           Leaf(kAstEnd, nullptr);
    445           break;
    446         }
    447         case kExprI8Const: {
    448           int32_t value = Operand<int8_t>(pc_);
    449           Leaf(kAstI32, BUILD(Int32Constant, value));
    450           len = 2;
    451           break;
    452         }
    453         case kExprI32Const: {
    454           int32_t value = Operand<int32_t>(pc_);
    455           Leaf(kAstI32, BUILD(Int32Constant, value));
    456           len = 5;
    457           break;
    458         }
    459         case kExprI64Const: {
    460           int64_t value = Operand<int64_t>(pc_);
    461           Leaf(kAstI64, BUILD(Int64Constant, value));
    462           len = 9;
    463           break;
    464         }
    465         case kExprF32Const: {
    466           float value = Operand<float>(pc_);
    467           Leaf(kAstF32, BUILD(Float32Constant, value));
    468           len = 5;
    469           break;
    470         }
    471         case kExprF64Const: {
    472           double value = Operand<double>(pc_);
    473           Leaf(kAstF64, BUILD(Float64Constant, value));
    474           len = 9;
    475           break;
    476         }
    477         case kExprGetLocal: {
    478           uint32_t index;
    479           LocalType type = LocalOperand(pc_, &index, &len);
    480           TFNode* val =
    481               build() && type != kAstStmt ? ssa_env_->locals[index] : nullptr;
    482           Leaf(type, val);
    483           break;
    484         }
    485         case kExprSetLocal: {
    486           uint32_t index;
    487           LocalType type = LocalOperand(pc_, &index, &len);
    488           Shift(type, 1);
    489           break;
    490         }
    491         case kExprLoadGlobal: {
    492           uint32_t index;
    493           LocalType type = GlobalOperand(pc_, &index, &len);
    494           Leaf(type, BUILD(LoadGlobal, index));
    495           break;
    496         }
    497         case kExprStoreGlobal: {
    498           uint32_t index;
    499           LocalType type = GlobalOperand(pc_, &index, &len);
    500           Shift(type, 1);
    501           break;
    502         }
    503         case kExprI32LoadMem8S:
    504         case kExprI32LoadMem8U:
    505         case kExprI32LoadMem16S:
    506         case kExprI32LoadMem16U:
    507         case kExprI32LoadMem:
    508           len = DecodeLoadMem(pc_, kAstI32);
    509           break;
    510         case kExprI64LoadMem8S:
    511         case kExprI64LoadMem8U:
    512         case kExprI64LoadMem16S:
    513         case kExprI64LoadMem16U:
    514         case kExprI64LoadMem32S:
    515         case kExprI64LoadMem32U:
    516         case kExprI64LoadMem:
    517           len = DecodeLoadMem(pc_, kAstI64);
    518           break;
    519         case kExprF32LoadMem:
    520           len = DecodeLoadMem(pc_, kAstF32);
    521           break;
    522         case kExprF64LoadMem:
    523           len = DecodeLoadMem(pc_, kAstF64);
    524           break;
    525         case kExprI32StoreMem8:
    526         case kExprI32StoreMem16:
    527         case kExprI32StoreMem:
    528           len = DecodeStoreMem(pc_, kAstI32);
    529           break;
    530         case kExprI64StoreMem8:
    531         case kExprI64StoreMem16:
    532         case kExprI64StoreMem32:
    533         case kExprI64StoreMem:
    534           len = DecodeStoreMem(pc_, kAstI64);
    535           break;
    536         case kExprF32StoreMem:
    537           len = DecodeStoreMem(pc_, kAstF32);
    538           break;
    539         case kExprF64StoreMem:
    540           len = DecodeStoreMem(pc_, kAstF64);
    541           break;
    542         case kExprMemorySize:
    543           Leaf(kAstI32, BUILD(MemSize, 0));
    544           break;
    545         case kExprGrowMemory:
    546           Shift(kAstI32, 1);
    547           break;
    548         case kExprCallFunction: {
    549           uint32_t unused;
    550           FunctionSig* sig = FunctionSigOperand(pc_, &unused, &len);
    551           if (sig) {
    552             LocalType type =
    553                 sig->return_count() == 0 ? kAstStmt : sig->GetReturn();
    554             Shift(type, static_cast<int>(sig->parameter_count()));
    555           } else {
    556             Leaf(kAstI32);  // error
    557           }
    558           break;
    559         }
    560         case kExprCallIndirect: {
    561           uint32_t unused;
    562           FunctionSig* sig = SigOperand(pc_, &unused, &len);
    563           if (sig) {
    564             LocalType type =
    565                 sig->return_count() == 0 ? kAstStmt : sig->GetReturn();
    566             Shift(type, static_cast<int>(1 + sig->parameter_count()));
    567           } else {
    568             Leaf(kAstI32);  // error
    569           }
    570           break;
    571         }
    572         default:
    573           error("Invalid opcode");
    574           return;
    575       }
    576       pc_ += len;
    577       if (pc_ >= limit_) {
    578         // End of code reached or exceeded.
    579         if (pc_ > limit_ && ok()) {
    580           error("Beyond end of code");
    581         }
    582         return;
    583       }
    584     }
    585   }
    586 
    587   void PushBlock(SsaEnv* ssa_env) {
    588     blocks_.push_back({ssa_env, static_cast<int>(stack_.size() - 1)});
    589   }
    590 
    591   int DecodeLoadMem(const byte* pc, LocalType type) {
    592     int length = 2;
    593     uint32_t offset;
    594     MemoryAccessOperand(pc, &length, &offset);
    595     Shift(type, 1);
    596     return length;
    597   }
    598 
    599   int DecodeStoreMem(const byte* pc, LocalType type) {
    600     int length = 2;
    601     uint32_t offset;
    602     MemoryAccessOperand(pc, &length, &offset);
    603     Shift(type, 2);
    604     return length;
    605   }
    606 
    607   void AddImplicitReturnAtEnd() {
    608     int retcount = static_cast<int>(function_env_->sig->return_count());
    609     if (retcount == 0) {
    610       BUILD0(ReturnVoid);
    611       return;
    612     }
    613 
    614     if (static_cast<int>(trees_.size()) < retcount) {
    615       error(limit_, nullptr,
    616             "ImplicitReturn expects %d arguments, only %d remain", retcount,
    617             static_cast<int>(trees_.size()));
    618       return;
    619     }
    620 
    621     TRACE("wasm-decode implicit return of %d args\n", retcount);
    622 
    623     TFNode** buffer = BUILD(Buffer, retcount);
    624     for (int index = 0; index < retcount; index++) {
    625       Tree* tree = trees_[trees_.size() - 1 - index];
    626       if (buffer) buffer[index] = tree->node;
    627       LocalType expected = function_env_->sig->GetReturn(index);
    628       if (tree->type != expected) {
    629         error(limit_, tree->pc,
    630               "ImplicitReturn[%d] expected type %s, found %s of type %s", index,
    631               WasmOpcodes::TypeName(expected),
    632               WasmOpcodes::OpcodeName(tree->opcode()),
    633               WasmOpcodes::TypeName(tree->type));
    634         return;
    635       }
    636     }
    637 
    638     BUILD(Return, retcount, buffer);
    639   }
    640 
    641   int baserel(const byte* ptr) {
    642     return base_ ? static_cast<int>(ptr - base_) : 0;
    643   }
    644 
    645   int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); }
    646 
    647   void Reduce(Production* p) {
    648     WasmOpcode opcode = p->opcode();
    649     TRACE("-----reduce module+%-6d %s func+%d: 0x%02x %s\n", baserel(p->pc()),
    650           indentation(), startrel(p->pc()), opcode,
    651           WasmOpcodes::OpcodeName(opcode));
    652     FunctionSig* sig = WasmOpcodes::Signature(opcode);
    653     if (sig) {
    654       // A simple expression with a fixed signature.
    655       TypeCheckLast(p, sig->GetParam(p->index - 1));
    656       if (p->done() && build()) {
    657         if (sig->parameter_count() == 2) {
    658           p->tree->node = builder_->Binop(opcode, p->tree->children[0]->node,
    659                                           p->tree->children[1]->node);
    660         } else if (sig->parameter_count() == 1) {
    661           p->tree->node = builder_->Unop(opcode, p->tree->children[0]->node);
    662         } else {
    663           UNREACHABLE();
    664         }
    665       }
    666       return;
    667     }
    668 
    669     switch (opcode) {
    670       case kExprBlock: {
    671         if (p->done()) {
    672           Block* last = &blocks_.back();
    673           DCHECK_EQ(stack_.size() - 1, last->stack_depth);
    674           // fallthrough with the last expression.
    675           ReduceBreakToExprBlock(p, last);
    676           SetEnv("block:end", last->ssa_env);
    677           blocks_.pop_back();
    678         }
    679         break;
    680       }
    681       case kExprLoop: {
    682         if (p->done()) {
    683           // Pop the continue environment.
    684           blocks_.pop_back();
    685           // Get the break environment.
    686           Block* last = &blocks_.back();
    687           DCHECK_EQ(stack_.size() - 1, last->stack_depth);
    688           // fallthrough with the last expression.
    689           ReduceBreakToExprBlock(p, last);
    690           SetEnv("loop:end", last->ssa_env);
    691           blocks_.pop_back();
    692         }
    693         break;
    694       }
    695       case kExprIf: {
    696         if (p->index == 1) {
    697           // Condition done. Split environment for true branch.
    698           TypeCheckLast(p, kAstI32);
    699           SsaEnv* false_env = ssa_env_;
    700           SsaEnv* true_env = Split(ssa_env_);
    701           ifs_.push_back({nullptr, false_env, nullptr});
    702           BUILD(Branch, p->last()->node, &true_env->control,
    703                 &false_env->control);
    704           SetEnv("if:true", true_env);
    705         } else if (p->index == 2) {
    706           // True block done. Merge true and false environments.
    707           IfEnv* env = &ifs_.back();
    708           SsaEnv* merge = env->merge_env;
    709           if (merge->go()) {
    710             merge->state = SsaEnv::kReached;
    711             Goto(ssa_env_, merge);
    712           }
    713           SetEnv("if:merge", merge);
    714           ifs_.pop_back();
    715         }
    716         break;
    717       }
    718       case kExprIfElse: {
    719         if (p->index == 1) {
    720           // Condition done. Split environment for true and false branches.
    721           TypeCheckLast(p, kAstI32);
    722           SsaEnv* merge_env = ssa_env_;
    723           TFNode* if_true = nullptr;
    724           TFNode* if_false = nullptr;
    725           BUILD(Branch, p->last()->node, &if_true, &if_false);
    726           SsaEnv* false_env = Split(ssa_env_);
    727           SsaEnv* true_env = Steal(ssa_env_);
    728           false_env->control = if_false;
    729           true_env->control = if_true;
    730           ifs_.push_back({false_env, merge_env, nullptr});
    731           SetEnv("if_else:true", true_env);
    732         } else if (p->index == 2) {
    733           // True expr done.
    734           IfEnv* env = &ifs_.back();
    735           MergeIntoProduction(p, env->merge_env, p->last());
    736           // Switch to environment for false branch.
    737           SsaEnv* false_env = ifs_.back().false_env;
    738           SetEnv("if_else:false", false_env);
    739         } else if (p->index == 3) {
    740           // False expr done.
    741           IfEnv* env = &ifs_.back();
    742           MergeIntoProduction(p, env->merge_env, p->last());
    743           SetEnv("if_else:merge", env->merge_env);
    744           ifs_.pop_back();
    745         }
    746         break;
    747       }
    748       case kExprSelect: {
    749         if (p->index == 1) {
    750           // Condition done.
    751           TypeCheckLast(p, kAstI32);
    752         } else if (p->index == 2) {
    753           // True expression done.
    754           p->tree->type = p->last()->type;
    755           if (p->tree->type == kAstStmt) {
    756             error(p->pc(), p->tree->children[1]->pc,
    757                   "select operand should be expression");
    758           }
    759         } else {
    760           // False expression done.
    761           DCHECK(p->done());
    762           TypeCheckLast(p, p->tree->type);
    763           if (build()) {
    764             TFNode* controls[2];
    765             builder_->Branch(p->tree->children[0]->node, &controls[0],
    766                              &controls[1]);
    767             TFNode* merge = builder_->Merge(2, controls);
    768             TFNode* vals[2] = {p->tree->children[1]->node,
    769                                p->tree->children[2]->node};
    770             TFNode* phi = builder_->Phi(p->tree->type, 2, vals, merge);
    771             p->tree->node = phi;
    772             ssa_env_->control = merge;
    773           }
    774         }
    775         break;
    776       }
    777       case kExprBr: {
    778         uint32_t depth = Operand<uint8_t>(p->pc());
    779         if (depth >= blocks_.size()) {
    780           error("improperly nested branch");
    781           break;
    782         }
    783         Block* block = &blocks_[blocks_.size() - depth - 1];
    784         ReduceBreakToExprBlock(p, block);
    785         break;
    786       }
    787       case kExprBrIf: {
    788         if (p->index == 1) {
    789           TypeCheckLast(p, kAstI32);
    790         } else if (p->done()) {
    791           uint32_t depth = Operand<uint8_t>(p->pc());
    792           if (depth >= blocks_.size()) {
    793             error("improperly nested branch");
    794             break;
    795           }
    796           Block* block = &blocks_[blocks_.size() - depth - 1];
    797           SsaEnv* fenv = ssa_env_;
    798           SsaEnv* tenv = Split(fenv);
    799           BUILD(Branch, p->tree->children[0]->node, &tenv->control,
    800                 &fenv->control);
    801           ssa_env_ = tenv;
    802           ReduceBreakToExprBlock(p, block);
    803           ssa_env_ = fenv;
    804         }
    805         break;
    806       }
    807       case kExprTableSwitch: {
    808         uint16_t table_count = *reinterpret_cast<const uint16_t*>(p->pc() + 3);
    809         if (table_count == 1) {
    810           // Degenerate switch with only a default target.
    811           if (p->index == 1) {
    812             SsaEnv* break_env = ssa_env_;
    813             PushBlock(break_env);
    814             SetEnv("switch:default", Steal(break_env));
    815           }
    816           if (p->done()) {
    817             Block* block = &blocks_.back();
    818             // fall through to the end.
    819             ReduceBreakToExprBlock(p, block);
    820             SetEnv("switch:end", block->ssa_env);
    821             blocks_.pop_back();
    822           }
    823           break;
    824         }
    825 
    826         if (p->index == 1) {
    827           // Switch key finished.
    828           TypeCheckLast(p, kAstI32);
    829 
    830           TFNode* sw = BUILD(Switch, table_count, p->last()->node);
    831 
    832           // Allocate environments for each case.
    833           uint16_t case_count = *reinterpret_cast<const uint16_t*>(p->pc() + 1);
    834           SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count);
    835           for (int i = 0; i < case_count; i++) {
    836             case_envs[i] = UnreachableEnv();
    837           }
    838 
    839           ifs_.push_back({nullptr, nullptr, case_envs});
    840           SsaEnv* break_env = ssa_env_;
    841           PushBlock(break_env);
    842           SsaEnv* copy = Steal(break_env);
    843           ssa_env_ = copy;
    844 
    845           // Build the environments for each case based on the table.
    846           const uint16_t* table =
    847               reinterpret_cast<const uint16_t*>(p->pc() + 5);
    848           for (int i = 0; i < table_count; i++) {
    849             uint16_t target = table[i];
    850             SsaEnv* env = Split(copy);
    851             env->control = (i == table_count - 1) ? BUILD(IfDefault, sw)
    852                                                   : BUILD(IfValue, i, sw);
    853             if (target >= 0x8000) {
    854               // Targets an outer block.
    855               int depth = target - 0x8000;
    856               SsaEnv* tenv = blocks_[blocks_.size() - depth - 1].ssa_env;
    857               Goto(env, tenv);
    858             } else {
    859               // Targets a case.
    860               Goto(env, case_envs[target]);
    861             }
    862           }
    863 
    864           // Switch to the environment for the first case.
    865           SetEnv("switch:case", case_envs[0]);
    866         } else {
    867           // Switch case finished.
    868           if (p->done()) {
    869             // Last case. Fall through to the end.
    870             Block* block = &blocks_.back();
    871             ReduceBreakToExprBlock(p, block);
    872             SsaEnv* next = block->ssa_env;
    873             blocks_.pop_back();
    874             ifs_.pop_back();
    875             SetEnv("switch:end", next);
    876           } else {
    877             // Interior case. Maybe fall through to the next case.
    878             SsaEnv* next = ifs_.back().case_envs[p->index - 1];
    879             if (ssa_env_->go()) Goto(ssa_env_, next);
    880             SetEnv("switch:case", next);
    881           }
    882         }
    883         break;
    884       }
    885       case kExprReturn: {
    886         TypeCheckLast(p, function_env_->sig->GetReturn(p->index - 1));
    887         if (p->done()) {
    888           if (build()) {
    889             int count = p->tree->count;
    890             TFNode** buffer = builder_->Buffer(count);
    891             for (int i = 0; i < count; i++) {
    892               buffer[i] = p->tree->children[i]->node;
    893             }
    894             BUILD(Return, count, buffer);
    895           }
    896           ssa_env_->Kill(SsaEnv::kControlEnd);
    897         }
    898         break;
    899       }
    900       case kExprSetLocal: {
    901         int unused = 0;
    902         uint32_t index;
    903         LocalType type = LocalOperand(p->pc(), &index, &unused);
    904         Tree* val = p->last();
    905         if (type == val->type) {
    906           if (build()) ssa_env_->locals[index] = val->node;
    907           p->tree->node = val->node;
    908         } else {
    909           error(p->pc(), val->pc, "Typecheck failed in SetLocal");
    910         }
    911         break;
    912       }
    913       case kExprStoreGlobal: {
    914         int unused = 0;
    915         uint32_t index;
    916         LocalType type = GlobalOperand(p->pc(), &index, &unused);
    917         Tree* val = p->last();
    918         if (type == val->type) {
    919           BUILD(StoreGlobal, index, val->node);
    920           p->tree->node = val->node;
    921         } else {
    922           error(p->pc(), val->pc, "Typecheck failed in StoreGlobal");
    923         }
    924         break;
    925       }
    926 
    927       case kExprI32LoadMem8S:
    928         return ReduceLoadMem(p, kAstI32, MachineType::Int8());
    929       case kExprI32LoadMem8U:
    930         return ReduceLoadMem(p, kAstI32, MachineType::Uint8());
    931       case kExprI32LoadMem16S:
    932         return ReduceLoadMem(p, kAstI32, MachineType::Int16());
    933       case kExprI32LoadMem16U:
    934         return ReduceLoadMem(p, kAstI32, MachineType::Uint16());
    935       case kExprI32LoadMem:
    936         return ReduceLoadMem(p, kAstI32, MachineType::Int32());
    937 
    938       case kExprI64LoadMem8S:
    939         return ReduceLoadMem(p, kAstI64, MachineType::Int8());
    940       case kExprI64LoadMem8U:
    941         return ReduceLoadMem(p, kAstI64, MachineType::Uint8());
    942       case kExprI64LoadMem16S:
    943         return ReduceLoadMem(p, kAstI64, MachineType::Int16());
    944       case kExprI64LoadMem16U:
    945         return ReduceLoadMem(p, kAstI64, MachineType::Uint16());
    946       case kExprI64LoadMem32S:
    947         return ReduceLoadMem(p, kAstI64, MachineType::Int32());
    948       case kExprI64LoadMem32U:
    949         return ReduceLoadMem(p, kAstI64, MachineType::Uint32());
    950       case kExprI64LoadMem:
    951         return ReduceLoadMem(p, kAstI64, MachineType::Int64());
    952 
    953       case kExprF32LoadMem:
    954         return ReduceLoadMem(p, kAstF32, MachineType::Float32());
    955 
    956       case kExprF64LoadMem:
    957         return ReduceLoadMem(p, kAstF64, MachineType::Float64());
    958 
    959       case kExprI32StoreMem8:
    960         return ReduceStoreMem(p, kAstI32, MachineType::Int8());
    961       case kExprI32StoreMem16:
    962         return ReduceStoreMem(p, kAstI32, MachineType::Int16());
    963       case kExprI32StoreMem:
    964         return ReduceStoreMem(p, kAstI32, MachineType::Int32());
    965 
    966       case kExprI64StoreMem8:
    967         return ReduceStoreMem(p, kAstI64, MachineType::Int8());
    968       case kExprI64StoreMem16:
    969         return ReduceStoreMem(p, kAstI64, MachineType::Int16());
    970       case kExprI64StoreMem32:
    971         return ReduceStoreMem(p, kAstI64, MachineType::Int32());
    972       case kExprI64StoreMem:
    973         return ReduceStoreMem(p, kAstI64, MachineType::Int64());
    974 
    975       case kExprF32StoreMem:
    976         return ReduceStoreMem(p, kAstF32, MachineType::Float32());
    977 
    978       case kExprF64StoreMem:
    979         return ReduceStoreMem(p, kAstF64, MachineType::Float64());
    980 
    981       case kExprGrowMemory:
    982         TypeCheckLast(p, kAstI32);
    983         // TODO(titzer): build node for GrowMemory
    984         p->tree->node = BUILD(Int32Constant, 0);
    985         return;
    986 
    987       case kExprCallFunction: {
    988         int len;
    989         uint32_t index;
    990         FunctionSig* sig = FunctionSigOperand(p->pc(), &index, &len);
    991         if (!sig) break;
    992         if (p->index > 0) {
    993           TypeCheckLast(p, sig->GetParam(p->index - 1));
    994         }
    995         if (p->done() && build()) {
    996           uint32_t count = p->tree->count + 1;
    997           TFNode** buffer = builder_->Buffer(count);
    998           FunctionSig* sig = FunctionSigOperand(p->pc(), &index, &len);
    999           USE(sig);
   1000           buffer[0] = nullptr;  // reserved for code object.
   1001           for (uint32_t i = 1; i < count; i++) {
   1002             buffer[i] = p->tree->children[i - 1]->node;
   1003           }
   1004           p->tree->node = builder_->CallDirect(index, buffer);
   1005         }
   1006         break;
   1007       }
   1008       case kExprCallIndirect: {
   1009         int len;
   1010         uint32_t index;
   1011         FunctionSig* sig = SigOperand(p->pc(), &index, &len);
   1012         if (p->index == 1) {
   1013           TypeCheckLast(p, kAstI32);
   1014         } else {
   1015           TypeCheckLast(p, sig->GetParam(p->index - 2));
   1016         }
   1017         if (p->done() && build()) {
   1018           uint32_t count = p->tree->count;
   1019           TFNode** buffer = builder_->Buffer(count);
   1020           for (uint32_t i = 0; i < count; i++) {
   1021             buffer[i] = p->tree->children[i]->node;
   1022           }
   1023           p->tree->node = builder_->CallIndirect(index, buffer);
   1024         }
   1025         break;
   1026       }
   1027       default:
   1028         break;
   1029     }
   1030   }
   1031 
   1032   void ReduceBreakToExprBlock(Production* p, Block* block) {
   1033     if (block->stack_depth < 0) {
   1034       // This is the inner loop block, which does not have a value.
   1035       Goto(ssa_env_, block->ssa_env);
   1036     } else {
   1037       // Merge the value into the production for the block.
   1038       Production* bp = &stack_[block->stack_depth];
   1039       MergeIntoProduction(bp, block->ssa_env, p->last());
   1040     }
   1041   }
   1042 
   1043   void MergeIntoProduction(Production* p, SsaEnv* target, Tree* expr) {
   1044     if (!ssa_env_->go()) return;
   1045 
   1046     bool first = target->state == SsaEnv::kUnreachable;
   1047     Goto(ssa_env_, target);
   1048     if (expr->type == kAstEnd) return;
   1049 
   1050     if (first) {
   1051       // first merge to this environment; set the type and the node.
   1052       p->tree->type = expr->type;
   1053       p->tree->node = expr->node;
   1054     } else {
   1055       // merge with the existing value for this block.
   1056       LocalType type = p->tree->type;
   1057       if (expr->type != type) {
   1058         type = kAstStmt;
   1059         p->tree->type = kAstStmt;
   1060         p->tree->node = nullptr;
   1061       } else if (type != kAstStmt) {
   1062         p->tree->node = CreateOrMergeIntoPhi(type, target->control,
   1063                                              p->tree->node, expr->node);
   1064       }
   1065     }
   1066   }
   1067 
   1068   void ReduceLoadMem(Production* p, LocalType type, MachineType mem_type) {
   1069     DCHECK_EQ(1, p->index);
   1070     TypeCheckLast(p, kAstI32);  // index
   1071     if (build()) {
   1072       int length = 0;
   1073       uint32_t offset = 0;
   1074       MemoryAccessOperand(p->pc(), &length, &offset);
   1075       p->tree->node =
   1076           builder_->LoadMem(type, mem_type, p->last()->node, offset);
   1077     }
   1078   }
   1079 
   1080   void ReduceStoreMem(Production* p, LocalType type, MachineType mem_type) {
   1081     if (p->index == 1) {
   1082       TypeCheckLast(p, kAstI32);  // index
   1083     } else {
   1084       DCHECK_EQ(2, p->index);
   1085       TypeCheckLast(p, type);
   1086       if (build()) {
   1087         int length = 0;
   1088         uint32_t offset = 0;
   1089         MemoryAccessOperand(p->pc(), &length, &offset);
   1090         TFNode* val = p->tree->children[1]->node;
   1091         builder_->StoreMem(mem_type, p->tree->children[0]->node, offset, val);
   1092         p->tree->node = val;
   1093       }
   1094     }
   1095   }
   1096 
   1097   void TypeCheckLast(Production* p, LocalType expected) {
   1098     LocalType result = p->last()->type;
   1099     if (result == expected) return;
   1100     if (result == kAstEnd) return;
   1101     if (expected != kAstStmt) {
   1102       error(p->pc(), p->last()->pc,
   1103             "%s[%d] expected type %s, found %s of type %s",
   1104             WasmOpcodes::OpcodeName(p->opcode()), p->index - 1,
   1105             WasmOpcodes::TypeName(expected),
   1106             WasmOpcodes::OpcodeName(p->last()->opcode()),
   1107             WasmOpcodes::TypeName(p->last()->type));
   1108     }
   1109   }
   1110 
   1111   void SetEnv(const char* reason, SsaEnv* env) {
   1112     TRACE("  env = %p, block depth = %d, reason = %s", static_cast<void*>(env),
   1113           static_cast<int>(blocks_.size()), reason);
   1114     if (env->control != nullptr && FLAG_trace_wasm_decoder) {
   1115       TRACE(", control = ");
   1116       compiler::WasmGraphBuilder::PrintDebugName(env->control);
   1117     }
   1118     TRACE("\n");
   1119     ssa_env_ = env;
   1120     if (builder_) {
   1121       builder_->set_control_ptr(&env->control);
   1122       builder_->set_effect_ptr(&env->effect);
   1123     }
   1124   }
   1125 
   1126   void Goto(SsaEnv* from, SsaEnv* to) {
   1127     DCHECK_NOT_NULL(to);
   1128     if (!from->go()) return;
   1129     switch (to->state) {
   1130       case SsaEnv::kUnreachable: {  // Overwrite destination.
   1131         to->state = SsaEnv::kReached;
   1132         to->locals = from->locals;
   1133         to->control = from->control;
   1134         to->effect = from->effect;
   1135         break;
   1136       }
   1137       case SsaEnv::kReached: {  // Create a new merge.
   1138         to->state = SsaEnv::kMerged;
   1139         if (!builder_) break;
   1140         // Merge control.
   1141         TFNode* controls[] = {to->control, from->control};
   1142         TFNode* merge = builder_->Merge(2, controls);
   1143         to->control = merge;
   1144         // Merge effects.
   1145         if (from->effect != to->effect) {
   1146           TFNode* effects[] = {to->effect, from->effect, merge};
   1147           to->effect = builder_->EffectPhi(2, effects, merge);
   1148         }
   1149         // Merge SSA values.
   1150         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1151           TFNode* a = to->locals[i];
   1152           TFNode* b = from->locals[i];
   1153           if (a != b) {
   1154             TFNode* vals[] = {a, b};
   1155             to->locals[i] =
   1156                 builder_->Phi(function_env_->GetLocalType(i), 2, vals, merge);
   1157           }
   1158         }
   1159         break;
   1160       }
   1161       case SsaEnv::kMerged: {
   1162         if (!builder_) break;
   1163         TFNode* merge = to->control;
   1164         // Extend the existing merge.
   1165         builder_->AppendToMerge(merge, from->control);
   1166         // Merge effects.
   1167         if (builder_->IsPhiWithMerge(to->effect, merge)) {
   1168           builder_->AppendToPhi(merge, to->effect, from->effect);
   1169         } else if (to->effect != from->effect) {
   1170           uint32_t count = builder_->InputCount(merge);
   1171           TFNode** effects = builder_->Buffer(count);
   1172           for (uint32_t j = 0; j < count - 1; j++) {
   1173             effects[j] = to->effect;
   1174           }
   1175           effects[count - 1] = from->effect;
   1176           to->effect = builder_->EffectPhi(count, effects, merge);
   1177         }
   1178         // Merge locals.
   1179         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1180           TFNode* tnode = to->locals[i];
   1181           TFNode* fnode = from->locals[i];
   1182           if (builder_->IsPhiWithMerge(tnode, merge)) {
   1183             builder_->AppendToPhi(merge, tnode, fnode);
   1184           } else if (tnode != fnode) {
   1185             uint32_t count = builder_->InputCount(merge);
   1186             TFNode** vals = builder_->Buffer(count);
   1187             for (uint32_t j = 0; j < count - 1; j++) {
   1188               vals[j] = tnode;
   1189             }
   1190             vals[count - 1] = fnode;
   1191             to->locals[i] = builder_->Phi(function_env_->GetLocalType(i), count,
   1192                                           vals, merge);
   1193           }
   1194         }
   1195         break;
   1196       }
   1197       default:
   1198         UNREACHABLE();
   1199     }
   1200     return from->Kill();
   1201   }
   1202 
   1203   TFNode* CreateOrMergeIntoPhi(LocalType type, TFNode* merge, TFNode* tnode,
   1204                                TFNode* fnode) {
   1205     if (builder_->IsPhiWithMerge(tnode, merge)) {
   1206       builder_->AppendToPhi(merge, tnode, fnode);
   1207     } else if (tnode != fnode) {
   1208       uint32_t count = builder_->InputCount(merge);
   1209       TFNode** vals = builder_->Buffer(count);
   1210       for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode;
   1211       vals[count - 1] = fnode;
   1212       return builder_->Phi(type, count, vals, merge);
   1213     }
   1214     return tnode;
   1215   }
   1216 
   1217   void BuildInfiniteLoop() {
   1218     if (ssa_env_->go()) {
   1219       PrepareForLoop(ssa_env_);
   1220       SsaEnv* cont_env = ssa_env_;
   1221       ssa_env_ = Split(ssa_env_);
   1222       ssa_env_->state = SsaEnv::kReached;
   1223       Goto(ssa_env_, cont_env);
   1224     }
   1225   }
   1226 
   1227   void PrepareForLoop(SsaEnv* env) {
   1228     if (env->go()) {
   1229       env->state = SsaEnv::kMerged;
   1230       if (builder_) {
   1231         env->control = builder_->Loop(env->control);
   1232         env->effect = builder_->EffectPhi(1, &env->effect, env->control);
   1233         builder_->Terminate(env->effect, env->control);
   1234         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1235           env->locals[i] = builder_->Phi(function_env_->GetLocalType(i), 1,
   1236                                          &env->locals[i], env->control);
   1237         }
   1238       }
   1239     }
   1240   }
   1241 
   1242   // Create a complete copy of the {from}.
   1243   SsaEnv* Split(SsaEnv* from) {
   1244     DCHECK_NOT_NULL(from);
   1245     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1246     size_t size = sizeof(TFNode*) * EnvironmentCount();
   1247     result->control = from->control;
   1248     result->effect = from->effect;
   1249     result->state = from->state == SsaEnv::kUnreachable ? SsaEnv::kUnreachable
   1250                                                         : SsaEnv::kReached;
   1251 
   1252     if (from->go()) {
   1253       result->state = SsaEnv::kReached;
   1254       result->locals =
   1255           size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr;
   1256       memcpy(result->locals, from->locals, size);
   1257     } else {
   1258       result->state = SsaEnv::kUnreachable;
   1259       result->locals = nullptr;
   1260     }
   1261 
   1262     return result;
   1263   }
   1264 
   1265   // Create a copy of {from} that steals its state and leaves {from}
   1266   // unreachable.
   1267   SsaEnv* Steal(SsaEnv* from) {
   1268     DCHECK_NOT_NULL(from);
   1269     if (!from->go()) return UnreachableEnv();
   1270     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1271     result->state = SsaEnv::kReached;
   1272     result->locals = from->locals;
   1273     result->control = from->control;
   1274     result->effect = from->effect;
   1275     from->Kill(SsaEnv::kUnreachable);
   1276     return result;
   1277   }
   1278 
   1279   // Create an unreachable environment.
   1280   SsaEnv* UnreachableEnv() {
   1281     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1282     result->state = SsaEnv::kUnreachable;
   1283     result->control = nullptr;
   1284     result->effect = nullptr;
   1285     result->locals = nullptr;
   1286     return result;
   1287   }
   1288 
   1289   // Load an operand at [pc + 1].
   1290   template <typename V>
   1291   V Operand(const byte* pc) {
   1292     if ((limit_ - pc) < static_cast<int>(1 + sizeof(V))) {
   1293       const char* msg = "Expected operand following opcode";
   1294       switch (sizeof(V)) {
   1295         case 1:
   1296           msg = "Expected 1-byte operand following opcode";
   1297           break;
   1298         case 2:
   1299           msg = "Expected 2-byte operand following opcode";
   1300           break;
   1301         case 4:
   1302           msg = "Expected 4-byte operand following opcode";
   1303           break;
   1304         default:
   1305           break;
   1306       }
   1307       error(pc, msg);
   1308       return -1;
   1309     }
   1310     return *reinterpret_cast<const V*>(pc + 1);
   1311   }
   1312 
   1313   int EnvironmentCount() {
   1314     if (builder_) return static_cast<int>(function_env_->GetLocalCount());
   1315     return 0;  // if we aren't building a graph, don't bother with SSA renaming.
   1316   }
   1317 
   1318   LocalType LocalOperand(const byte* pc, uint32_t* index, int* length) {
   1319     *index = UnsignedLEB128Operand(pc, length);
   1320     if (function_env_->IsValidLocal(*index)) {
   1321       return function_env_->GetLocalType(*index);
   1322     }
   1323     error(pc, "invalid local variable index");
   1324     return kAstStmt;
   1325   }
   1326 
   1327   LocalType GlobalOperand(const byte* pc, uint32_t* index, int* length) {
   1328     *index = UnsignedLEB128Operand(pc, length);
   1329     if (function_env_->module->IsValidGlobal(*index)) {
   1330       return WasmOpcodes::LocalTypeFor(
   1331           function_env_->module->GetGlobalType(*index));
   1332     }
   1333     error(pc, "invalid global variable index");
   1334     return kAstStmt;
   1335   }
   1336 
   1337   FunctionSig* FunctionSigOperand(const byte* pc, uint32_t* index,
   1338                                   int* length) {
   1339     *index = UnsignedLEB128Operand(pc, length);
   1340     if (function_env_->module->IsValidFunction(*index)) {
   1341       return function_env_->module->GetFunctionSignature(*index);
   1342     }
   1343     error(pc, "invalid function index");
   1344     return nullptr;
   1345   }
   1346 
   1347   FunctionSig* SigOperand(const byte* pc, uint32_t* index, int* length) {
   1348     *index = UnsignedLEB128Operand(pc, length);
   1349     if (function_env_->module->IsValidSignature(*index)) {
   1350       return function_env_->module->GetSignature(*index);
   1351     }
   1352     error(pc, "invalid signature index");
   1353     return nullptr;
   1354   }
   1355 
   1356   uint32_t UnsignedLEB128Operand(const byte* pc, int* length) {
   1357     uint32_t result = 0;
   1358     ReadUnsignedLEB128ErrorCode error_code =
   1359         ReadUnsignedLEB128Operand(pc + 1, limit_, length, &result);
   1360     if (error_code == kInvalidLEB128) error(pc, "invalid LEB128 varint");
   1361     if (error_code == kMissingLEB128) error(pc, "expected LEB128 varint");
   1362     (*length)++;
   1363     return result;
   1364   }
   1365 
   1366   void MemoryAccessOperand(const byte* pc, int* length, uint32_t* offset) {
   1367     byte bitfield = Operand<uint8_t>(pc);
   1368     if (MemoryAccess::OffsetField::decode(bitfield)) {
   1369       *offset = UnsignedLEB128Operand(pc + 1, length);
   1370       (*length)++;  // to account for the memory access byte
   1371     } else {
   1372       *offset = 0;
   1373       *length = 2;
   1374     }
   1375   }
   1376 
   1377   virtual void onFirstError() {
   1378     limit_ = start_;     // Terminate decoding loop.
   1379     builder_ = nullptr;  // Don't build any more nodes.
   1380 #if DEBUG
   1381     PrintStackForDebugging();
   1382 #endif
   1383   }
   1384 
   1385 #if DEBUG
   1386   void PrintStackForDebugging() { PrintProduction(0); }
   1387 
   1388   void PrintProduction(size_t depth) {
   1389     if (depth >= stack_.size()) return;
   1390     Production* p = &stack_[depth];
   1391     for (size_t d = 0; d < depth; d++) PrintF("  ");
   1392 
   1393     PrintF("@%d %s [%d]\n", static_cast<int>(p->tree->pc - start_),
   1394            WasmOpcodes::OpcodeName(p->opcode()), p->tree->count);
   1395     for (int i = 0; i < p->index; i++) {
   1396       Tree* child = p->tree->children[i];
   1397       for (size_t d = 0; d <= depth; d++) PrintF("  ");
   1398       PrintF("@%d %s [%d]", static_cast<int>(child->pc - start_),
   1399              WasmOpcodes::OpcodeName(child->opcode()), child->count);
   1400       if (child->node) {
   1401         PrintF(" => TF");
   1402         compiler::WasmGraphBuilder::PrintDebugName(child->node);
   1403       }
   1404       PrintF("\n");
   1405     }
   1406     PrintProduction(depth + 1);
   1407   }
   1408 #endif
   1409 };
   1410 
   1411 
   1412 TreeResult VerifyWasmCode(FunctionEnv* env, const byte* base, const byte* start,
   1413                           const byte* end) {
   1414   Zone zone;
   1415   LR_WasmDecoder decoder(&zone, nullptr);
   1416   TreeResult result = decoder.Decode(env, base, start, end);
   1417   return result;
   1418 }
   1419 
   1420 
   1421 TreeResult BuildTFGraph(TFBuilder* builder, FunctionEnv* env, const byte* base,
   1422                         const byte* start, const byte* end) {
   1423   Zone zone;
   1424   LR_WasmDecoder decoder(&zone, builder);
   1425   TreeResult result = decoder.Decode(env, base, start, end);
   1426   return result;
   1427 }
   1428 
   1429 
   1430 std::ostream& operator<<(std::ostream& os, const Tree& tree) {
   1431   if (tree.pc == nullptr) {
   1432     os << "null";
   1433     return os;
   1434   }
   1435   PrintF("%s", WasmOpcodes::OpcodeName(tree.opcode()));
   1436   if (tree.count > 0) os << "(";
   1437   for (uint32_t i = 0; i < tree.count; i++) {
   1438     if (i > 0) os << ", ";
   1439     os << *tree.children[i];
   1440   }
   1441   if (tree.count > 0) os << ")";
   1442   return os;
   1443 }
   1444 
   1445 
   1446 ReadUnsignedLEB128ErrorCode ReadUnsignedLEB128Operand(const byte* pc,
   1447                                                       const byte* limit,
   1448                                                       int* length,
   1449                                                       uint32_t* result) {
   1450   *result = 0;
   1451   const byte* ptr = pc;
   1452   const byte* end = pc + 5;  // maximum 5 bytes.
   1453   if (end > limit) end = limit;
   1454   int shift = 0;
   1455   byte b = 0;
   1456   while (ptr < end) {
   1457     b = *ptr++;
   1458     *result = *result | ((b & 0x7F) << shift);
   1459     if ((b & 0x80) == 0) break;
   1460     shift += 7;
   1461   }
   1462   DCHECK_LE(ptr - pc, 5);
   1463   *length = static_cast<int>(ptr - pc);
   1464   if (ptr == end && (b & 0x80)) {
   1465     return kInvalidLEB128;
   1466   } else if (*length == 0) {
   1467     return kMissingLEB128;
   1468   } else {
   1469     return kNoError;
   1470   }
   1471 }
   1472 
   1473 
   1474 int OpcodeLength(const byte* pc) {
   1475   switch (static_cast<WasmOpcode>(*pc)) {
   1476 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1477     FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1478     FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1479 #undef DECLARE_OPCODE_CASE
   1480 
   1481     case kExprI8Const:
   1482     case kExprBlock:
   1483     case kExprLoop:
   1484     case kExprBr:
   1485     case kExprBrIf:
   1486       return 2;
   1487     case kExprI32Const:
   1488     case kExprF32Const:
   1489       return 5;
   1490     case kExprI64Const:
   1491     case kExprF64Const:
   1492       return 9;
   1493     case kExprStoreGlobal:
   1494     case kExprSetLocal:
   1495     case kExprLoadGlobal:
   1496     case kExprCallFunction:
   1497     case kExprCallIndirect:
   1498     case kExprGetLocal: {
   1499       int length;
   1500       uint32_t result = 0;
   1501       ReadUnsignedLEB128Operand(pc + 1, pc + 6, &length, &result);
   1502       return 1 + length;
   1503     }
   1504     case kExprTableSwitch: {
   1505       uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc + 3);
   1506       return 5 + table_count * 2;
   1507     }
   1508 
   1509     default:
   1510       return 1;
   1511   }
   1512 }
   1513 
   1514 
   1515 int OpcodeArity(FunctionEnv* env, const byte* pc) {
   1516 #define DECLARE_ARITY(name, ...)                          \
   1517   static const LocalType kTypes_##name[] = {__VA_ARGS__}; \
   1518   static const int kArity_##name =                        \
   1519       static_cast<int>(arraysize(kTypes_##name) - 1);
   1520 
   1521   FOREACH_SIGNATURE(DECLARE_ARITY);
   1522 #undef DECLARE_ARITY
   1523 
   1524   switch (static_cast<WasmOpcode>(*pc)) {
   1525     case kExprI8Const:
   1526     case kExprI32Const:
   1527     case kExprI64Const:
   1528     case kExprF64Const:
   1529     case kExprF32Const:
   1530     case kExprGetLocal:
   1531     case kExprLoadGlobal:
   1532     case kExprNop:
   1533     case kExprUnreachable:
   1534       return 0;
   1535 
   1536     case kExprBr:
   1537     case kExprStoreGlobal:
   1538     case kExprSetLocal:
   1539       return 1;
   1540 
   1541     case kExprIf:
   1542     case kExprBrIf:
   1543       return 2;
   1544     case kExprIfElse:
   1545     case kExprSelect:
   1546       return 3;
   1547     case kExprBlock:
   1548     case kExprLoop:
   1549       return *(pc + 1);
   1550 
   1551     case kExprCallFunction: {
   1552       int index = *(pc + 1);
   1553       return static_cast<int>(
   1554           env->module->GetFunctionSignature(index)->parameter_count());
   1555     }
   1556     case kExprCallIndirect: {
   1557       int index = *(pc + 1);
   1558       return 1 + static_cast<int>(
   1559                      env->module->GetSignature(index)->parameter_count());
   1560     }
   1561     case kExprReturn:
   1562       return static_cast<int>(env->sig->return_count());
   1563     case kExprTableSwitch: {
   1564       uint16_t case_count = *reinterpret_cast<const uint16_t*>(pc + 1);
   1565       return 1 + case_count;
   1566     }
   1567 
   1568 #define DECLARE_OPCODE_CASE(name, opcode, sig) \
   1569   case kExpr##name:                            \
   1570     return kArity_##sig;
   1571 
   1572       FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1573       FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1574       FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1575       FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE)
   1576 #undef DECLARE_OPCODE_CASE
   1577   }
   1578   UNREACHABLE();
   1579   return 0;
   1580 }
   1581 }  // namespace wasm
   1582 }  // namespace internal
   1583 }  // namespace v8
   1584