V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
function-body-decoder.h
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  : 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 
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  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 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  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()}.
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  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.
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  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 
152  opcode_iterator(end_, end_));
153  }
154 
157  offset_iterator(start_, pc_, end_),
158  offset_iterator(start_, end_, end_));
159  }
160 
161  WasmOpcode current() {
162  return static_cast<WasmOpcode>(
163  read_u8<Decoder::kNoValidate>(pc_, "expected bytecode"));
164  }
165 
166  void next() {
167  if (pc_ < end_) {
168  pc_ += OpcodeLength(pc_, end_);
169  if (pc_ >= end_) pc_ = end_;
170  }
171  }
172 
173  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  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_
Definition: libplatform.h:13