LCOV - code coverage report
Current view: top level - src/wasm - function-body-decoder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 59 98 60.2 %
Date: 2019-04-17 Functions: 9 11 81.8 %

          Line data    Source code
       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/wasm/function-body-decoder.h"
       6             : 
       7             : #include "src/flags.h"
       8             : #include "src/handles.h"
       9             : #include "src/objects-inl.h"
      10             : #include "src/ostreams.h"
      11             : #include "src/wasm/decoder.h"
      12             : #include "src/wasm/function-body-decoder-impl.h"
      13             : #include "src/wasm/wasm-limits.h"
      14             : #include "src/wasm/wasm-linkage.h"
      15             : #include "src/wasm/wasm-module.h"
      16             : #include "src/wasm/wasm-opcodes.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace wasm {
      21             : 
      22      368419 : bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls,
      23             :                       const byte* start, const byte* end) {
      24             :   Decoder decoder(start, end);
      25      368419 :   if (WasmDecoder<Decoder::kValidate>::DecodeLocals(enabled, &decoder, nullptr,
      26             :                                                     &decls->type_list)) {
      27             :     DCHECK(decoder.ok());
      28      368388 :     decls->encoded_size = decoder.pc_offset();
      29      368388 :     return true;
      30             :   }
      31             :   return false;
      32             : }
      33             : 
      34      368327 : BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
      35             :                                    BodyLocalDecls* decls)
      36      368327 :     : Decoder(start, end) {
      37      368327 :   if (decls != nullptr) {
      38      368324 :     if (DecodeLocalDecls(kAllWasmFeatures, decls, start, end)) {
      39      368294 :       pc_ += decls->encoded_size;
      40      368294 :       if (pc_ > end_) pc_ = end_;
      41             :     }
      42             :   }
      43      368327 : }
      44             : 
      45      168185 : DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
      46             :                             const WasmFeatures& enabled,
      47             :                             const WasmModule* module, WasmFeatures* detected,
      48             :                             FunctionBody& body) {
      49      336370 :   Zone zone(allocator, ZONE_NAME);
      50             :   WasmFullDecoder<Decoder::kValidate, EmptyInterface> decoder(
      51             :       &zone, module, enabled, detected, body);
      52      168185 :   decoder.Decode();
      53      504555 :   return decoder.toResult(nullptr);
      54             : }
      55             : 
      56     2011187 : unsigned OpcodeLength(const byte* pc, const byte* end) {
      57             :   Decoder decoder(pc, end);
      58     2011187 :   return WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, pc);
      59             : }
      60             : 
      61     1987016 : std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
      62             :                                           FunctionSig* sig, const byte* pc,
      63             :                                           const byte* end) {
      64     1987016 :   WasmFeatures unused_detected_features;
      65             :   WasmDecoder<Decoder::kNoValidate> decoder(
      66             :       module, kAllWasmFeatures, &unused_detected_features, sig, pc, end);
      67     3974032 :   return decoder.StackEffect(pc);
      68             : }
      69             : 
      70           0 : void PrintRawWasmCode(const byte* start, const byte* end) {
      71           0 :   AccountingAllocator allocator;
      72           0 :   PrintRawWasmCode(&allocator, FunctionBody{nullptr, 0, start, end}, nullptr,
      73           0 :                    kPrintLocals);
      74           0 : }
      75             : 
      76             : namespace {
      77          32 : const char* RawOpcodeName(WasmOpcode opcode) {
      78          32 :   switch (opcode) {
      79             : #define DECLARE_NAME_CASE(name, opcode, sig) \
      80             :   case kExpr##name:                          \
      81             :     return "kExpr" #name;
      82           0 :     FOREACH_OPCODE(DECLARE_NAME_CASE)
      83             : #undef DECLARE_NAME_CASE
      84             :     default:
      85             :       break;
      86             :   }
      87           0 :   return "Unknown";
      88             : }
      89             : }  // namespace
      90             : 
      91           0 : bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
      92             :                       const WasmModule* module, PrintLocals print_locals) {
      93           0 :   StdoutStream os;
      94           0 :   return PrintRawWasmCode(allocator, body, module, print_locals, os);
      95             : }
      96             : 
      97           8 : bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
      98             :                       const WasmModule* module, PrintLocals print_locals,
      99             :                       std::ostream& os, std::vector<int>* line_numbers) {
     100          16 :   Zone zone(allocator, ZONE_NAME);
     101           8 :   WasmFeatures unused_detected_features;
     102             :   WasmDecoder<Decoder::kNoValidate> decoder(module, kAllWasmFeatures,
     103           8 :                                             &unused_detected_features, body.sig,
     104           8 :                                             body.start, body.end);
     105             :   int line_nr = 0;
     106           8 :   constexpr int kNoByteCode = -1;
     107             : 
     108             :   // Print the function signature.
     109           8 :   if (body.sig) {
     110           8 :     os << "// signature: " << *body.sig << std::endl;
     111           8 :     if (line_numbers) line_numbers->push_back(kNoByteCode);
     112             :     ++line_nr;
     113             :   }
     114             : 
     115             :   // Print the local declarations.
     116             :   BodyLocalDecls decls(&zone);
     117           8 :   BytecodeIterator i(body.start, body.end, &decls);
     118           8 :   if (body.start != i.pc() && print_locals == kPrintLocals) {
     119           8 :     os << "// locals:";
     120           8 :     if (!decls.type_list.empty()) {
     121           0 :       ValueType type = decls.type_list[0];
     122             :       uint32_t count = 0;
     123           0 :       for (size_t pos = 0; pos < decls.type_list.size(); ++pos) {
     124           0 :         if (decls.type_list[pos] == type) {
     125           0 :           ++count;
     126             :         } else {
     127           0 :           os << " " << count << " " << ValueTypes::TypeName(type);
     128           0 :           type = decls.type_list[pos];
     129             :           count = 1;
     130             :         }
     131             :       }
     132           0 :       os << " " << count << " " << ValueTypes::TypeName(type);
     133             :     }
     134             :     os << std::endl;
     135           8 :     if (line_numbers) line_numbers->push_back(kNoByteCode);
     136             :     ++line_nr;
     137             : 
     138          16 :     for (const byte* locals = body.start; locals < i.pc(); locals++) {
     139          16 :       os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
     140             :     }
     141             :     os << std::endl;
     142           8 :     if (line_numbers) line_numbers->push_back(kNoByteCode);
     143             :     ++line_nr;
     144             :   }
     145             : 
     146             :   os << "// body: " << std::endl;
     147           8 :   if (line_numbers) line_numbers->push_back(kNoByteCode);
     148             :   ++line_nr;
     149             :   unsigned control_depth = 0;
     150          72 :   for (; i.has_next(); i.next()) {
     151             :     unsigned length =
     152          32 :         WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, i.pc());
     153             : 
     154             :     WasmOpcode opcode = i.current();
     155          96 :     if (line_numbers) line_numbers->push_back(i.position());
     156          32 :     if (opcode == kExprElse || opcode == kExprCatch) {
     157           0 :       control_depth--;
     158             :     }
     159             : 
     160          32 :     int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
     161             : 
     162             :     // 64 whitespaces
     163             :     const char* padding =
     164             :         "                                                                ";
     165          32 :     os.write(padding, num_whitespaces);
     166             : 
     167          32 :     os << RawOpcodeName(opcode) << ",";
     168             : 
     169          64 :     if (opcode == kExprLoop || opcode == kExprIf || opcode == kExprBlock ||
     170          32 :         opcode == kExprTry) {
     171             :       DCHECK_EQ(2, length);
     172             : 
     173           0 :       switch (i.pc()[1]) {
     174             : #define CASE_LOCAL_TYPE(local_name, type_name) \
     175             :   case kLocal##local_name:                     \
     176             :     os << " kWasm" #type_name ",";             \
     177             :     break;
     178             : 
     179           0 :         CASE_LOCAL_TYPE(I32, I32)
     180           0 :         CASE_LOCAL_TYPE(I64, I64)
     181           0 :         CASE_LOCAL_TYPE(F32, F32)
     182           0 :         CASE_LOCAL_TYPE(F64, F64)
     183           0 :         CASE_LOCAL_TYPE(S128, S128)
     184           0 :         CASE_LOCAL_TYPE(Void, Stmt)
     185             :         default:
     186           0 :           os << " 0x" << AsHex(i.pc()[1], 2) << ",";
     187           0 :           break;
     188             :       }
     189             : #undef CASE_LOCAL_TYPE
     190             :     } else {
     191          64 :       for (unsigned j = 1; j < length; ++j) {
     192          32 :         os << " 0x" << AsHex(i.pc()[j], 2) << ",";
     193             :       }
     194             :     }
     195             : 
     196          32 :     switch (opcode) {
     197             :       case kExprElse:
     198             :       case kExprCatch:
     199             :         os << "   // @" << i.pc_offset();
     200           0 :         control_depth++;
     201           0 :         break;
     202             :       case kExprLoop:
     203             :       case kExprIf:
     204             :       case kExprBlock:
     205             :       case kExprTry: {
     206             :         BlockTypeImmediate<Decoder::kNoValidate> imm(kAllWasmFeatures, &i,
     207           0 :                                                      i.pc());
     208             :         os << "   // @" << i.pc_offset();
     209             :         if (decoder.Complete(imm)) {
     210           0 :           for (uint32_t i = 0; i < imm.out_arity(); i++) {
     211           0 :             os << " " << ValueTypes::TypeName(imm.out_type(i));
     212             :           }
     213             :         }
     214           0 :         control_depth++;
     215             :         break;
     216             :       }
     217             :       case kExprEnd:
     218             :         os << "   // @" << i.pc_offset();
     219           8 :         control_depth--;
     220           8 :         break;
     221             :       case kExprBr: {
     222             :         BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc());
     223             :         os << "   // depth=" << imm.depth;
     224             :         break;
     225             :       }
     226             :       case kExprBrIf: {
     227             :         BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc());
     228             :         os << "   // depth=" << imm.depth;
     229             :         break;
     230             :       }
     231             :       case kExprBrTable: {
     232           0 :         BranchTableImmediate<Decoder::kNoValidate> imm(&i, i.pc());
     233           0 :         os << " // entries=" << imm.table_count;
     234             :         break;
     235             :       }
     236             :       case kExprCallIndirect: {
     237             :         CallIndirectImmediate<Decoder::kNoValidate> imm(kAllWasmFeatures, &i,
     238           0 :                                                         i.pc());
     239           0 :         os << "   // sig #" << imm.sig_index;
     240             :         if (decoder.Complete(i.pc(), imm)) {
     241           0 :           os << ": " << *imm.sig;
     242             :         }
     243             :         break;
     244             :       }
     245             :       case kExprCallFunction: {
     246             :         CallFunctionImmediate<Decoder::kNoValidate> imm(&i, i.pc());
     247             :         os << " // function #" << imm.index;
     248             :         if (decoder.Complete(i.pc(), imm)) {
     249           0 :           os << ": " << *imm.sig;
     250             :         }
     251             :         break;
     252             :       }
     253             :       default:
     254             :         break;
     255             :     }
     256             :     os << std::endl;
     257             :     ++line_nr;
     258             :   }
     259             :   DCHECK(!line_numbers || line_numbers->size() == static_cast<size_t>(line_nr));
     260             : 
     261           8 :   return decoder.ok();
     262             : }
     263             : 
     264          78 : BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
     265             :                                            const byte* start, const byte* end) {
     266             :   Decoder decoder(start, end);
     267          78 :   return WasmDecoder<Decoder::kValidate>::AnalyzeLoopAssignment(
     268         156 :       &decoder, start, static_cast<uint32_t>(num_locals), zone);
     269             : }
     270             : 
     271             : }  // namespace wasm
     272             : }  // namespace internal
     273      122004 : }  // namespace v8

Generated by: LCOV version 1.10