LCOV - code coverage report
Current view: top level - src/wasm - function-body-decoder.h (source / functions) Hit Total Coverage
Test: app.info Lines: 23 24 95.8 %
Date: 2017-10-20 Functions: 5 8 62.5 %

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

Generated by: LCOV version 1.10