blob: 5376e7bfdd9db7ab6e0521726b77c77e9f9013bc [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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_AST_DECODER_H_
6#define V8_WASM_AST_DECODER_H_
7
8#include "src/signature.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +01009#include "src/wasm/decoder.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/wasm/wasm-opcodes.h"
11#include "src/wasm/wasm-result.h"
12
13namespace v8 {
14namespace internal {
15
Ben Murdoch097c5b22016-05-18 11:27:45 +010016class BitVector; // forward declaration
17
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018namespace compiler { // external declarations from compiler.
19class WasmGraphBuilder;
20}
21
22namespace wasm {
23
Ben Murdoch097c5b22016-05-18 11:27:45 +010024// Helpers for decoding different kinds of operands which follow bytecodes.
25struct LocalIndexOperand {
26 uint32_t index;
27 LocalType type;
28 int length;
29
30 inline LocalIndexOperand(Decoder* decoder, const byte* pc) {
31 index = decoder->checked_read_u32v(pc, 1, &length, "local index");
32 type = kAstStmt;
33 }
34};
35
36struct ImmI8Operand {
37 int8_t value;
38 int length;
39 inline ImmI8Operand(Decoder* decoder, const byte* pc) {
40 value = bit_cast<int8_t>(decoder->checked_read_u8(pc, 1, "immi8"));
41 length = 1;
42 }
43};
44
45struct ImmI32Operand {
46 int32_t value;
47 int length;
48 inline ImmI32Operand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +010049 value = decoder->checked_read_i32v(pc, 1, &length, "immi32");
Ben Murdoch097c5b22016-05-18 11:27:45 +010050 }
51};
52
53struct ImmI64Operand {
54 int64_t value;
55 int length;
56 inline ImmI64Operand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +010057 value = decoder->checked_read_i64v(pc, 1, &length, "immi64");
Ben Murdoch097c5b22016-05-18 11:27:45 +010058 }
59};
60
61struct ImmF32Operand {
62 float value;
63 int length;
64 inline ImmF32Operand(Decoder* decoder, const byte* pc) {
65 value = bit_cast<float>(decoder->checked_read_u32(pc, 1, "immf32"));
66 length = 4;
67 }
68};
69
70struct ImmF64Operand {
71 double value;
72 int length;
73 inline ImmF64Operand(Decoder* decoder, const byte* pc) {
74 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64"));
75 length = 8;
76 }
77};
78
79struct GlobalIndexOperand {
80 uint32_t index;
81 LocalType type;
82 MachineType machine_type;
83 int length;
84
85 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) {
86 index = decoder->checked_read_u32v(pc, 1, &length, "global index");
87 type = kAstStmt;
88 machine_type = MachineType::None();
89 }
90};
91
92struct Block;
93struct BreakDepthOperand {
94 uint32_t depth;
95 Block* target;
96 int length;
97 inline BreakDepthOperand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +010098 depth = decoder->checked_read_u32v(pc, 1, &length, "break depth");
Ben Murdoch097c5b22016-05-18 11:27:45 +010099 target = nullptr;
100 }
101};
102
103struct BlockCountOperand {
104 uint32_t count;
105 int length;
106 inline BlockCountOperand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +0100107 count = decoder->checked_read_u32v(pc, 1, &length, "block count");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100108 }
109};
110
111struct SignatureIndexOperand {
112 uint32_t index;
113 FunctionSig* sig;
114 int length;
115 inline SignatureIndexOperand(Decoder* decoder, const byte* pc) {
116 index = decoder->checked_read_u32v(pc, 1, &length, "signature index");
117 sig = nullptr;
118 }
119};
120
121struct FunctionIndexOperand {
122 uint32_t index;
123 FunctionSig* sig;
124 int length;
125 inline FunctionIndexOperand(Decoder* decoder, const byte* pc) {
126 index = decoder->checked_read_u32v(pc, 1, &length, "function index");
127 sig = nullptr;
128 }
129};
130
131struct ImportIndexOperand {
132 uint32_t index;
133 FunctionSig* sig;
134 int length;
135 inline ImportIndexOperand(Decoder* decoder, const byte* pc) {
136 index = decoder->checked_read_u32v(pc, 1, &length, "import index");
137 sig = nullptr;
138 }
139};
140
Ben Murdochda12d292016-06-02 14:46:10 +0100141struct BranchTableOperand {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100142 uint32_t table_count;
143 const byte* table;
144 int length;
Ben Murdochda12d292016-06-02 14:46:10 +0100145 inline BranchTableOperand(Decoder* decoder, const byte* pc) {
146 int varint_length;
147 table_count =
148 decoder->checked_read_u32v(pc, 1, &varint_length, "expected #entries");
149 length = varint_length + (table_count + 1) * sizeof(uint32_t);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100150
Ben Murdochda12d292016-06-02 14:46:10 +0100151 uint32_t table_start = 1 + varint_length;
152 if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t),
153 "expected <table entries>")) {
154 table = pc + table_start;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100155 } else {
156 table = nullptr;
157 }
158 }
Ben Murdochda12d292016-06-02 14:46:10 +0100159 inline uint32_t read_entry(Decoder* decoder, int i) {
160 DCHECK(i >= 0 && static_cast<uint32_t>(i) <= table_count);
161 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100162 }
163};
164
165struct MemoryAccessOperand {
Ben Murdochda12d292016-06-02 14:46:10 +0100166 uint32_t alignment;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100167 uint32_t offset;
168 int length;
169 inline MemoryAccessOperand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +0100170 int alignment_length;
171 alignment =
172 decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment");
173 int offset_length;
174 offset = decoder->checked_read_u32v(pc, 1 + alignment_length,
175 &offset_length, "offset");
176 length = alignment_length + offset_length;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100177 }
178};
179
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180typedef compiler::WasmGraphBuilder TFBuilder;
181struct ModuleEnv; // forward declaration of module interface.
182
Ben Murdochda12d292016-06-02 14:46:10 +0100183// All of the various data structures necessary to decode a function body.
184struct FunctionBody {
185 ModuleEnv* module; // module environment
186 FunctionSig* sig; // function signature
187 const byte* base; // base of the module bytes, for error reporting
188 const byte* start; // start of the function body
189 const byte* end; // end of the function body
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190};
191
192struct Tree;
193typedef Result<Tree*> TreeResult;
194
195std::ostream& operator<<(std::ostream& os, const Tree& tree);
196
Ben Murdochda12d292016-06-02 14:46:10 +0100197TreeResult VerifyWasmCode(base::AccountingAllocator* allocator,
198 FunctionBody& body);
199TreeResult BuildTFGraph(base::AccountingAllocator* allocator,
200 TFBuilder* builder, FunctionBody& body);
201void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202
Ben Murdochda12d292016-06-02 14:46:10 +0100203inline TreeResult VerifyWasmCode(base::AccountingAllocator* allocator,
204 ModuleEnv* module, FunctionSig* sig,
205 const byte* start, const byte* end) {
206 FunctionBody body = {module, sig, nullptr, start, end};
207 return VerifyWasmCode(allocator, body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000208}
209
Ben Murdochda12d292016-06-02 14:46:10 +0100210inline TreeResult BuildTFGraph(base::AccountingAllocator* allocator,
211 TFBuilder* builder, ModuleEnv* module,
212 FunctionSig* sig, const byte* start,
213 const byte* end) {
214 FunctionBody body = {module, sig, nullptr, start, end};
215 return BuildTFGraph(allocator, builder, body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216}
217
218enum ReadUnsignedLEB128ErrorCode { kNoError, kInvalidLEB128, kMissingLEB128 };
219
220ReadUnsignedLEB128ErrorCode ReadUnsignedLEB128Operand(const byte*, const byte*,
221 int*, uint32_t*);
222
Ben Murdochda12d292016-06-02 14:46:10 +0100223struct AstLocalDecls {
224 // The size of the encoded declarations.
225 uint32_t decls_encoded_size; // size of encoded declarations
226
227 // Total number of locals.
228 uint32_t total_local_count;
229
230 // List of {local type, count} pairs.
231 ZoneVector<std::pair<LocalType, uint32_t>> local_types;
232
233 // Constructor initializes the vector.
234 explicit AstLocalDecls(Zone* zone)
235 : decls_encoded_size(0), total_local_count(0), local_types(zone) {}
236};
237
238bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end);
239BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100240 const byte* start, const byte* end);
241
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242// Computes the length of the opcode at the given address.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100243int OpcodeLength(const byte* pc, const byte* end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244
245// Computes the arity (number of sub-nodes) of the opcode at the given address.
Ben Murdochda12d292016-06-02 14:46:10 +0100246int OpcodeArity(ModuleEnv* module, FunctionSig* sig, const byte* pc,
247 const byte* end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000248} // namespace wasm
249} // namespace internal
250} // namespace v8
251
252#endif // V8_WASM_AST_DECODER_H_