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