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/signature.h"
      6 
      7 #include "src/base/platform/elapsed-timer.h"
      8 #include "src/bit-vector.h"
      9 #include "src/flags.h"
     10 #include "src/handles.h"
     11 #include "src/objects-inl.h"
     12 #include "src/zone/zone-containers.h"
     13 
     14 #include "src/wasm/decoder.h"
     15 #include "src/wasm/function-body-decoder-impl.h"
     16 #include "src/wasm/function-body-decoder.h"
     17 #include "src/wasm/wasm-limits.h"
     18 #include "src/wasm/wasm-module.h"
     19 #include "src/wasm/wasm-opcodes.h"
     20 
     21 #include "src/ostreams.h"
     22 
     23 #include "src/compiler/wasm-compiler.h"
     24 
     25 namespace v8 {
     26 namespace internal {
     27 namespace wasm {
     28 
     29 #if DEBUG
     30 #define TRACE(...)                                    \
     31   do {                                                \
     32     if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
     33   } while (false)
     34 #else
     35 #define TRACE(...)
     36 #endif
     37 
     38 #define CHECK_PROTOTYPE_OPCODE(flag)                           \
     39   if (module_ != nullptr && module_->origin == kAsmJsOrigin) { \
     40     error("Opcode not supported for asmjs modules");           \
     41   }                                                            \
     42   if (!FLAG_##flag) {                                          \
     43     error("Invalid opcode (enable with --" #flag ")");         \
     44     break;                                                     \
     45   }
     46 
     47 // An SsaEnv environment carries the current local variable renaming
     48 // as well as the current effect and control dependency in the TF graph.
     49 // It maintains a control state that tracks whether the environment
     50 // is reachable, has reached a control end, or has been merged.
     51 struct SsaEnv {
     52   enum State { kControlEnd, kUnreachable, kReached, kMerged };
     53 
     54   State state;
     55   TFNode* control;
     56   TFNode* effect;
     57   TFNode** locals;
     58 
     59   bool go() { return state >= kReached; }
     60   void Kill(State new_state = kControlEnd) {
     61     state = new_state;
     62     locals = nullptr;
     63     control = nullptr;
     64     effect = nullptr;
     65   }
     66   void SetNotMerged() {
     67     if (state == kMerged) state = kReached;
     68   }
     69 };
     70 
     71 // An entry on the value stack.
     72 struct Value {
     73   const byte* pc;
     74   TFNode* node;
     75   ValueType type;
     76 };
     77 
     78 struct TryInfo : public ZoneObject {
     79   SsaEnv* catch_env;
     80   TFNode* exception;
     81 
     82   explicit TryInfo(SsaEnv* c) : catch_env(c), exception(nullptr) {}
     83 };
     84 
     85 struct MergeValues {
     86   uint32_t arity;
     87   union {
     88     Value* array;
     89     Value first;
     90   } vals;  // Either multiple values or a single value.
     91 
     92   Value& operator[](size_t i) {
     93     DCHECK_GT(arity, i);
     94     return arity == 1 ? vals.first : vals.array[i];
     95   }
     96 };
     97 
     98 static Value* NO_VALUE = nullptr;
     99 
    100 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry };
    101 
    102 // An entry on the control stack (i.e. if, block, loop).
    103 struct Control {
    104   const byte* pc;
    105   ControlKind kind;
    106   size_t stack_depth;      // stack height at the beginning of the construct.
    107   SsaEnv* end_env;         // end environment for the construct.
    108   SsaEnv* false_env;       // false environment (only for if).
    109   TryInfo* try_info;       // Information used for compiling try statements.
    110   int32_t previous_catch;  // The previous Control (on the stack) with a catch.
    111   bool unreachable;        // The current block has been ended.
    112 
    113   // Values merged into the end of this control construct.
    114   MergeValues merge;
    115 
    116   inline bool is_if() const { return kind == kControlIf; }
    117   inline bool is_block() const { return kind == kControlBlock; }
    118   inline bool is_loop() const { return kind == kControlLoop; }
    119   inline bool is_try() const { return kind == kControlTry; }
    120 
    121   // Named constructors.
    122   static Control Block(const byte* pc, size_t stack_depth, SsaEnv* end_env,
    123                        int32_t previous_catch) {
    124     return {pc,      kControlBlock,  stack_depth, end_env,        nullptr,
    125             nullptr, previous_catch, false,       {0, {NO_VALUE}}};
    126   }
    127 
    128   static Control If(const byte* pc, size_t stack_depth, SsaEnv* end_env,
    129                     SsaEnv* false_env, int32_t previous_catch) {
    130     return {pc,      kControlIf,     stack_depth, end_env,        false_env,
    131             nullptr, previous_catch, false,       {0, {NO_VALUE}}};
    132   }
    133 
    134   static Control Loop(const byte* pc, size_t stack_depth, SsaEnv* end_env,
    135                       int32_t previous_catch) {
    136     return {pc,      kControlLoop,   stack_depth, end_env,        nullptr,
    137             nullptr, previous_catch, false,       {0, {NO_VALUE}}};
    138   }
    139 
    140   static Control Try(const byte* pc, size_t stack_depth, SsaEnv* end_env,
    141                      Zone* zone, SsaEnv* catch_env, int32_t previous_catch) {
    142     DCHECK_NOT_NULL(catch_env);
    143     TryInfo* try_info = new (zone) TryInfo(catch_env);
    144     return {pc,       kControlTry,    stack_depth, end_env,        nullptr,
    145             try_info, previous_catch, false,       {0, {NO_VALUE}}};
    146   }
    147 };
    148 
    149 // Macros that build nodes only if there is a graph and the current SSA
    150 // environment is reachable from start. This avoids problems with malformed
    151 // TF graphs when decoding inputs that have unreachable code.
    152 #define BUILD(func, ...) \
    153   (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr)
    154 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr)
    155 
    156 // Generic Wasm bytecode decoder with utilities for decoding operands,
    157 // lengths, etc.
    158 class WasmDecoder : public Decoder {
    159  public:
    160   WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start,
    161               const byte* end)
    162       : Decoder(start, end),
    163         module_(module),
    164         sig_(sig),
    165         local_types_(nullptr) {}
    166   const WasmModule* module_;
    167   FunctionSig* sig_;
    168 
    169   ZoneVector<ValueType>* local_types_;
    170 
    171   size_t total_locals() const {
    172     return local_types_ == nullptr ? 0 : local_types_->size();
    173   }
    174 
    175   static bool DecodeLocals(Decoder* decoder, const FunctionSig* sig,
    176                            ZoneVector<ValueType>* type_list) {
    177     DCHECK_NOT_NULL(type_list);
    178     // Initialize from signature.
    179     if (sig != nullptr) {
    180       type_list->reserve(sig->parameter_count());
    181       for (size_t i = 0; i < sig->parameter_count(); ++i) {
    182         type_list->push_back(sig->GetParam(i));
    183       }
    184     }
    185     // Decode local declarations, if any.
    186     uint32_t entries = decoder->consume_u32v("local decls count");
    187     if (decoder->failed()) return false;
    188 
    189     TRACE("local decls count: %u\n", entries);
    190     while (entries-- > 0 && decoder->ok() && decoder->more()) {
    191       uint32_t count = decoder->consume_u32v("local count");
    192       if (decoder->failed()) return false;
    193 
    194       if ((count + type_list->size()) > kV8MaxWasmFunctionLocals) {
    195         decoder->error(decoder->pc() - 1, "local count too large");
    196         return false;
    197       }
    198       byte code = decoder->consume_u8("local type");
    199       if (decoder->failed()) return false;
    200 
    201       ValueType type;
    202       switch (code) {
    203         case kLocalI32:
    204           type = kWasmI32;
    205           break;
    206         case kLocalI64:
    207           type = kWasmI64;
    208           break;
    209         case kLocalF32:
    210           type = kWasmF32;
    211           break;
    212         case kLocalF64:
    213           type = kWasmF64;
    214           break;
    215         case kLocalS128:
    216           type = kWasmS128;
    217           break;
    218         case kLocalS1x4:
    219           type = kWasmS1x4;
    220           break;
    221         case kLocalS1x8:
    222           type = kWasmS1x8;
    223           break;
    224         case kLocalS1x16:
    225           type = kWasmS1x16;
    226           break;
    227         default:
    228           decoder->error(decoder->pc() - 1, "invalid local type");
    229           return false;
    230       }
    231       type_list->insert(type_list->end(), count, type);
    232     }
    233     DCHECK(decoder->ok());
    234     return true;
    235   }
    236 
    237   static BitVector* AnalyzeLoopAssignment(Decoder* decoder, const byte* pc,
    238                                           int locals_count, Zone* zone) {
    239     if (pc >= decoder->end()) return nullptr;
    240     if (*pc != kExprLoop) return nullptr;
    241 
    242     BitVector* assigned = new (zone) BitVector(locals_count, zone);
    243     int depth = 0;
    244     // Iteratively process all AST nodes nested inside the loop.
    245     while (pc < decoder->end() && decoder->ok()) {
    246       WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    247       unsigned length = 1;
    248       switch (opcode) {
    249         case kExprLoop:
    250         case kExprIf:
    251         case kExprBlock:
    252         case kExprTry:
    253           length = OpcodeLength(decoder, pc);
    254           depth++;
    255           break;
    256         case kExprSetLocal:  // fallthru
    257         case kExprTeeLocal: {
    258           LocalIndexOperand operand(decoder, pc);
    259           if (assigned->length() > 0 &&
    260               operand.index < static_cast<uint32_t>(assigned->length())) {
    261             // Unverified code might have an out-of-bounds index.
    262             assigned->Add(operand.index);
    263           }
    264           length = 1 + operand.length;
    265           break;
    266         }
    267         case kExprEnd:
    268           depth--;
    269           break;
    270         default:
    271           length = OpcodeLength(decoder, pc);
    272           break;
    273       }
    274       if (depth <= 0) break;
    275       pc += length;
    276     }
    277     return decoder->ok() ? assigned : nullptr;
    278   }
    279 
    280   inline bool Validate(const byte* pc, LocalIndexOperand& operand) {
    281     if (operand.index < total_locals()) {
    282       if (local_types_) {
    283         operand.type = local_types_->at(operand.index);
    284       } else {
    285         operand.type = kWasmStmt;
    286       }
    287       return true;
    288     }
    289     error(pc, pc + 1, "invalid local index: %u", operand.index);
    290     return false;
    291   }
    292 
    293   inline bool Validate(const byte* pc, GlobalIndexOperand& operand) {
    294     if (module_ != nullptr && operand.index < module_->globals.size()) {
    295       operand.global = &module_->globals[operand.index];
    296       operand.type = operand.global->type;
    297       return true;
    298     }
    299     error(pc, pc + 1, "invalid global index: %u", operand.index);
    300     return false;
    301   }
    302 
    303   inline bool Complete(const byte* pc, CallFunctionOperand& operand) {
    304     if (module_ != nullptr && operand.index < module_->functions.size()) {
    305       operand.sig = module_->functions[operand.index].sig;
    306       return true;
    307     }
    308     return false;
    309   }
    310 
    311   inline bool Validate(const byte* pc, CallFunctionOperand& operand) {
    312     if (Complete(pc, operand)) {
    313       return true;
    314     }
    315     error(pc, pc + 1, "invalid function index: %u", operand.index);
    316     return false;
    317   }
    318 
    319   inline bool Complete(const byte* pc, CallIndirectOperand& operand) {
    320     if (module_ != nullptr && operand.index < module_->signatures.size()) {
    321       operand.sig = module_->signatures[operand.index];
    322       return true;
    323     }
    324     return false;
    325   }
    326 
    327   inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
    328     if (module_ == nullptr || module_->function_tables.empty()) {
    329       error("function table has to exist to execute call_indirect");
    330       return false;
    331     }
    332     if (Complete(pc, operand)) {
    333       return true;
    334     }
    335     error(pc, pc + 1, "invalid signature index: #%u", operand.index);
    336     return false;
    337   }
    338 
    339   inline bool Validate(const byte* pc, BreakDepthOperand& operand,
    340                        ZoneVector<Control>& control) {
    341     if (operand.depth < control.size()) {
    342       operand.target = &control[control.size() - operand.depth - 1];
    343       return true;
    344     }
    345     error(pc, pc + 1, "invalid break depth: %u", operand.depth);
    346     return false;
    347   }
    348 
    349   bool Validate(const byte* pc, BranchTableOperand& operand,
    350                 size_t block_depth) {
    351     // TODO(titzer): add extra redundant validation for br_table here?
    352     return true;
    353   }
    354 
    355   inline bool Validate(const byte* pc, WasmOpcode opcode,
    356                        SimdLaneOperand& operand) {
    357     uint8_t num_lanes = 0;
    358     switch (opcode) {
    359       case kExprF32x4ExtractLane:
    360       case kExprF32x4ReplaceLane:
    361       case kExprI32x4ExtractLane:
    362       case kExprI32x4ReplaceLane:
    363         num_lanes = 4;
    364         break;
    365       case kExprI16x8ExtractLane:
    366       case kExprI16x8ReplaceLane:
    367         num_lanes = 8;
    368         break;
    369       case kExprI8x16ExtractLane:
    370       case kExprI8x16ReplaceLane:
    371         num_lanes = 16;
    372         break;
    373       default:
    374         UNREACHABLE();
    375         break;
    376     }
    377     if (operand.lane < 0 || operand.lane >= num_lanes) {
    378       error(pc_, pc_ + 2, "invalid lane index");
    379       return false;
    380     } else {
    381       return true;
    382     }
    383   }
    384 
    385   inline bool Validate(const byte* pc, WasmOpcode opcode,
    386                        SimdShiftOperand& operand) {
    387     uint8_t max_shift = 0;
    388     switch (opcode) {
    389       case kExprI32x4Shl:
    390       case kExprI32x4ShrS:
    391       case kExprI32x4ShrU:
    392         max_shift = 32;
    393         break;
    394       case kExprI16x8Shl:
    395       case kExprI16x8ShrS:
    396       case kExprI16x8ShrU:
    397         max_shift = 16;
    398         break;
    399       case kExprI8x16Shl:
    400       case kExprI8x16ShrS:
    401       case kExprI8x16ShrU:
    402         max_shift = 8;
    403         break;
    404       default:
    405         UNREACHABLE();
    406         break;
    407     }
    408     if (operand.shift < 0 || operand.shift >= max_shift) {
    409       error(pc_, pc_ + 2, "invalid shift amount");
    410       return false;
    411     } else {
    412       return true;
    413     }
    414   }
    415 
    416   static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
    417     switch (static_cast<byte>(*pc)) {
    418 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
    419       FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
    420       FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
    421 #undef DECLARE_OPCODE_CASE
    422       {
    423         MemoryAccessOperand operand(decoder, pc, UINT32_MAX);
    424         return 1 + operand.length;
    425       }
    426       case kExprBr:
    427       case kExprBrIf: {
    428         BreakDepthOperand operand(decoder, pc);
    429         return 1 + operand.length;
    430       }
    431       case kExprSetGlobal:
    432       case kExprGetGlobal: {
    433         GlobalIndexOperand operand(decoder, pc);
    434         return 1 + operand.length;
    435       }
    436 
    437       case kExprCallFunction: {
    438         CallFunctionOperand operand(decoder, pc);
    439         return 1 + operand.length;
    440       }
    441       case kExprCallIndirect: {
    442         CallIndirectOperand operand(decoder, pc);
    443         return 1 + operand.length;
    444       }
    445 
    446       case kExprTry:
    447       case kExprIf:  // fall thru
    448       case kExprLoop:
    449       case kExprBlock: {
    450         BlockTypeOperand operand(decoder, pc);
    451         return 1 + operand.length;
    452       }
    453 
    454       case kExprSetLocal:
    455       case kExprTeeLocal:
    456       case kExprGetLocal:
    457       case kExprCatch: {
    458         LocalIndexOperand operand(decoder, pc);
    459         return 1 + operand.length;
    460       }
    461       case kExprBrTable: {
    462         BranchTableOperand operand(decoder, pc);
    463         BranchTableIterator iterator(decoder, operand);
    464         return 1 + iterator.length();
    465       }
    466       case kExprI32Const: {
    467         ImmI32Operand operand(decoder, pc);
    468         return 1 + operand.length;
    469       }
    470       case kExprI64Const: {
    471         ImmI64Operand operand(decoder, pc);
    472         return 1 + operand.length;
    473       }
    474       case kExprGrowMemory:
    475       case kExprMemorySize: {
    476         MemoryIndexOperand operand(decoder, pc);
    477         return 1 + operand.length;
    478       }
    479       case kExprF32Const:
    480         return 5;
    481       case kExprF64Const:
    482         return 9;
    483       case kSimdPrefix: {
    484         byte simd_index = decoder->checked_read_u8(pc, 1, "simd_index");
    485         WasmOpcode opcode =
    486             static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index);
    487         switch (opcode) {
    488 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
    489           FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
    490 #undef DECLARE_OPCODE_CASE
    491           {
    492             return 2;
    493           }
    494 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
    495           FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
    496 #undef DECLARE_OPCODE_CASE
    497           {
    498             return 3;
    499           }
    500           default:
    501             decoder->error(pc, "invalid SIMD opcode");
    502             return 2;
    503         }
    504       }
    505       default:
    506         return 1;
    507     }
    508   }
    509 };
    510 
    511 static const int32_t kNullCatch = -1;
    512 
    513 // The full WASM decoder for bytecode. Verifies bytecode and, optionally,
    514 // generates a TurboFan IR graph.
    515 class WasmFullDecoder : public WasmDecoder {
    516  public:
    517   WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
    518                   const FunctionBody& body)
    519       : WasmFullDecoder(zone, module, nullptr, body) {}
    520 
    521   WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
    522       : WasmFullDecoder(zone, builder->module_env() == nullptr
    523                                   ? nullptr
    524                                   : builder->module_env()->module,
    525                         builder, body) {}
    526 
    527   bool Decode() {
    528     if (FLAG_wasm_code_fuzzer_gen_test) {
    529       PrintRawWasmCode(start_, end_);
    530     }
    531     base::ElapsedTimer decode_timer;
    532     if (FLAG_trace_wasm_decode_time) {
    533       decode_timer.Start();
    534     }
    535     stack_.clear();
    536     control_.clear();
    537 
    538     if (end_ < pc_) {
    539       error("function body end < start");
    540       return false;
    541     }
    542 
    543     DCHECK_EQ(0, local_types_->size());
    544     WasmDecoder::DecodeLocals(this, sig_, local_types_);
    545     InitSsaEnv();
    546     DecodeFunctionBody();
    547 
    548     if (failed()) return TraceFailed();
    549 
    550     if (!control_.empty()) {
    551       // Generate a better error message whether the unterminated control
    552       // structure is the function body block or an innner structure.
    553       if (control_.size() > 1) {
    554         error(pc_, control_.back().pc, "unterminated control structure");
    555       } else {
    556         error("function body must end with \"end\" opcode.");
    557       }
    558       return TraceFailed();
    559     }
    560 
    561     if (!last_end_found_) {
    562       error("function body must end with \"end\" opcode.");
    563       return false;
    564     }
    565 
    566     if (FLAG_trace_wasm_decode_time) {
    567       double ms = decode_timer.Elapsed().InMillisecondsF();
    568       PrintF("wasm-decode %s (%0.3f ms)\n\n", ok() ? "ok" : "failed", ms);
    569     } else {
    570       TRACE("wasm-decode %s\n\n", ok() ? "ok" : "failed");
    571     }
    572 
    573     return true;
    574   }
    575 
    576   bool TraceFailed() {
    577     TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_),
    578           startrel(error_pc_), error_msg_.get());
    579     return false;
    580   }
    581 
    582  private:
    583   WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
    584                   TFBuilder* builder, const FunctionBody& body)
    585       : WasmDecoder(module, body.sig, body.start, body.end),
    586         zone_(zone),
    587         builder_(builder),
    588         base_(body.base),
    589         local_type_vec_(zone),
    590         stack_(zone),
    591         control_(zone),
    592         last_end_found_(false),
    593         current_catch_(kNullCatch) {
    594     local_types_ = &local_type_vec_;
    595   }
    596 
    597   static const size_t kErrorMsgSize = 128;
    598 
    599   Zone* zone_;
    600   TFBuilder* builder_;
    601   const byte* base_;
    602 
    603   SsaEnv* ssa_env_;
    604 
    605   ZoneVector<ValueType> local_type_vec_;  // types of local variables.
    606   ZoneVector<Value> stack_;               // stack of values.
    607   ZoneVector<Control> control_;           // stack of blocks, loops, and ifs.
    608   bool last_end_found_;
    609 
    610   int32_t current_catch_;
    611 
    612   TryInfo* current_try_info() { return control_[current_catch_].try_info; }
    613 
    614   inline bool build() { return builder_ && ssa_env_->go(); }
    615 
    616   void InitSsaEnv() {
    617     TFNode* start = nullptr;
    618     SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
    619     size_t size = sizeof(TFNode*) * EnvironmentCount();
    620     ssa_env->state = SsaEnv::kReached;
    621     ssa_env->locals =
    622         size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr;
    623 
    624     if (builder_) {
    625       start = builder_->Start(static_cast<int>(sig_->parameter_count() + 1));
    626       // Initialize local variables.
    627       uint32_t index = 0;
    628       while (index < sig_->parameter_count()) {
    629         ssa_env->locals[index] = builder_->Param(index);
    630         index++;
    631       }
    632       while (index < local_type_vec_.size()) {
    633         ValueType type = local_type_vec_[index];
    634         TFNode* node = DefaultValue(type);
    635         while (index < local_type_vec_.size() &&
    636                local_type_vec_[index] == type) {
    637           // Do a whole run of like-typed locals at a time.
    638           ssa_env->locals[index++] = node;
    639         }
    640       }
    641     }
    642     ssa_env->control = start;
    643     ssa_env->effect = start;
    644     SetEnv("initial", ssa_env);
    645     if (builder_) {
    646       // The function-prologue stack check is associated with position 0, which
    647       // is never a position of any instruction in the function.
    648       builder_->StackCheck(0);
    649     }
    650   }
    651 
    652   TFNode* DefaultValue(ValueType type) {
    653     switch (type) {
    654       case kWasmI32:
    655         return builder_->Int32Constant(0);
    656       case kWasmI64:
    657         return builder_->Int64Constant(0);
    658       case kWasmF32:
    659         return builder_->Float32Constant(0);
    660       case kWasmF64:
    661         return builder_->Float64Constant(0);
    662       case kWasmS128:
    663         return builder_->CreateS128Value(0);
    664       default:
    665         UNREACHABLE();
    666         return nullptr;
    667     }
    668   }
    669 
    670   char* indentation() {
    671     static const int kMaxIndent = 64;
    672     static char bytes[kMaxIndent + 1];
    673     for (int i = 0; i < kMaxIndent; ++i) bytes[i] = ' ';
    674     bytes[kMaxIndent] = 0;
    675     if (stack_.size() < kMaxIndent / 2) {
    676       bytes[stack_.size() * 2] = 0;
    677     }
    678     return bytes;
    679   }
    680 
    681   bool CheckHasMemory() {
    682     if (!module_->has_memory) {
    683       error(pc_ - 1, "memory instruction with no memory");
    684     }
    685     return module_->has_memory;
    686   }
    687 
    688   // Decodes the body of a function.
    689   void DecodeFunctionBody() {
    690     TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n",
    691           reinterpret_cast<const void*>(start_),
    692           reinterpret_cast<const void*>(end_), baserel(pc_),
    693           static_cast<int>(end_ - start_), builder_ ? "graph building" : "");
    694 
    695     {
    696       // Set up initial function block.
    697       SsaEnv* break_env = ssa_env_;
    698       SetEnv("initial env", Steal(break_env));
    699       PushBlock(break_env);
    700       Control* c = &control_.back();
    701       c->merge.arity = static_cast<uint32_t>(sig_->return_count());
    702 
    703       if (c->merge.arity == 1) {
    704         c->merge.vals.first = {pc_, nullptr, sig_->GetReturn(0)};
    705       } else if (c->merge.arity > 1) {
    706         c->merge.vals.array = zone_->NewArray<Value>(c->merge.arity);
    707         for (unsigned i = 0; i < c->merge.arity; i++) {
    708           c->merge.vals.array[i] = {pc_, nullptr, sig_->GetReturn(i)};
    709         }
    710       }
    711     }
    712 
    713     while (pc_ < end_) {  // decoding loop.
    714       unsigned len = 1;
    715       WasmOpcode opcode = static_cast<WasmOpcode>(*pc_);
    716 #if DEBUG
    717       if (FLAG_trace_wasm_decoder && !WasmOpcodes::IsPrefixOpcode(opcode)) {
    718         TRACE("  @%-8d #%-20s|", startrel(pc_),
    719               WasmOpcodes::OpcodeName(opcode));
    720       }
    721 #endif
    722 
    723       FunctionSig* sig = WasmOpcodes::Signature(opcode);
    724       if (sig) {
    725         BuildSimpleOperator(opcode, sig);
    726       } else {
    727         // Complex bytecode.
    728         switch (opcode) {
    729           case kExprNop:
    730             break;
    731           case kExprBlock: {
    732             // The break environment is the outer environment.
    733             BlockTypeOperand operand(this, pc_);
    734             SsaEnv* break_env = ssa_env_;
    735             PushBlock(break_env);
    736             SetEnv("block:start", Steal(break_env));
    737             SetBlockType(&control_.back(), operand);
    738             len = 1 + operand.length;
    739             break;
    740           }
    741           case kExprThrow: {
    742             CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
    743             Value value = Pop(0, kWasmI32);
    744             BUILD(Throw, value.node);
    745             // TODO(titzer): Throw should end control, but currently we build a
    746             // (reachable) runtime call instead of connecting it directly to
    747             // end.
    748             //            EndControl();
    749             break;
    750           }
    751           case kExprTry: {
    752             CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
    753             BlockTypeOperand operand(this, pc_);
    754             SsaEnv* outer_env = ssa_env_;
    755             SsaEnv* try_env = Steal(outer_env);
    756             SsaEnv* catch_env = UnreachableEnv();
    757             PushTry(outer_env, catch_env);
    758             SetEnv("try_catch:start", try_env);
    759             SetBlockType(&control_.back(), operand);
    760             len = 1 + operand.length;
    761             break;
    762           }
    763           case kExprCatch: {
    764             CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
    765             LocalIndexOperand operand(this, pc_);
    766             len = 1 + operand.length;
    767 
    768             if (control_.empty()) {
    769               error("catch does not match any try");
    770               break;
    771             }
    772 
    773             Control* c = &control_.back();
    774             if (!c->is_try()) {
    775               error("catch does not match any try");
    776               break;
    777             }
    778 
    779             if (c->try_info->catch_env == nullptr) {
    780               error(pc_, "catch already present for try with catch");
    781               break;
    782             }
    783 
    784             FallThruTo(c);
    785             stack_.resize(c->stack_depth);
    786 
    787             DCHECK_NOT_NULL(c->try_info);
    788             SsaEnv* catch_env = c->try_info->catch_env;
    789             c->try_info->catch_env = nullptr;
    790             SetEnv("catch:begin", catch_env);
    791             current_catch_ = c->previous_catch;
    792 
    793             if (Validate(pc_, operand)) {
    794               if (ssa_env_->locals) {
    795                 TFNode* exception_as_i32 =
    796                     BUILD(Catch, c->try_info->exception, position());
    797                 ssa_env_->locals[operand.index] = exception_as_i32;
    798               }
    799             }
    800 
    801             break;
    802           }
    803           case kExprLoop: {
    804             BlockTypeOperand operand(this, pc_);
    805             SsaEnv* finish_try_env = Steal(ssa_env_);
    806             // The continue environment is the inner environment.
    807             SsaEnv* loop_body_env = PrepareForLoop(pc_, finish_try_env);
    808             SetEnv("loop:start", loop_body_env);
    809             ssa_env_->SetNotMerged();
    810             PushLoop(finish_try_env);
    811             SetBlockType(&control_.back(), operand);
    812             len = 1 + operand.length;
    813             break;
    814           }
    815           case kExprIf: {
    816             // Condition on top of stack. Split environments for branches.
    817             BlockTypeOperand operand(this, pc_);
    818             Value cond = Pop(0, kWasmI32);
    819             TFNode* if_true = nullptr;
    820             TFNode* if_false = nullptr;
    821             BUILD(BranchNoHint, cond.node, &if_true, &if_false);
    822             SsaEnv* end_env = ssa_env_;
    823             SsaEnv* false_env = Split(ssa_env_);
    824             false_env->control = if_false;
    825             SsaEnv* true_env = Steal(ssa_env_);
    826             true_env->control = if_true;
    827             PushIf(end_env, false_env);
    828             SetEnv("if:true", true_env);
    829             SetBlockType(&control_.back(), operand);
    830             len = 1 + operand.length;
    831             break;
    832           }
    833           case kExprElse: {
    834             if (control_.empty()) {
    835               error("else does not match any if");
    836               break;
    837             }
    838             Control* c = &control_.back();
    839             if (!c->is_if()) {
    840               error(pc_, c->pc, "else does not match an if");
    841               break;
    842             }
    843             if (c->false_env == nullptr) {
    844               error(pc_, c->pc, "else already present for if");
    845               break;
    846             }
    847             FallThruTo(c);
    848             stack_.resize(c->stack_depth);
    849             // Switch to environment for false branch.
    850             SetEnv("if_else:false", c->false_env);
    851             c->false_env = nullptr;  // record that an else is already seen
    852             break;
    853           }
    854           case kExprEnd: {
    855             if (control_.empty()) {
    856               error("end does not match any if, try, or block");
    857               return;
    858             }
    859             const char* name = "block:end";
    860             Control* c = &control_.back();
    861             if (c->is_loop()) {
    862               // A loop just leaves the values on the stack.
    863               TypeCheckFallThru(c);
    864               if (c->unreachable) PushEndValues(c);
    865               PopControl();
    866               SetEnv("loop:end", ssa_env_);
    867               break;
    868             }
    869             if (c->is_if()) {
    870               if (c->false_env != nullptr) {
    871                 // End the true branch of a one-armed if.
    872                 Goto(c->false_env, c->end_env);
    873                 if (!c->unreachable && stack_.size() != c->stack_depth) {
    874                   error("end of if expected empty stack");
    875                   stack_.resize(c->stack_depth);
    876                 }
    877                 if (c->merge.arity > 0) {
    878                   error("non-void one-armed if");
    879                 }
    880                 name = "if:merge";
    881               } else {
    882                 // End the false branch of a two-armed if.
    883                 name = "if_else:merge";
    884               }
    885             } else if (c->is_try()) {
    886               name = "try:end";
    887 
    888               // validate that catch was seen.
    889               if (c->try_info->catch_env != nullptr) {
    890                 error(pc_, "missing catch in try");
    891                 break;
    892               }
    893             }
    894             FallThruTo(c);
    895             SetEnv(name, c->end_env);
    896             PushEndValues(c);
    897 
    898             if (control_.size() == 1) {
    899               // If at the last (implicit) control, check we are at end.
    900               if (pc_ + 1 != end_) {
    901                 error(pc_, pc_ + 1, "trailing code after function end");
    902                 break;
    903               }
    904               last_end_found_ = true;
    905               if (ssa_env_->go()) {
    906                 // The result of the block is the return value.
    907                 TRACE("  @%-8d #xx:%-20s|", startrel(pc_), "(implicit) return");
    908                 DoReturn();
    909                 TRACE("\n");
    910               } else {
    911                 TypeCheckFallThru(c);
    912               }
    913             }
    914             PopControl();
    915             break;
    916           }
    917           case kExprSelect: {
    918             Value cond = Pop(2, kWasmI32);
    919             Value fval = Pop();
    920             Value tval = Pop(0, fval.type);
    921             if (build()) {
    922               TFNode* controls[2];
    923               builder_->BranchNoHint(cond.node, &controls[0], &controls[1]);
    924               TFNode* merge = builder_->Merge(2, controls);
    925               TFNode* vals[2] = {tval.node, fval.node};
    926               TFNode* phi = builder_->Phi(tval.type, 2, vals, merge);
    927               Push(tval.type, phi);
    928               ssa_env_->control = merge;
    929             } else {
    930               Push(tval.type == kWasmVar ? fval.type : tval.type, nullptr);
    931             }
    932             break;
    933           }
    934           case kExprBr: {
    935             BreakDepthOperand operand(this, pc_);
    936             if (Validate(pc_, operand, control_)) {
    937               BreakTo(operand.depth);
    938             }
    939             len = 1 + operand.length;
    940             EndControl();
    941             break;
    942           }
    943           case kExprBrIf: {
    944             BreakDepthOperand operand(this, pc_);
    945             Value cond = Pop(0, kWasmI32);
    946             if (ok() && Validate(pc_, operand, control_)) {
    947               SsaEnv* fenv = ssa_env_;
    948               SsaEnv* tenv = Split(fenv);
    949               fenv->SetNotMerged();
    950               BUILD(BranchNoHint, cond.node, &tenv->control, &fenv->control);
    951               ssa_env_ = tenv;
    952               BreakTo(operand.depth);
    953               ssa_env_ = fenv;
    954             }
    955             len = 1 + operand.length;
    956             break;
    957           }
    958           case kExprBrTable: {
    959             BranchTableOperand operand(this, pc_);
    960             BranchTableIterator iterator(this, operand);
    961             if (Validate(pc_, operand, control_.size())) {
    962               Value key = Pop(0, kWasmI32);
    963               if (failed()) break;
    964 
    965               SsaEnv* break_env = ssa_env_;
    966               if (operand.table_count > 0) {
    967                 // Build branches to the various blocks based on the table.
    968                 TFNode* sw = BUILD(Switch, operand.table_count + 1, key.node);
    969 
    970                 SsaEnv* copy = Steal(break_env);
    971                 ssa_env_ = copy;
    972                 MergeValues* merge = nullptr;
    973                 while (ok() && iterator.has_next()) {
    974                   uint32_t i = iterator.cur_index();
    975                   const byte* pos = iterator.pc();
    976                   uint32_t target = iterator.next();
    977                   if (target >= control_.size()) {
    978                     error(pos, "improper branch in br_table");
    979                     break;
    980                   }
    981                   ssa_env_ = Split(copy);
    982                   ssa_env_->control = (i == operand.table_count)
    983                                           ? BUILD(IfDefault, sw)
    984                                           : BUILD(IfValue, i, sw);
    985                   BreakTo(target);
    986 
    987                   // Check that label types match up.
    988                   Control* c = &control_[control_.size() - target - 1];
    989                   if (i == 0) {
    990                     merge = &c->merge;
    991                   } else if (merge->arity != c->merge.arity) {
    992                     error(pos, pos, "inconsistent arity in br_table target %d"
    993                           " (previous was %u, this one %u)",
    994                           i, merge->arity, c->merge.arity);
    995                   } else if (control_.back().unreachable) {
    996                     for (uint32_t j = 0; ok() && j < merge->arity; ++j) {
    997                       if ((*merge)[j].type != c->merge[j].type) {
    998                         error(pos, pos,
    999                               "type error in br_table target %d operand %d"
   1000                               " (previous expected %s, this one %s)", i, j,
   1001                               WasmOpcodes::TypeName((*merge)[j].type),
   1002                               WasmOpcodes::TypeName(c->merge[j].type));
   1003                       }
   1004                     }
   1005                   }
   1006                 }
   1007                 if (failed()) break;
   1008               } else {
   1009                 // Only a default target. Do the equivalent of br.
   1010                 const byte* pos = iterator.pc();
   1011                 uint32_t target = iterator.next();
   1012                 if (target >= control_.size()) {
   1013                   error(pos, "improper branch in br_table");
   1014                   break;
   1015                 }
   1016                 BreakTo(target);
   1017               }
   1018               // br_table ends the control flow like br.
   1019               ssa_env_ = break_env;
   1020             }
   1021             len = 1 + iterator.length();
   1022             EndControl();
   1023             break;
   1024           }
   1025           case kExprReturn: {
   1026             DoReturn();
   1027             break;
   1028           }
   1029           case kExprUnreachable: {
   1030             BUILD(Unreachable, position());
   1031             EndControl();
   1032             break;
   1033           }
   1034           case kExprI32Const: {
   1035             ImmI32Operand operand(this, pc_);
   1036             Push(kWasmI32, BUILD(Int32Constant, operand.value));
   1037             len = 1 + operand.length;
   1038             break;
   1039           }
   1040           case kExprI64Const: {
   1041             ImmI64Operand operand(this, pc_);
   1042             Push(kWasmI64, BUILD(Int64Constant, operand.value));
   1043             len = 1 + operand.length;
   1044             break;
   1045           }
   1046           case kExprF32Const: {
   1047             ImmF32Operand operand(this, pc_);
   1048             Push(kWasmF32, BUILD(Float32Constant, operand.value));
   1049             len = 1 + operand.length;
   1050             break;
   1051           }
   1052           case kExprF64Const: {
   1053             ImmF64Operand operand(this, pc_);
   1054             Push(kWasmF64, BUILD(Float64Constant, operand.value));
   1055             len = 1 + operand.length;
   1056             break;
   1057           }
   1058           case kExprGetLocal: {
   1059             LocalIndexOperand operand(this, pc_);
   1060             if (Validate(pc_, operand)) {
   1061               if (build()) {
   1062                 Push(operand.type, ssa_env_->locals[operand.index]);
   1063               } else {
   1064                 Push(operand.type, nullptr);
   1065               }
   1066             }
   1067             len = 1 + operand.length;
   1068             break;
   1069           }
   1070           case kExprSetLocal: {
   1071             LocalIndexOperand operand(this, pc_);
   1072             if (Validate(pc_, operand)) {
   1073               Value val = Pop(0, local_type_vec_[operand.index]);
   1074               if (ssa_env_->locals) ssa_env_->locals[operand.index] = val.node;
   1075             }
   1076             len = 1 + operand.length;
   1077             break;
   1078           }
   1079           case kExprTeeLocal: {
   1080             LocalIndexOperand operand(this, pc_);
   1081             if (Validate(pc_, operand)) {
   1082               Value val = Pop(0, local_type_vec_[operand.index]);
   1083               if (ssa_env_->locals) ssa_env_->locals[operand.index] = val.node;
   1084               Push(val.type, val.node);
   1085             }
   1086             len = 1 + operand.length;
   1087             break;
   1088           }
   1089           case kExprDrop: {
   1090             Pop();
   1091             break;
   1092           }
   1093           case kExprGetGlobal: {
   1094             GlobalIndexOperand operand(this, pc_);
   1095             if (Validate(pc_, operand)) {
   1096               Push(operand.type, BUILD(GetGlobal, operand.index));
   1097             }
   1098             len = 1 + operand.length;
   1099             break;
   1100           }
   1101           case kExprSetGlobal: {
   1102             GlobalIndexOperand operand(this, pc_);
   1103             if (Validate(pc_, operand)) {
   1104               if (operand.global->mutability) {
   1105                 Value val = Pop(0, operand.type);
   1106                 BUILD(SetGlobal, operand.index, val.node);
   1107               } else {
   1108                 error(pc_, pc_ + 1, "immutable global #%u cannot be assigned",
   1109                       operand.index);
   1110               }
   1111             }
   1112             len = 1 + operand.length;
   1113             break;
   1114           }
   1115           case kExprI32LoadMem8S:
   1116             len = DecodeLoadMem(kWasmI32, MachineType::Int8());
   1117             break;
   1118           case kExprI32LoadMem8U:
   1119             len = DecodeLoadMem(kWasmI32, MachineType::Uint8());
   1120             break;
   1121           case kExprI32LoadMem16S:
   1122             len = DecodeLoadMem(kWasmI32, MachineType::Int16());
   1123             break;
   1124           case kExprI32LoadMem16U:
   1125             len = DecodeLoadMem(kWasmI32, MachineType::Uint16());
   1126             break;
   1127           case kExprI32LoadMem:
   1128             len = DecodeLoadMem(kWasmI32, MachineType::Int32());
   1129             break;
   1130           case kExprI64LoadMem8S:
   1131             len = DecodeLoadMem(kWasmI64, MachineType::Int8());
   1132             break;
   1133           case kExprI64LoadMem8U:
   1134             len = DecodeLoadMem(kWasmI64, MachineType::Uint8());
   1135             break;
   1136           case kExprI64LoadMem16S:
   1137             len = DecodeLoadMem(kWasmI64, MachineType::Int16());
   1138             break;
   1139           case kExprI64LoadMem16U:
   1140             len = DecodeLoadMem(kWasmI64, MachineType::Uint16());
   1141             break;
   1142           case kExprI64LoadMem32S:
   1143             len = DecodeLoadMem(kWasmI64, MachineType::Int32());
   1144             break;
   1145           case kExprI64LoadMem32U:
   1146             len = DecodeLoadMem(kWasmI64, MachineType::Uint32());
   1147             break;
   1148           case kExprI64LoadMem:
   1149             len = DecodeLoadMem(kWasmI64, MachineType::Int64());
   1150             break;
   1151           case kExprF32LoadMem:
   1152             len = DecodeLoadMem(kWasmF32, MachineType::Float32());
   1153             break;
   1154           case kExprF64LoadMem:
   1155             len = DecodeLoadMem(kWasmF64, MachineType::Float64());
   1156             break;
   1157           case kExprI32StoreMem8:
   1158             len = DecodeStoreMem(kWasmI32, MachineType::Int8());
   1159             break;
   1160           case kExprI32StoreMem16:
   1161             len = DecodeStoreMem(kWasmI32, MachineType::Int16());
   1162             break;
   1163           case kExprI32StoreMem:
   1164             len = DecodeStoreMem(kWasmI32, MachineType::Int32());
   1165             break;
   1166           case kExprI64StoreMem8:
   1167             len = DecodeStoreMem(kWasmI64, MachineType::Int8());
   1168             break;
   1169           case kExprI64StoreMem16:
   1170             len = DecodeStoreMem(kWasmI64, MachineType::Int16());
   1171             break;
   1172           case kExprI64StoreMem32:
   1173             len = DecodeStoreMem(kWasmI64, MachineType::Int32());
   1174             break;
   1175           case kExprI64StoreMem:
   1176             len = DecodeStoreMem(kWasmI64, MachineType::Int64());
   1177             break;
   1178           case kExprF32StoreMem:
   1179             len = DecodeStoreMem(kWasmF32, MachineType::Float32());
   1180             break;
   1181           case kExprF64StoreMem:
   1182             len = DecodeStoreMem(kWasmF64, MachineType::Float64());
   1183             break;
   1184           case kExprGrowMemory: {
   1185             if (!CheckHasMemory()) break;
   1186             MemoryIndexOperand operand(this, pc_);
   1187             DCHECK_NOT_NULL(module_);
   1188             if (module_->origin != kAsmJsOrigin) {
   1189               Value val = Pop(0, kWasmI32);
   1190               Push(kWasmI32, BUILD(GrowMemory, val.node));
   1191             } else {
   1192               error("grow_memory is not supported for asmjs modules");
   1193             }
   1194             len = 1 + operand.length;
   1195             break;
   1196           }
   1197           case kExprMemorySize: {
   1198             if (!CheckHasMemory()) break;
   1199             MemoryIndexOperand operand(this, pc_);
   1200             Push(kWasmI32, BUILD(CurrentMemoryPages));
   1201             len = 1 + operand.length;
   1202             break;
   1203           }
   1204           case kExprCallFunction: {
   1205             CallFunctionOperand operand(this, pc_);
   1206             if (Validate(pc_, operand)) {
   1207               TFNode** buffer = PopArgs(operand.sig);
   1208               TFNode** rets = nullptr;
   1209               BUILD(CallDirect, operand.index, buffer, &rets, position());
   1210               PushReturns(operand.sig, rets);
   1211             }
   1212             len = 1 + operand.length;
   1213             break;
   1214           }
   1215           case kExprCallIndirect: {
   1216             CallIndirectOperand operand(this, pc_);
   1217             if (Validate(pc_, operand)) {
   1218               Value index = Pop(0, kWasmI32);
   1219               TFNode** buffer = PopArgs(operand.sig);
   1220               if (buffer) buffer[0] = index.node;
   1221               TFNode** rets = nullptr;
   1222               BUILD(CallIndirect, operand.index, buffer, &rets, position());
   1223               PushReturns(operand.sig, rets);
   1224             }
   1225             len = 1 + operand.length;
   1226             break;
   1227           }
   1228           case kSimdPrefix: {
   1229             CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
   1230             len++;
   1231             byte simd_index = checked_read_u8(pc_, 1, "simd index");
   1232             opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index);
   1233             TRACE("  @%-4d #%-20s|", startrel(pc_),
   1234                   WasmOpcodes::OpcodeName(opcode));
   1235             len += DecodeSimdOpcode(opcode);
   1236             break;
   1237           }
   1238           case kAtomicPrefix: {
   1239             if (module_ == nullptr || module_->origin != kAsmJsOrigin) {
   1240               error("Atomics are allowed only in AsmJs modules");
   1241               break;
   1242             }
   1243             if (!FLAG_wasm_atomics_prototype) {
   1244               error("Invalid opcode (enable with --wasm_atomics_prototype)");
   1245               break;
   1246             }
   1247             len = 2;
   1248             byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index");
   1249             opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode);
   1250             sig = WasmOpcodes::AtomicSignature(opcode);
   1251             if (sig) {
   1252               BuildAtomicOperator(opcode);
   1253             }
   1254             break;
   1255           }
   1256           default: {
   1257             // Deal with special asmjs opcodes.
   1258             if (module_ != nullptr && module_->origin == kAsmJsOrigin) {
   1259               sig = WasmOpcodes::AsmjsSignature(opcode);
   1260               if (sig) {
   1261                 BuildSimpleOperator(opcode, sig);
   1262               }
   1263             } else {
   1264               error("Invalid opcode");
   1265               return;
   1266             }
   1267           }
   1268         }
   1269       }
   1270 
   1271 #if DEBUG
   1272       if (FLAG_trace_wasm_decoder) {
   1273         PrintF(" ");
   1274         for (size_t i = 0; i < control_.size(); ++i) {
   1275           Control* c = &control_[i];
   1276           enum ControlKind {
   1277             kControlIf,
   1278             kControlBlock,
   1279             kControlLoop,
   1280             kControlTry
   1281           };
   1282           switch (c->kind) {
   1283             case kControlIf:
   1284               PrintF("I");
   1285               break;
   1286             case kControlBlock:
   1287               PrintF("B");
   1288               break;
   1289             case kControlLoop:
   1290               PrintF("L");
   1291               break;
   1292             case kControlTry:
   1293               PrintF("T");
   1294               break;
   1295             default:
   1296               break;
   1297           }
   1298           PrintF("%u", c->merge.arity);
   1299           if (c->unreachable) PrintF("*");
   1300         }
   1301         PrintF(" | ");
   1302         for (size_t i = 0; i < stack_.size(); ++i) {
   1303           Value& val = stack_[i];
   1304           WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc);
   1305           if (WasmOpcodes::IsPrefixOpcode(opcode)) {
   1306             opcode = static_cast<WasmOpcode>(opcode << 8 | *(val.pc + 1));
   1307           }
   1308           PrintF(" %c@%d:%s", WasmOpcodes::ShortNameOf(val.type),
   1309                  static_cast<int>(val.pc - start_),
   1310                  WasmOpcodes::OpcodeName(opcode));
   1311           switch (opcode) {
   1312             case kExprI32Const: {
   1313               ImmI32Operand operand(this, val.pc);
   1314               PrintF("[%d]", operand.value);
   1315               break;
   1316             }
   1317             case kExprGetLocal: {
   1318               LocalIndexOperand operand(this, val.pc);
   1319               PrintF("[%u]", operand.index);
   1320               break;
   1321             }
   1322             case kExprSetLocal:  // fallthru
   1323             case kExprTeeLocal: {
   1324               LocalIndexOperand operand(this, val.pc);
   1325               PrintF("[%u]", operand.index);
   1326               break;
   1327             }
   1328             default:
   1329               break;
   1330           }
   1331           if (val.node == nullptr) PrintF("?");
   1332         }
   1333         PrintF("\n");
   1334       }
   1335 #endif
   1336       pc_ += len;
   1337     }  // end decode loop
   1338     if (pc_ > end_ && ok()) error("Beyond end of code");
   1339   }
   1340 
   1341   void EndControl() {
   1342     ssa_env_->Kill(SsaEnv::kControlEnd);
   1343     if (!control_.empty()) {
   1344       stack_.resize(control_.back().stack_depth);
   1345       control_.back().unreachable = true;
   1346     }
   1347   }
   1348 
   1349   void SetBlockType(Control* c, BlockTypeOperand& operand) {
   1350     c->merge.arity = operand.arity;
   1351     if (c->merge.arity == 1) {
   1352       c->merge.vals.first = {pc_, nullptr, operand.read_entry(0)};
   1353     } else if (c->merge.arity > 1) {
   1354       c->merge.vals.array = zone_->NewArray<Value>(c->merge.arity);
   1355       for (unsigned i = 0; i < c->merge.arity; i++) {
   1356         c->merge.vals.array[i] = {pc_, nullptr, operand.read_entry(i)};
   1357       }
   1358     }
   1359   }
   1360 
   1361   TFNode** PopArgs(FunctionSig* sig) {
   1362     if (build()) {
   1363       int count = static_cast<int>(sig->parameter_count());
   1364       TFNode** buffer = builder_->Buffer(count + 1);
   1365       buffer[0] = nullptr;  // reserved for code object or function index.
   1366       for (int i = count - 1; i >= 0; i--) {
   1367         buffer[i + 1] = Pop(i, sig->GetParam(i)).node;
   1368       }
   1369       return buffer;
   1370     } else {
   1371       int count = static_cast<int>(sig->parameter_count());
   1372       for (int i = count - 1; i >= 0; i--) {
   1373         Pop(i, sig->GetParam(i));
   1374       }
   1375       return nullptr;
   1376     }
   1377   }
   1378 
   1379   ValueType GetReturnType(FunctionSig* sig) {
   1380     return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn();
   1381   }
   1382 
   1383   void PushBlock(SsaEnv* end_env) {
   1384     control_.emplace_back(
   1385         Control::Block(pc_, stack_.size(), end_env, current_catch_));
   1386   }
   1387 
   1388   void PushLoop(SsaEnv* end_env) {
   1389     control_.emplace_back(
   1390         Control::Loop(pc_, stack_.size(), end_env, current_catch_));
   1391   }
   1392 
   1393   void PushIf(SsaEnv* end_env, SsaEnv* false_env) {
   1394     control_.emplace_back(
   1395         Control::If(pc_, stack_.size(), end_env, false_env, current_catch_));
   1396   }
   1397 
   1398   void PushTry(SsaEnv* end_env, SsaEnv* catch_env) {
   1399     control_.emplace_back(Control::Try(pc_, stack_.size(), end_env, zone_,
   1400                                        catch_env, current_catch_));
   1401     current_catch_ = static_cast<int32_t>(control_.size() - 1);
   1402   }
   1403 
   1404   void PopControl() { control_.pop_back(); }
   1405 
   1406   int DecodeLoadMem(ValueType type, MachineType mem_type) {
   1407     if (!CheckHasMemory()) return 0;
   1408     MemoryAccessOperand operand(this, pc_,
   1409                                 ElementSizeLog2Of(mem_type.representation()));
   1410 
   1411     Value index = Pop(0, kWasmI32);
   1412     TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset,
   1413                          operand.alignment, position());
   1414     Push(type, node);
   1415     return 1 + operand.length;
   1416   }
   1417 
   1418   int DecodeStoreMem(ValueType type, MachineType mem_type) {
   1419     if (!CheckHasMemory()) return 0;
   1420     MemoryAccessOperand operand(this, pc_,
   1421                                 ElementSizeLog2Of(mem_type.representation()));
   1422     Value val = Pop(1, type);
   1423     Value index = Pop(0, kWasmI32);
   1424     BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment,
   1425           val.node, position());
   1426     return 1 + operand.length;
   1427   }
   1428 
   1429   unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) {
   1430     SimdLaneOperand operand(this, pc_);
   1431     if (Validate(pc_, opcode, operand)) {
   1432       compiler::NodeVector inputs(1, zone_);
   1433       inputs[0] = Pop(0, ValueType::kSimd128).node;
   1434       TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs);
   1435       Push(type, node);
   1436     }
   1437     return operand.length;
   1438   }
   1439 
   1440   unsigned SimdReplaceLane(WasmOpcode opcode, ValueType type) {
   1441     SimdLaneOperand operand(this, pc_);
   1442     if (Validate(pc_, opcode, operand)) {
   1443       compiler::NodeVector inputs(2, zone_);
   1444       inputs[1] = Pop(1, type).node;
   1445       inputs[0] = Pop(0, ValueType::kSimd128).node;
   1446       TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs);
   1447       Push(ValueType::kSimd128, node);
   1448     }
   1449     return operand.length;
   1450   }
   1451 
   1452   unsigned SimdShiftOp(WasmOpcode opcode) {
   1453     SimdShiftOperand operand(this, pc_);
   1454     if (Validate(pc_, opcode, operand)) {
   1455       compiler::NodeVector inputs(1, zone_);
   1456       inputs[0] = Pop(0, ValueType::kSimd128).node;
   1457       TFNode* node = BUILD(SimdShiftOp, opcode, operand.shift, inputs);
   1458       Push(ValueType::kSimd128, node);
   1459     }
   1460     return operand.length;
   1461   }
   1462 
   1463   unsigned DecodeSimdOpcode(WasmOpcode opcode) {
   1464     unsigned len = 0;
   1465     switch (opcode) {
   1466       case kExprF32x4ExtractLane: {
   1467         len = SimdExtractLane(opcode, ValueType::kFloat32);
   1468         break;
   1469       }
   1470       case kExprI32x4ExtractLane:
   1471       case kExprI16x8ExtractLane:
   1472       case kExprI8x16ExtractLane: {
   1473         len = SimdExtractLane(opcode, ValueType::kWord32);
   1474         break;
   1475       }
   1476       case kExprF32x4ReplaceLane: {
   1477         len = SimdReplaceLane(opcode, ValueType::kFloat32);
   1478         break;
   1479       }
   1480       case kExprI32x4ReplaceLane:
   1481       case kExprI16x8ReplaceLane:
   1482       case kExprI8x16ReplaceLane: {
   1483         len = SimdReplaceLane(opcode, ValueType::kWord32);
   1484         break;
   1485       }
   1486       case kExprI32x4Shl:
   1487       case kExprI32x4ShrS:
   1488       case kExprI32x4ShrU:
   1489       case kExprI16x8Shl:
   1490       case kExprI16x8ShrS:
   1491       case kExprI16x8ShrU:
   1492       case kExprI8x16Shl:
   1493       case kExprI8x16ShrS:
   1494       case kExprI8x16ShrU: {
   1495         len = SimdShiftOp(opcode);
   1496         break;
   1497       }
   1498       default: {
   1499         FunctionSig* sig = WasmOpcodes::Signature(opcode);
   1500         if (sig != nullptr) {
   1501           compiler::NodeVector inputs(sig->parameter_count(), zone_);
   1502           for (size_t i = sig->parameter_count(); i > 0; i--) {
   1503             Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1));
   1504             inputs[i - 1] = val.node;
   1505           }
   1506           TFNode* node = BUILD(SimdOp, opcode, inputs);
   1507           Push(GetReturnType(sig), node);
   1508         } else {
   1509           error("invalid simd opcode");
   1510         }
   1511       }
   1512     }
   1513     return len;
   1514   }
   1515 
   1516   void BuildAtomicOperator(WasmOpcode opcode) { UNIMPLEMENTED(); }
   1517 
   1518   void DoReturn() {
   1519     int count = static_cast<int>(sig_->return_count());
   1520     TFNode** buffer = nullptr;
   1521     if (build()) buffer = builder_->Buffer(count);
   1522 
   1523     // Pop return values off the stack in reverse order.
   1524     for (int i = count - 1; i >= 0; i--) {
   1525       Value val = Pop(i, sig_->GetReturn(i));
   1526       if (buffer) buffer[i] = val.node;
   1527     }
   1528 
   1529     BUILD(Return, count, buffer);
   1530     EndControl();
   1531   }
   1532 
   1533   void Push(ValueType type, TFNode* node) {
   1534     if (type != kWasmStmt) {
   1535       stack_.push_back({pc_, node, type});
   1536     }
   1537   }
   1538 
   1539   void PushEndValues(Control* c) {
   1540     DCHECK_EQ(c, &control_.back());
   1541     stack_.resize(c->stack_depth);
   1542     if (c->merge.arity == 1) {
   1543       stack_.push_back(c->merge.vals.first);
   1544     } else {
   1545       for (unsigned i = 0; i < c->merge.arity; i++) {
   1546         stack_.push_back(c->merge.vals.array[i]);
   1547       }
   1548     }
   1549     DCHECK_EQ(c->stack_depth + c->merge.arity, stack_.size());
   1550   }
   1551 
   1552   void PushReturns(FunctionSig* sig, TFNode** rets) {
   1553     for (size_t i = 0; i < sig->return_count(); i++) {
   1554       // When verifying only, then {rets} will be null, so push null.
   1555       Push(sig->GetReturn(i), rets ? rets[i] : nullptr);
   1556     }
   1557   }
   1558 
   1559   const char* SafeOpcodeNameAt(const byte* pc) {
   1560     if (pc >= end_) return "<end>";
   1561     return WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(*pc));
   1562   }
   1563 
   1564   Value Pop(int index, ValueType expected) {
   1565     Value val = Pop();
   1566     if (val.type != expected && val.type != kWasmVar && expected != kWasmVar) {
   1567       error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s",
   1568             SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected),
   1569             SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type));
   1570     }
   1571     return val;
   1572   }
   1573 
   1574   Value Pop() {
   1575     size_t limit = control_.empty() ? 0 : control_.back().stack_depth;
   1576     if (stack_.size() <= limit) {
   1577       // Popping past the current control start in reachable code.
   1578       Value val = {pc_, nullptr, kWasmVar};
   1579       if (!control_.back().unreachable) {
   1580         error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_));
   1581       }
   1582       return val;
   1583     }
   1584     Value val = stack_.back();
   1585     stack_.pop_back();
   1586     return val;
   1587   }
   1588 
   1589   int baserel(const byte* ptr) {
   1590     return base_ ? static_cast<int>(ptr - base_) : 0;
   1591   }
   1592 
   1593   int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); }
   1594 
   1595   void BreakTo(unsigned depth) {
   1596     Control* c = &control_[control_.size() - depth - 1];
   1597     if (c->is_loop()) {
   1598       // This is the inner loop block, which does not have a value.
   1599       Goto(ssa_env_, c->end_env);
   1600     } else {
   1601       // Merge the value(s) into the end of the block.
   1602       size_t expected = control_.back().stack_depth + c->merge.arity;
   1603       if (stack_.size() < expected && !control_.back().unreachable) {
   1604         error(
   1605             pc_, pc_,
   1606             "expected at least %u values on the stack for br to @%d, found %d",
   1607             c->merge.arity, startrel(c->pc),
   1608             static_cast<int>(stack_.size() - c->stack_depth));
   1609         return;
   1610       }
   1611       MergeValuesInto(c);
   1612     }
   1613   }
   1614 
   1615   void FallThruTo(Control* c) {
   1616     DCHECK_EQ(c, &control_.back());
   1617     // Merge the value(s) into the end of the block.
   1618     size_t expected = c->stack_depth + c->merge.arity;
   1619     if (stack_.size() == expected ||
   1620         (stack_.size() < expected && c->unreachable)) {
   1621       MergeValuesInto(c);
   1622       c->unreachable = false;
   1623       return;
   1624     }
   1625     error(pc_, pc_, "expected %u elements on the stack for fallthru to @%d",
   1626           c->merge.arity, startrel(c->pc));
   1627   }
   1628 
   1629   inline Value& GetMergeValueFromStack(Control* c, size_t i) {
   1630     return stack_[stack_.size() - c->merge.arity + i];
   1631   }
   1632 
   1633   void TypeCheckFallThru(Control* c) {
   1634     DCHECK_EQ(c, &control_.back());
   1635     // Fallthru must match arity exactly.
   1636     int arity = static_cast<int>(c->merge.arity);
   1637     if (c->stack_depth + arity < stack_.size() ||
   1638         (c->stack_depth + arity != stack_.size() && !c->unreachable)) {
   1639       error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d",
   1640             arity, startrel(c->pc));
   1641       return;
   1642     }
   1643     // Typecheck the values left on the stack.
   1644     size_t avail = stack_.size() - c->stack_depth;
   1645     for (size_t i = avail >= c->merge.arity ? 0 : c->merge.arity - avail;
   1646          i < c->merge.arity; i++) {
   1647       Value& val = GetMergeValueFromStack(c, i);
   1648       Value& old = c->merge[i];
   1649       if (val.type != old.type) {
   1650         error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
   1651               WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
   1652         return;
   1653       }
   1654     }
   1655   }
   1656 
   1657   void MergeValuesInto(Control* c) {
   1658     SsaEnv* target = c->end_env;
   1659     bool first = target->state == SsaEnv::kUnreachable;
   1660     bool reachable = ssa_env_->go();
   1661     Goto(ssa_env_, target);
   1662 
   1663     size_t avail = stack_.size() - control_.back().stack_depth;
   1664     for (size_t i = avail >= c->merge.arity ? 0 : c->merge.arity - avail;
   1665          i < c->merge.arity; i++) {
   1666       Value& val = GetMergeValueFromStack(c, i);
   1667       Value& old = c->merge[i];
   1668       if (val.type != old.type && val.type != kWasmVar) {
   1669         error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
   1670               WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
   1671         return;
   1672       }
   1673       if (builder_ && reachable) {
   1674         DCHECK_NOT_NULL(val.node);
   1675         old.node =
   1676             first ? val.node : CreateOrMergeIntoPhi(old.type, target->control,
   1677                                                     old.node, val.node);
   1678       }
   1679     }
   1680   }
   1681 
   1682   void SetEnv(const char* reason, SsaEnv* env) {
   1683 #if DEBUG
   1684     if (FLAG_trace_wasm_decoder) {
   1685       char state = 'X';
   1686       if (env) {
   1687         switch (env->state) {
   1688           case SsaEnv::kReached:
   1689             state = 'R';
   1690             break;
   1691           case SsaEnv::kUnreachable:
   1692             state = 'U';
   1693             break;
   1694           case SsaEnv::kMerged:
   1695             state = 'M';
   1696             break;
   1697           case SsaEnv::kControlEnd:
   1698             state = 'E';
   1699             break;
   1700         }
   1701       }
   1702       PrintF("{set_env = %p, state = %c, reason = %s", static_cast<void*>(env),
   1703              state, reason);
   1704       if (env && env->control) {
   1705         PrintF(", control = ");
   1706         compiler::WasmGraphBuilder::PrintDebugName(env->control);
   1707       }
   1708       PrintF("}");
   1709     }
   1710 #endif
   1711     ssa_env_ = env;
   1712     if (builder_) {
   1713       builder_->set_control_ptr(&env->control);
   1714       builder_->set_effect_ptr(&env->effect);
   1715     }
   1716   }
   1717 
   1718   TFNode* CheckForException(TFNode* node) {
   1719     if (node == nullptr) {
   1720       return nullptr;
   1721     }
   1722 
   1723     const bool inside_try_scope = current_catch_ != kNullCatch;
   1724 
   1725     if (!inside_try_scope) {
   1726       return node;
   1727     }
   1728 
   1729     TFNode* if_success = nullptr;
   1730     TFNode* if_exception = nullptr;
   1731     if (!builder_->ThrowsException(node, &if_success, &if_exception)) {
   1732       return node;
   1733     }
   1734 
   1735     SsaEnv* success_env = Steal(ssa_env_);
   1736     success_env->control = if_success;
   1737 
   1738     SsaEnv* exception_env = Split(success_env);
   1739     exception_env->control = if_exception;
   1740     TryInfo* try_info = current_try_info();
   1741     Goto(exception_env, try_info->catch_env);
   1742     TFNode* exception = try_info->exception;
   1743     if (exception == nullptr) {
   1744       DCHECK_EQ(SsaEnv::kReached, try_info->catch_env->state);
   1745       try_info->exception = if_exception;
   1746     } else {
   1747       DCHECK_EQ(SsaEnv::kMerged, try_info->catch_env->state);
   1748       try_info->exception =
   1749           CreateOrMergeIntoPhi(kWasmI32, try_info->catch_env->control,
   1750                                try_info->exception, if_exception);
   1751     }
   1752 
   1753     SetEnv("if_success", success_env);
   1754     return node;
   1755   }
   1756 
   1757   void Goto(SsaEnv* from, SsaEnv* to) {
   1758     DCHECK_NOT_NULL(to);
   1759     if (!from->go()) return;
   1760     switch (to->state) {
   1761       case SsaEnv::kUnreachable: {  // Overwrite destination.
   1762         to->state = SsaEnv::kReached;
   1763         to->locals = from->locals;
   1764         to->control = from->control;
   1765         to->effect = from->effect;
   1766         break;
   1767       }
   1768       case SsaEnv::kReached: {  // Create a new merge.
   1769         to->state = SsaEnv::kMerged;
   1770         if (!builder_) break;
   1771         // Merge control.
   1772         TFNode* controls[] = {to->control, from->control};
   1773         TFNode* merge = builder_->Merge(2, controls);
   1774         to->control = merge;
   1775         // Merge effects.
   1776         if (from->effect != to->effect) {
   1777           TFNode* effects[] = {to->effect, from->effect, merge};
   1778           to->effect = builder_->EffectPhi(2, effects, merge);
   1779         }
   1780         // Merge SSA values.
   1781         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1782           TFNode* a = to->locals[i];
   1783           TFNode* b = from->locals[i];
   1784           if (a != b) {
   1785             TFNode* vals[] = {a, b};
   1786             to->locals[i] = builder_->Phi(local_type_vec_[i], 2, vals, merge);
   1787           }
   1788         }
   1789         break;
   1790       }
   1791       case SsaEnv::kMerged: {
   1792         if (!builder_) break;
   1793         TFNode* merge = to->control;
   1794         // Extend the existing merge.
   1795         builder_->AppendToMerge(merge, from->control);
   1796         // Merge effects.
   1797         if (builder_->IsPhiWithMerge(to->effect, merge)) {
   1798           builder_->AppendToPhi(to->effect, from->effect);
   1799         } else if (to->effect != from->effect) {
   1800           uint32_t count = builder_->InputCount(merge);
   1801           TFNode** effects = builder_->Buffer(count);
   1802           for (uint32_t j = 0; j < count - 1; j++) {
   1803             effects[j] = to->effect;
   1804           }
   1805           effects[count - 1] = from->effect;
   1806           to->effect = builder_->EffectPhi(count, effects, merge);
   1807         }
   1808         // Merge locals.
   1809         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1810           TFNode* tnode = to->locals[i];
   1811           TFNode* fnode = from->locals[i];
   1812           if (builder_->IsPhiWithMerge(tnode, merge)) {
   1813             builder_->AppendToPhi(tnode, fnode);
   1814           } else if (tnode != fnode) {
   1815             uint32_t count = builder_->InputCount(merge);
   1816             TFNode** vals = builder_->Buffer(count);
   1817             for (uint32_t j = 0; j < count - 1; j++) {
   1818               vals[j] = tnode;
   1819             }
   1820             vals[count - 1] = fnode;
   1821             to->locals[i] =
   1822                 builder_->Phi(local_type_vec_[i], count, vals, merge);
   1823           }
   1824         }
   1825         break;
   1826       }
   1827       default:
   1828         UNREACHABLE();
   1829     }
   1830     return from->Kill();
   1831   }
   1832 
   1833   TFNode* CreateOrMergeIntoPhi(ValueType type, TFNode* merge, TFNode* tnode,
   1834                                TFNode* fnode) {
   1835     DCHECK_NOT_NULL(builder_);
   1836     if (builder_->IsPhiWithMerge(tnode, merge)) {
   1837       builder_->AppendToPhi(tnode, fnode);
   1838     } else if (tnode != fnode) {
   1839       uint32_t count = builder_->InputCount(merge);
   1840       TFNode** vals = builder_->Buffer(count);
   1841       for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode;
   1842       vals[count - 1] = fnode;
   1843       return builder_->Phi(type, count, vals, merge);
   1844     }
   1845     return tnode;
   1846   }
   1847 
   1848   SsaEnv* PrepareForLoop(const byte* pc, SsaEnv* env) {
   1849     if (!builder_) return Split(env);
   1850     if (!env->go()) return Split(env);
   1851     env->state = SsaEnv::kMerged;
   1852 
   1853     env->control = builder_->Loop(env->control);
   1854     env->effect = builder_->EffectPhi(1, &env->effect, env->control);
   1855     builder_->Terminate(env->effect, env->control);
   1856     if (FLAG_wasm_loop_assignment_analysis) {
   1857       BitVector* assigned = AnalyzeLoopAssignment(
   1858           this, pc, static_cast<int>(total_locals()), zone_);
   1859       if (failed()) return env;
   1860       if (assigned != nullptr) {
   1861         // Only introduce phis for variables assigned in this loop.
   1862         for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1863           if (!assigned->Contains(i)) continue;
   1864           env->locals[i] = builder_->Phi(local_type_vec_[i], 1, &env->locals[i],
   1865                                          env->control);
   1866         }
   1867         SsaEnv* loop_body_env = Split(env);
   1868         builder_->StackCheck(position(), &(loop_body_env->effect),
   1869                              &(loop_body_env->control));
   1870         return loop_body_env;
   1871       }
   1872     }
   1873 
   1874     // Conservatively introduce phis for all local variables.
   1875     for (int i = EnvironmentCount() - 1; i >= 0; i--) {
   1876       env->locals[i] =
   1877           builder_->Phi(local_type_vec_[i], 1, &env->locals[i], env->control);
   1878     }
   1879 
   1880     SsaEnv* loop_body_env = Split(env);
   1881     builder_->StackCheck(position(), &(loop_body_env->effect),
   1882                          &(loop_body_env->control));
   1883     return loop_body_env;
   1884   }
   1885 
   1886   // Create a complete copy of the {from}.
   1887   SsaEnv* Split(SsaEnv* from) {
   1888     DCHECK_NOT_NULL(from);
   1889     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1890     size_t size = sizeof(TFNode*) * EnvironmentCount();
   1891     result->control = from->control;
   1892     result->effect = from->effect;
   1893 
   1894     if (from->go()) {
   1895       result->state = SsaEnv::kReached;
   1896       result->locals =
   1897           size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr;
   1898       memcpy(result->locals, from->locals, size);
   1899     } else {
   1900       result->state = SsaEnv::kUnreachable;
   1901       result->locals = nullptr;
   1902     }
   1903 
   1904     return result;
   1905   }
   1906 
   1907   // Create a copy of {from} that steals its state and leaves {from}
   1908   // unreachable.
   1909   SsaEnv* Steal(SsaEnv* from) {
   1910     DCHECK_NOT_NULL(from);
   1911     if (!from->go()) return UnreachableEnv();
   1912     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1913     result->state = SsaEnv::kReached;
   1914     result->locals = from->locals;
   1915     result->control = from->control;
   1916     result->effect = from->effect;
   1917     from->Kill(SsaEnv::kUnreachable);
   1918     return result;
   1919   }
   1920 
   1921   // Create an unreachable environment.
   1922   SsaEnv* UnreachableEnv() {
   1923     SsaEnv* result = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
   1924     result->state = SsaEnv::kUnreachable;
   1925     result->control = nullptr;
   1926     result->effect = nullptr;
   1927     result->locals = nullptr;
   1928     return result;
   1929   }
   1930 
   1931   int EnvironmentCount() {
   1932     if (builder_) return static_cast<int>(local_type_vec_.size());
   1933     return 0;  // if we aren't building a graph, don't bother with SSA renaming.
   1934   }
   1935 
   1936   virtual void onFirstError() {
   1937     end_ = start_;       // Terminate decoding loop.
   1938     builder_ = nullptr;  // Don't build any more nodes.
   1939     TRACE(" !%s\n", error_msg_.get());
   1940   }
   1941 
   1942   inline wasm::WasmCodePosition position() {
   1943     int offset = static_cast<int>(pc_ - start_);
   1944     DCHECK_EQ(pc_ - start_, offset);  // overflows cannot happen
   1945     return offset;
   1946   }
   1947 
   1948   inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) {
   1949     TFNode* node;
   1950     switch (sig->parameter_count()) {
   1951       case 1: {
   1952         Value val = Pop(0, sig->GetParam(0));
   1953         node = BUILD(Unop, opcode, val.node, position());
   1954         break;
   1955       }
   1956       case 2: {
   1957         Value rval = Pop(1, sig->GetParam(1));
   1958         Value lval = Pop(0, sig->GetParam(0));
   1959         node = BUILD(Binop, opcode, lval.node, rval.node, position());
   1960         break;
   1961       }
   1962       default:
   1963         UNREACHABLE();
   1964         node = nullptr;
   1965         break;
   1966     }
   1967     Push(GetReturnType(sig), node);
   1968   }
   1969 };
   1970 
   1971 bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start,
   1972                       const byte* end) {
   1973   Decoder decoder(start, end);
   1974   if (WasmDecoder::DecodeLocals(&decoder, nullptr, &decls->type_list)) {
   1975     DCHECK(decoder.ok());
   1976     decls->encoded_size = decoder.pc_offset();
   1977     return true;
   1978   }
   1979   return false;
   1980 }
   1981 
   1982 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
   1983                                    BodyLocalDecls* decls)
   1984     : Decoder(start, end) {
   1985   if (decls != nullptr) {
   1986     if (DecodeLocalDecls(decls, start, end)) {
   1987       pc_ += decls->encoded_size;
   1988       if (pc_ > end_) pc_ = end_;
   1989     }
   1990   }
   1991 }
   1992 
   1993 DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
   1994                             const wasm::WasmModule* module,
   1995                             FunctionBody& body) {
   1996   Zone zone(allocator, ZONE_NAME);
   1997   WasmFullDecoder decoder(&zone, module, body);
   1998   decoder.Decode();
   1999   return decoder.toResult<DecodeStruct*>(nullptr);
   2000 }
   2001 
   2002 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder,
   2003                           FunctionBody& body) {
   2004   Zone zone(allocator, ZONE_NAME);
   2005   WasmFullDecoder decoder(&zone, builder, body);
   2006   decoder.Decode();
   2007   return decoder.toResult<DecodeStruct*>(nullptr);
   2008 }
   2009 
   2010 unsigned OpcodeLength(const byte* pc, const byte* end) {
   2011   Decoder decoder(pc, end);
   2012   return WasmDecoder::OpcodeLength(&decoder, pc);
   2013 }
   2014 
   2015 void PrintRawWasmCode(const byte* start, const byte* end) {
   2016   AccountingAllocator allocator;
   2017   PrintRawWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr);
   2018 }
   2019 
   2020 namespace {
   2021 const char* RawOpcodeName(WasmOpcode opcode) {
   2022   switch (opcode) {
   2023 #define DECLARE_NAME_CASE(name, opcode, sig) \
   2024   case kExpr##name:                          \
   2025     return "kExpr" #name;
   2026     FOREACH_OPCODE(DECLARE_NAME_CASE)
   2027 #undef DECLARE_NAME_CASE
   2028     default:
   2029       break;
   2030   }
   2031   return "Unknown";
   2032 }
   2033 }  // namespace
   2034 
   2035 bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
   2036                       const wasm::WasmModule* module) {
   2037   OFStream os(stdout);
   2038   Zone zone(allocator, ZONE_NAME);
   2039   WasmFullDecoder decoder(&zone, module, body);
   2040   int line_nr = 0;
   2041 
   2042   // Print the function signature.
   2043   if (body.sig) {
   2044     os << "// signature: " << *body.sig << std::endl;
   2045     ++line_nr;
   2046   }
   2047 
   2048   // Print the local declarations.
   2049   BodyLocalDecls decls(&zone);
   2050   BytecodeIterator i(body.start, body.end, &decls);
   2051   if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) {
   2052     os << "// locals: ";
   2053     if (!decls.type_list.empty()) {
   2054       ValueType type = decls.type_list[0];
   2055       uint32_t count = 0;
   2056       for (size_t pos = 0; pos < decls.type_list.size(); ++pos) {
   2057         if (decls.type_list[pos] == type) {
   2058           ++count;
   2059         } else {
   2060           os << " " << count << " " << WasmOpcodes::TypeName(type);
   2061           type = decls.type_list[pos];
   2062           count = 1;
   2063         }
   2064       }
   2065     }
   2066     os << std::endl;
   2067     ++line_nr;
   2068 
   2069     for (const byte* locals = body.start; locals < i.pc(); locals++) {
   2070       os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
   2071     }
   2072     os << std::endl;
   2073     ++line_nr;
   2074   }
   2075 
   2076   os << "// body: " << std::endl;
   2077   ++line_nr;
   2078   unsigned control_depth = 0;
   2079   for (; i.has_next(); i.next()) {
   2080     unsigned length = WasmDecoder::OpcodeLength(&decoder, i.pc());
   2081 
   2082     WasmOpcode opcode = i.current();
   2083     if (opcode == kExprElse) control_depth--;
   2084 
   2085     int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
   2086 
   2087     // 64 whitespaces
   2088     const char* padding =
   2089         "                                                                ";
   2090     os.write(padding, num_whitespaces);
   2091 
   2092     os << RawOpcodeName(opcode) << ",";
   2093 
   2094     for (size_t j = 1; j < length; ++j) {
   2095       os << " 0x" << AsHex(i.pc()[j], 2) << ",";
   2096     }
   2097 
   2098     switch (opcode) {
   2099       case kExprElse:
   2100         os << "   // @" << i.pc_offset();
   2101         control_depth++;
   2102         break;
   2103       case kExprLoop:
   2104       case kExprIf:
   2105       case kExprBlock:
   2106       case kExprTry: {
   2107         BlockTypeOperand operand(&i, i.pc());
   2108         os << "   // @" << i.pc_offset();
   2109         for (unsigned i = 0; i < operand.arity; i++) {
   2110           os << " " << WasmOpcodes::TypeName(operand.read_entry(i));
   2111         }
   2112         control_depth++;
   2113         break;
   2114       }
   2115       case kExprEnd:
   2116         os << "   // @" << i.pc_offset();
   2117         control_depth--;
   2118         break;
   2119       case kExprBr: {
   2120         BreakDepthOperand operand(&i, i.pc());
   2121         os << "   // depth=" << operand.depth;
   2122         break;
   2123       }
   2124       case kExprBrIf: {
   2125         BreakDepthOperand operand(&i, i.pc());
   2126         os << "   // depth=" << operand.depth;
   2127         break;
   2128       }
   2129       case kExprBrTable: {
   2130         BranchTableOperand operand(&i, i.pc());
   2131         os << " // entries=" << operand.table_count;
   2132         break;
   2133       }
   2134       case kExprCallIndirect: {
   2135         CallIndirectOperand operand(&i, i.pc());
   2136         os << "   // sig #" << operand.index;
   2137         if (decoder.Complete(i.pc(), operand)) {
   2138           os << ": " << *operand.sig;
   2139         }
   2140         break;
   2141       }
   2142       case kExprCallFunction: {
   2143         CallFunctionOperand operand(&i, i.pc());
   2144         os << " // function #" << operand.index;
   2145         if (decoder.Complete(i.pc(), operand)) {
   2146           os << ": " << *operand.sig;
   2147         }
   2148         break;
   2149       }
   2150       default:
   2151         break;
   2152     }
   2153     os << std::endl;
   2154     ++line_nr;
   2155   }
   2156 
   2157   return decoder.ok();
   2158 }
   2159 
   2160 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
   2161                                            const byte* start, const byte* end) {
   2162   Decoder decoder(start, end);
   2163   return WasmDecoder::AnalyzeLoopAssignment(&decoder, start,
   2164                                             static_cast<int>(num_locals), zone);
   2165 }
   2166 
   2167 }  // namespace wasm
   2168 }  // namespace internal
   2169 }  // namespace v8
   2170