LCOV - code coverage report
Current view: top level - src/wasm - function-body-decoder.h (source / functions) Hit Total Coverage
Test: app.info Lines: 16 16 100.0 %
Date: 2019-04-17 Functions: 4 6 66.7 %

          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             : #ifndef V8_WASM_FUNCTION_BODY_DECODER_H_
       6             : #define V8_WASM_FUNCTION_BODY_DECODER_H_
       7             : 
       8             : #include "src/base/compiler-specific.h"
       9             : #include "src/base/iterator.h"
      10             : #include "src/globals.h"
      11             : #include "src/wasm/decoder.h"
      12             : #include "src/wasm/wasm-opcodes.h"
      13             : #include "src/wasm/wasm-result.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18             : class BitVector;  // forward declaration
      19             : 
      20             : namespace wasm {
      21             : 
      22             : struct WasmModule;  // forward declaration of module interface.
      23             : struct WasmFeatures;
      24             : 
      25             : // A wrapper around the signature and bytes of a function.
      26             : struct FunctionBody {
      27             :   FunctionSig* sig;   // function signature
      28             :   uint32_t offset;    // offset in the module bytes, for error reporting
      29             :   const byte* start;  // start of the function body
      30             :   const byte* end;    // end of the function body
      31             : 
      32             :   FunctionBody(FunctionSig* sig, uint32_t offset, const byte* start,
      33             :                const byte* end)
      34     1241675 :       : sig(sig), offset(offset), start(start), end(end) {}
      35             : };
      36             : 
      37             : V8_EXPORT_PRIVATE DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
      38             :                                               const WasmFeatures& enabled,
      39             :                                               const WasmModule* module,
      40             :                                               WasmFeatures* detected,
      41             :                                               FunctionBody& body);
      42             : 
      43             : enum PrintLocals { kPrintLocals, kOmitLocals };
      44             : V8_EXPORT_PRIVATE
      45             : bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
      46             :                       const WasmModule* module, PrintLocals print_locals);
      47             : 
      48             : V8_EXPORT_PRIVATE
      49             : bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
      50             :                       const WasmModule* module, PrintLocals print_locals,
      51             :                       std::ostream& out,
      52             :                       std::vector<int>* line_numbers = nullptr);
      53             : 
      54             : // A simplified form of AST printing, e.g. from a debugger.
      55             : void PrintRawWasmCode(const byte* start, const byte* end);
      56             : 
      57      747194 : struct BodyLocalDecls {
      58             :   // The size of the encoded declarations.
      59             :   uint32_t encoded_size = 0;  // size of encoded declarations
      60             : 
      61             :   ZoneVector<ValueType> type_list;
      62             : 
      63         264 :   explicit BodyLocalDecls(Zone* zone) : type_list(zone) {}
      64             : };
      65             : 
      66             : V8_EXPORT_PRIVATE bool DecodeLocalDecls(const WasmFeatures& enabled,
      67             :                                         BodyLocalDecls* decls,
      68             :                                         const byte* start, const byte* end);
      69             : 
      70             : V8_EXPORT_PRIVATE BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone,
      71             :                                                              size_t num_locals,
      72             :                                                              const byte* start,
      73             :                                                              const byte* end);
      74             : 
      75             : // Computes the length of the opcode at the given address.
      76             : V8_EXPORT_PRIVATE unsigned OpcodeLength(const byte* pc, const byte* end);
      77             : 
      78             : // Computes the stack effect of the opcode at the given address.
      79             : // Returns <pop count, push count>.
      80             : // Be cautious with control opcodes: This function only covers their immediate,
      81             : // local stack effect (e.g. BrIf pops 1, Br pops 0). Those opcodes can have
      82             : // non-local stack effect though, which are not covered here.
      83             : std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
      84             :                                           FunctionSig* sig, const byte* pc,
      85             :                                           const byte* end);
      86             : 
      87             : // A simple forward iterator for bytecodes.
      88      736654 : class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
      89             :   // Base class for both iterators defined below.
      90             :   class iterator_base {
      91             :    public:
      92             :     inline iterator_base& operator++() {
      93             :       DCHECK_LT(ptr_, end_);
      94         322 :       ptr_ += OpcodeLength(ptr_, end_);
      95             :       return *this;
      96             :     }
      97             :     inline bool operator==(const iterator_base& that) {
      98             :       return this->ptr_ == that.ptr_;
      99             :     }
     100             :     inline bool operator!=(const iterator_base& that) {
     101             :       return this->ptr_ != that.ptr_;
     102             :     }
     103             : 
     104             :    protected:
     105             :     const byte* ptr_;
     106             :     const byte* end_;
     107             :     iterator_base(const byte* ptr, const byte* end) : ptr_(ptr), end_(end) {}
     108             :   };
     109             : 
     110             :  public:
     111             :   // If one wants to iterate over the bytecode without looking at {pc_offset()}.
     112             :   class opcode_iterator
     113             :       : public iterator_base,
     114             :         public base::iterator<std::input_iterator_tag, WasmOpcode> {
     115             :    public:
     116             :     inline WasmOpcode operator*() {
     117             :       DCHECK_LT(ptr_, end_);
     118           6 :       return static_cast<WasmOpcode>(*ptr_);
     119             :     }
     120             : 
     121             :    private:
     122             :     friend class BytecodeIterator;
     123             :     opcode_iterator(const byte* ptr, const byte* end)
     124             :         : iterator_base(ptr, end) {}
     125             :   };
     126             :   // If one wants to iterate over the instruction offsets without looking at
     127             :   // opcodes.
     128             :   class offset_iterator
     129             :       : public iterator_base,
     130             :         public base::iterator<std::input_iterator_tag, uint32_t> {
     131             :    public:
     132             :     inline uint32_t operator*() {
     133             :       DCHECK_LT(ptr_, end_);
     134         320 :       return static_cast<uint32_t>(ptr_ - start_);
     135             :     }
     136             : 
     137             :    private:
     138             :     const byte* start_;
     139             :     friend class BytecodeIterator;
     140             :     offset_iterator(const byte* start, const byte* ptr, const byte* end)
     141             :         : iterator_base(ptr, end), start_(start) {}
     142             :   };
     143             : 
     144             :   // Create a new {BytecodeIterator}. If the {decls} pointer is non-null,
     145             :   // assume the bytecode starts with local declarations and decode them.
     146             :   // Otherwise, do not decode local decls.
     147             :   BytecodeIterator(const byte* start, const byte* end,
     148             :                    BodyLocalDecls* decls = nullptr);
     149             : 
     150             :   base::iterator_range<opcode_iterator> opcodes() {
     151             :     return base::iterator_range<opcode_iterator>(opcode_iterator(pc_, end_),
     152             :                                                  opcode_iterator(end_, end_));
     153             :   }
     154             : 
     155             :   base::iterator_range<offset_iterator> offsets() {
     156             :     return base::iterator_range<offset_iterator>(
     157             :         offset_iterator(start_, pc_, end_),
     158          74 :         offset_iterator(start_, end_, end_));
     159             :   }
     160             : 
     161             :   WasmOpcode current() {
     162             :     return static_cast<WasmOpcode>(
     163     2010545 :         read_u8<Decoder::kNoValidate>(pc_, "expected bytecode"));
     164             :   }
     165             : 
     166     2010545 :   void next() {
     167     2010545 :     if (pc_ < end_) {
     168     2010545 :       pc_ += OpcodeLength(pc_, end_);
     169     2010545 :       if (pc_ >= end_) pc_ = end_;
     170             :     }
     171     2010545 :   }
     172             : 
     173           2 :   bool has_next() { return pc_ < end_; }
     174             : 
     175             :   WasmOpcode prefixed_opcode() {
     176             :     byte prefix = read_u8<Decoder::kNoValidate>(pc_, "expected prefix");
     177             :     byte index = read_u8<Decoder::kNoValidate>(pc_ + 1, "expected index");
     178       15740 :     return static_cast<WasmOpcode>(prefix << 8 | index);
     179             :   }
     180             : };
     181             : 
     182             : }  // namespace wasm
     183             : }  // namespace internal
     184             : }  // namespace v8
     185             : 
     186             : #endif  // V8_WASM_FUNCTION_BODY_DECODER_H_

Generated by: LCOV version 1.10