blob: 9e96053a6ce035773fbe9f992e24d2f0e8430c35 [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
Ben Murdochc5610432016-08-08 18:44:38 +010092struct Control;
Ben Murdoch097c5b22016-05-18 11:27:45 +010093struct BreakDepthOperand {
Ben Murdochc5610432016-08-08 18:44:38 +010094 uint32_t arity;
Ben Murdoch097c5b22016-05-18 11:27:45 +010095 uint32_t depth;
Ben Murdochc5610432016-08-08 18:44:38 +010096 Control* target;
Ben Murdoch097c5b22016-05-18 11:27:45 +010097 int length;
98 inline BreakDepthOperand(Decoder* decoder, const byte* pc) {
Ben Murdochc5610432016-08-08 18:44:38 +010099 int len1 = 0;
100 int len2 = 0;
101 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
102 depth = decoder->checked_read_u32v(pc, 1 + len1, &len2, "break depth");
103 length = len1 + len2;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 target = nullptr;
105 }
106};
107
Ben Murdochc5610432016-08-08 18:44:38 +0100108struct CallIndirectOperand {
109 uint32_t arity;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110 uint32_t index;
111 FunctionSig* sig;
112 int length;
Ben Murdochc5610432016-08-08 18:44:38 +0100113 inline CallIndirectOperand(Decoder* decoder, const byte* pc) {
114 int len1 = 0;
115 int len2 = 0;
116 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
117 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "signature index");
118 length = len1 + len2;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100119 sig = nullptr;
120 }
121};
122
Ben Murdochc5610432016-08-08 18:44:38 +0100123struct CallFunctionOperand {
124 uint32_t arity;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100125 uint32_t index;
126 FunctionSig* sig;
127 int length;
Ben Murdochc5610432016-08-08 18:44:38 +0100128 inline CallFunctionOperand(Decoder* decoder, const byte* pc) {
129 int len1 = 0;
130 int len2 = 0;
131 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
132 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "function index");
133 length = len1 + len2;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100134 sig = nullptr;
135 }
136};
137
Ben Murdochc5610432016-08-08 18:44:38 +0100138struct CallImportOperand {
139 uint32_t arity;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100140 uint32_t index;
141 FunctionSig* sig;
142 int length;
Ben Murdochc5610432016-08-08 18:44:38 +0100143 inline CallImportOperand(Decoder* decoder, const byte* pc) {
144 int len1 = 0;
145 int len2 = 0;
146 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
147 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "import index");
148 length = len1 + len2;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100149 sig = nullptr;
150 }
151};
152
Ben Murdochda12d292016-06-02 14:46:10 +0100153struct BranchTableOperand {
Ben Murdochc5610432016-08-08 18:44:38 +0100154 uint32_t arity;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100155 uint32_t table_count;
156 const byte* table;
157 int length;
Ben Murdochda12d292016-06-02 14:46:10 +0100158 inline BranchTableOperand(Decoder* decoder, const byte* pc) {
Ben Murdochc5610432016-08-08 18:44:38 +0100159 int len1 = 0;
160 int len2 = 0;
161 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
Ben Murdochda12d292016-06-02 14:46:10 +0100162 table_count =
Ben Murdochc5610432016-08-08 18:44:38 +0100163 decoder->checked_read_u32v(pc, 1 + len1, &len2, "table count");
164 length = len1 + len2 + (table_count + 1) * sizeof(uint32_t);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100165
Ben Murdochc5610432016-08-08 18:44:38 +0100166 uint32_t table_start = 1 + len1 + len2;
Ben Murdochda12d292016-06-02 14:46:10 +0100167 if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t),
168 "expected <table entries>")) {
169 table = pc + table_start;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100170 } else {
171 table = nullptr;
172 }
173 }
Ben Murdochda12d292016-06-02 14:46:10 +0100174 inline uint32_t read_entry(Decoder* decoder, int i) {
175 DCHECK(i >= 0 && static_cast<uint32_t>(i) <= table_count);
176 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100177 }
178};
179
180struct MemoryAccessOperand {
Ben Murdochda12d292016-06-02 14:46:10 +0100181 uint32_t alignment;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100182 uint32_t offset;
183 int length;
184 inline MemoryAccessOperand(Decoder* decoder, const byte* pc) {
Ben Murdochda12d292016-06-02 14:46:10 +0100185 int alignment_length;
186 alignment =
187 decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment");
188 int offset_length;
189 offset = decoder->checked_read_u32v(pc, 1 + alignment_length,
190 &offset_length, "offset");
191 length = alignment_length + offset_length;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100192 }
193};
194
Ben Murdochc5610432016-08-08 18:44:38 +0100195struct ReturnArityOperand {
196 uint32_t arity;
197 int length;
198
199 inline ReturnArityOperand(Decoder* decoder, const byte* pc) {
200 arity = decoder->checked_read_u32v(pc, 1, &length, "return count");
201 }
202};
203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204typedef compiler::WasmGraphBuilder TFBuilder;
205struct ModuleEnv; // forward declaration of module interface.
206
Ben Murdochda12d292016-06-02 14:46:10 +0100207// All of the various data structures necessary to decode a function body.
208struct FunctionBody {
209 ModuleEnv* module; // module environment
210 FunctionSig* sig; // function signature
211 const byte* base; // base of the module bytes, for error reporting
212 const byte* start; // start of the function body
213 const byte* end; // end of the function body
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214};
215
216struct Tree;
217typedef Result<Tree*> TreeResult;
218
219std::ostream& operator<<(std::ostream& os, const Tree& tree);
220
Ben Murdochda12d292016-06-02 14:46:10 +0100221TreeResult VerifyWasmCode(base::AccountingAllocator* allocator,
222 FunctionBody& body);
223TreeResult BuildTFGraph(base::AccountingAllocator* allocator,
224 TFBuilder* builder, FunctionBody& body);
225void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226
Ben Murdochc5610432016-08-08 18:44:38 +0100227// A simplified form of AST printing, e.g. from a debugger.
228void PrintAstForDebugging(const byte* start, const byte* end);
229
Ben Murdochda12d292016-06-02 14:46:10 +0100230inline TreeResult VerifyWasmCode(base::AccountingAllocator* allocator,
231 ModuleEnv* module, FunctionSig* sig,
232 const byte* start, const byte* end) {
233 FunctionBody body = {module, sig, nullptr, start, end};
234 return VerifyWasmCode(allocator, body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000235}
236
Ben Murdochda12d292016-06-02 14:46:10 +0100237inline TreeResult BuildTFGraph(base::AccountingAllocator* allocator,
238 TFBuilder* builder, ModuleEnv* module,
239 FunctionSig* sig, const byte* start,
240 const byte* end) {
241 FunctionBody body = {module, sig, nullptr, start, end};
242 return BuildTFGraph(allocator, builder, body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243}
244
Ben Murdochda12d292016-06-02 14:46:10 +0100245struct AstLocalDecls {
246 // The size of the encoded declarations.
247 uint32_t decls_encoded_size; // size of encoded declarations
248
249 // Total number of locals.
250 uint32_t total_local_count;
251
252 // List of {local type, count} pairs.
253 ZoneVector<std::pair<LocalType, uint32_t>> local_types;
254
255 // Constructor initializes the vector.
256 explicit AstLocalDecls(Zone* zone)
257 : decls_encoded_size(0), total_local_count(0), local_types(zone) {}
258};
259
260bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end);
261BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100262 const byte* start, const byte* end);
263
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000264// Computes the length of the opcode at the given address.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100265int OpcodeLength(const byte* pc, const byte* end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000266
267// Computes the arity (number of sub-nodes) of the opcode at the given address.
Ben Murdochc5610432016-08-08 18:44:38 +0100268int OpcodeArity(const byte* pc, const byte* end);
269
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270} // namespace wasm
271} // namespace internal
272} // namespace v8
273
274#endif // V8_WASM_AST_DECODER_H_