Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: src/wasm/ast-decoder.h

Issue 2345593003: [wasm] Master CL for Binary 0xC changes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: [wasm] Master CL for Binary 0xC changes. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_WASM_AST_DECODER_H_ 5 #ifndef V8_WASM_AST_DECODER_H_
6 #define V8_WASM_AST_DECODER_H_ 6 #define V8_WASM_AST_DECODER_H_
7 7
8 #include "src/signature.h" 8 #include "src/signature.h"
9 #include "src/wasm/decoder.h" 9 #include "src/wasm/decoder.h"
10 #include "src/wasm/wasm-opcodes.h" 10 #include "src/wasm/wasm-opcodes.h"
11 #include "src/wasm/wasm-result.h" 11 #include "src/wasm/wasm-result.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 class BitVector; // forward declaration 16 class BitVector; // forward declaration
17 17
18 namespace compiler { // external declarations from compiler. 18 namespace compiler { // external declarations from compiler.
19 class WasmGraphBuilder; 19 class WasmGraphBuilder;
20 } 20 }
21 21
22 namespace wasm { 22 namespace wasm {
23 23
24 const uint32_t kMaxNumWasmLocals = 8000000; 24 const uint32_t kMaxNumWasmLocals = 8000000;
25 struct WasmGlobal;
25 26
26 // Helpers for decoding different kinds of operands which follow bytecodes. 27 // Helpers for decoding different kinds of operands which follow bytecodes.
27 struct LocalIndexOperand { 28 struct LocalIndexOperand {
28 uint32_t index; 29 uint32_t index;
29 LocalType type; 30 LocalType type;
30 unsigned length; 31 unsigned length;
31 32
32 inline LocalIndexOperand(Decoder* decoder, const byte* pc) { 33 inline LocalIndexOperand(Decoder* decoder, const byte* pc) {
33 index = decoder->checked_read_u32v(pc, 1, &length, "local index"); 34 index = decoder->checked_read_u32v(pc, 1, &length, "local index");
34 type = kAstStmt; 35 type = kAstStmt;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 unsigned length; 75 unsigned length;
75 inline ImmF64Operand(Decoder* decoder, const byte* pc) { 76 inline ImmF64Operand(Decoder* decoder, const byte* pc) {
76 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64")); 77 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64"));
77 length = 8; 78 length = 8;
78 } 79 }
79 }; 80 };
80 81
81 struct GlobalIndexOperand { 82 struct GlobalIndexOperand {
82 uint32_t index; 83 uint32_t index;
83 LocalType type; 84 LocalType type;
85 const WasmGlobal* global;
84 unsigned length; 86 unsigned length;
85 87
86 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) { 88 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) {
87 index = decoder->checked_read_u32v(pc, 1, &length, "global index"); 89 index = decoder->checked_read_u32v(pc, 1, &length, "global index");
90 global = nullptr;
88 type = kAstStmt; 91 type = kAstStmt;
89 } 92 }
90 }; 93 };
91 94
95 struct BlockTypeOperand {
96 uint32_t arity;
97 const byte* types; // pointer to encoded types for the block.
98 unsigned length;
99
100 inline BlockTypeOperand(Decoder* decoder, const byte* pc) {
101 uint8_t val = decoder->checked_read_u8(pc, 1, "block type");
102 LocalType type = kAstStmt;
103 length = 1;
104 arity = 0;
105 types = nullptr;
106 if (decode_local_type(val, &type)) {
107 arity = type == kAstStmt ? 0 : 1;
108 types = pc + 1;
109 } else {
110 // Handle multi-value blocks.
111 if (!FLAG_wasm_mv_prototype) {
112 decoder->error(pc, pc + 1, "invalid block arity > 1");
113 return;
114 }
115 if (val != kMultivalBlock) {
116 decoder->error(pc, pc + 1, "invalid block type");
117 return;
118 }
119 // Decode and check the types vector of the block.
120 unsigned len = 0;
121 uint32_t count = decoder->checked_read_u32v(pc, 2, &len, "block arity");
122 // {count} is encoded as {arity-2}, so that a {0} count here corresponds
123 // to a block with 2 values. This makes invalid/redundant encodings
124 // impossible.
125 arity = count + 2;
126 length = 1 + len + arity;
127 types = pc + 1 + 1 + len;
128
129 for (uint32_t i = 0; i < arity; i++) {
130 uint32_t offset = 1 + 1 + len + i;
131 val = decoder->checked_read_u8(pc, offset, "block type");
132 decode_local_type(val, &type);
bradnelson 2016/09/23 11:36:00 This function has a weird calling convention. Migh
titzer 2016/09/23 12:07:30 Yeah, it is weird. The problem is that it can't ha
bradn 2016/09/23 15:18:43 Yeah true. Many to few is hard.
133 if (type == kAstStmt) {
134 decoder->error(pc, pc + offset, "invalid block type");
135 return;
136 }
137 }
138 }
139 }
140 // Decode a byte representing a local type. Return {false} if the encoded
141 // byte was invalid.
bradnelson 2016/09/23 11:36:01 Rather invalid or kMultivalBlock ?
titzer 2016/09/23 12:07:30 Done.
142 bool decode_local_type(uint8_t val, LocalType* result) {
143 switch (static_cast<LocalTypeCode>(val)) {
144 case kLocalVoid:
145 *result = kAstStmt;
146 return true;
147 case kLocalI32:
148 *result = kAstI32;
149 return true;
150 case kLocalI64:
151 *result = kAstI64;
152 return true;
153 case kLocalF32:
154 *result = kAstF32;
155 return true;
156 case kLocalF64:
157 *result = kAstF64;
158 return true;
159 default:
160 *result = kAstStmt;
161 return false;
162 }
163 }
164 LocalType read_entry(unsigned index) {
165 DCHECK_LT(index, arity);
166 LocalType result;
167 CHECK(decode_local_type(types[index], &result));
168 return result;
169 }
170 };
171
92 struct Control; 172 struct Control;
93 struct BreakDepthOperand { 173 struct BreakDepthOperand {
94 uint32_t arity;
95 uint32_t depth; 174 uint32_t depth;
96 Control* target; 175 Control* target;
97 unsigned length; 176 unsigned length;
98 inline BreakDepthOperand(Decoder* decoder, const byte* pc) { 177 inline BreakDepthOperand(Decoder* decoder, const byte* pc) {
99 unsigned len1 = 0; 178 depth = decoder->checked_read_u32v(pc, 1, &length, "break depth");
100 unsigned 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;
104 target = nullptr; 179 target = nullptr;
105 } 180 }
106 }; 181 };
107 182
108 struct CallIndirectOperand { 183 struct CallIndirectOperand {
109 uint32_t arity;
110 uint32_t index; 184 uint32_t index;
111 FunctionSig* sig; 185 FunctionSig* sig;
112 unsigned length; 186 unsigned length;
113 inline CallIndirectOperand(Decoder* decoder, const byte* pc) { 187 inline CallIndirectOperand(Decoder* decoder, const byte* pc) {
114 unsigned len1 = 0; 188 unsigned len1 = 0;
115 unsigned len2 = 0; 189 unsigned 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"); 190 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "signature index");
118 length = len1 + len2; 191 length = len1 + len2;
119 sig = nullptr; 192 sig = nullptr;
120 } 193 }
121 }; 194 };
122 195
123 struct CallFunctionOperand { 196 struct CallFunctionOperand {
124 uint32_t arity;
125 uint32_t index; 197 uint32_t index;
126 FunctionSig* sig; 198 FunctionSig* sig;
127 unsigned length; 199 unsigned length;
128 inline CallFunctionOperand(Decoder* decoder, const byte* pc) { 200 inline CallFunctionOperand(Decoder* decoder, const byte* pc) {
129 unsigned len1 = 0; 201 unsigned len1 = 0;
130 unsigned len2 = 0; 202 unsigned 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"); 203 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "function index");
133 length = len1 + len2; 204 length = len1 + len2;
134 sig = nullptr; 205 sig = nullptr;
135 } 206 }
136 }; 207 };
137 208
138 struct CallImportOperand { 209 struct BranchTableOperand {
139 uint32_t arity; 210 uint32_t table_count;
140 uint32_t index; 211 const byte* start;
141 FunctionSig* sig; 212 const byte* table;
142 unsigned length; 213 inline BranchTableOperand(Decoder* decoder, const byte* pc) {
143 inline CallImportOperand(Decoder* decoder, const byte* pc) { 214 DCHECK_EQ(kExprBrTable, decoder->checked_read_u8(pc, 0, "opcode"));
215 start = pc + 1;
144 unsigned len1 = 0; 216 unsigned len1 = 0;
145 unsigned len2 = 0; 217 table_count = decoder->checked_read_u32v(pc, 1, &len1, "table count");
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;
149 sig = nullptr;
150 }
151 };
152
153 struct BranchTableOperand {
154 uint32_t arity;
155 uint32_t table_count;
156 const byte* table;
157 unsigned length;
158 inline BranchTableOperand(Decoder* decoder, const byte* pc) {
159 unsigned len1 = 0;
160 unsigned len2 = 0;
161 arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
162 table_count =
163 decoder->checked_read_u32v(pc, 1 + len1, &len2, "table count");
164 if (table_count > (UINT_MAX / sizeof(uint32_t)) - 1 || 218 if (table_count > (UINT_MAX / sizeof(uint32_t)) - 1 ||
165 len1 + len2 > UINT_MAX - (table_count + 1) * sizeof(uint32_t)) { 219 len1 > UINT_MAX - (table_count + 1) * sizeof(uint32_t)) {
166 decoder->error(pc, "branch table size overflow"); 220 decoder->error(pc, "branch table size overflow");
167 } 221 }
168 length = len1 + len2 + (table_count + 1) * sizeof(uint32_t); 222 table = pc + 1 + len1;
169
170 uint32_t table_start = 1 + len1 + len2;
171 if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t),
172 "expected <table entries>")) {
173 table = pc + table_start;
174 } else {
175 table = nullptr;
176 }
177 } 223 }
178 inline uint32_t read_entry(Decoder* decoder, unsigned i) { 224 inline uint32_t read_entry(Decoder* decoder, unsigned i) {
179 DCHECK(i <= table_count); 225 DCHECK(i <= table_count);
180 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0; 226 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0;
181 } 227 }
182 }; 228 };
183 229
230 // A helper to iterate over a branch table.
231 class BranchTableIterator {
232 public:
233 unsigned cur_index() { return index_; }
234 bool has_next() { return index_ <= table_count_; }
235 uint32_t next() {
236 DCHECK(has_next());
237 index_++;
238 unsigned length = 0;
239 uint32_t result =
240 decoder_->checked_read_u32v(pc_, 0, &length, "branch table entry");
241 pc_ += length;
242 return result;
243 }
244 // length, including the length of the {BranchTableOperand}, but not the
245 // opcode.
246 unsigned length() {
247 while (has_next()) next();
248 return static_cast<unsigned>(pc_ - start_);
249 }
250 const byte* pc() { return pc_; }
251
252 BranchTableIterator(Decoder* decoder, BranchTableOperand& operand)
253 : decoder_(decoder),
254 start_(operand.start),
255 pc_(operand.table),
256 index_(0),
257 table_count_(operand.table_count) {}
258
259 private:
260 Decoder* decoder_;
261 const byte* start_;
262 const byte* pc_;
263 uint32_t index_; // the current index.
264 uint32_t table_count_; // the count of entries, not including default.
265 };
266
184 struct MemoryAccessOperand { 267 struct MemoryAccessOperand {
185 uint32_t alignment; 268 uint32_t alignment;
186 uint32_t offset; 269 uint32_t offset;
187 unsigned length; 270 unsigned length;
188 inline MemoryAccessOperand(Decoder* decoder, const byte* pc, 271 inline MemoryAccessOperand(Decoder* decoder, const byte* pc,
189 uint32_t max_alignment) { 272 uint32_t max_alignment) {
190 unsigned alignment_length; 273 unsigned alignment_length;
191 alignment = 274 alignment =
192 decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment"); 275 decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment");
193 if (max_alignment < alignment) { 276 if (max_alignment < alignment) {
194 decoder->error(pc, pc + 1, 277 decoder->error(pc, pc + 1,
195 "invalid alignment; expected maximum alignment is %u, " 278 "invalid alignment; expected maximum alignment is %u, "
196 "actual alignment is %u", 279 "actual alignment is %u",
197 max_alignment, alignment); 280 max_alignment, alignment);
198 } 281 }
199 unsigned offset_length; 282 unsigned offset_length;
200 offset = decoder->checked_read_u32v(pc, 1 + alignment_length, 283 offset = decoder->checked_read_u32v(pc, 1 + alignment_length,
201 &offset_length, "offset"); 284 &offset_length, "offset");
202 length = alignment_length + offset_length; 285 length = alignment_length + offset_length;
203 } 286 }
204 }; 287 };
205 288
206 struct ReturnArityOperand {
207 uint32_t arity;
208 unsigned length;
209
210 inline ReturnArityOperand(Decoder* decoder, const byte* pc) {
211 arity = decoder->checked_read_u32v(pc, 1, &length, "return count");
212 }
213 };
214
215 typedef compiler::WasmGraphBuilder TFBuilder; 289 typedef compiler::WasmGraphBuilder TFBuilder;
216 struct ModuleEnv; // forward declaration of module interface. 290 struct ModuleEnv; // forward declaration of module interface.
217 291
218 // All of the various data structures necessary to decode a function body. 292 // All of the various data structures necessary to decode a function body.
219 struct FunctionBody { 293 struct FunctionBody {
220 ModuleEnv* module; // module environment 294 ModuleEnv* module; // module environment
221 FunctionSig* sig; // function signature 295 FunctionSig* sig; // function signature
222 const byte* base; // base of the module bytes, for error reporting 296 const byte* base; // base of the module bytes, for error reporting
223 const byte* start; // start of the function body 297 const byte* start; // start of the function body
224 const byte* end; // end of the function body 298 const byte* end; // end of the function body
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 : decls_encoded_size(0), total_local_count(0), local_types(zone) {} 351 : decls_encoded_size(0), total_local_count(0), local_types(zone) {}
278 }; 352 };
279 353
280 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end); 354 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end);
281 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 355 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
282 const byte* start, const byte* end); 356 const byte* start, const byte* end);
283 357
284 // Computes the length of the opcode at the given address. 358 // Computes the length of the opcode at the given address.
285 unsigned OpcodeLength(const byte* pc, const byte* end); 359 unsigned OpcodeLength(const byte* pc, const byte* end);
286 360
287 // Computes the arity (number of sub-nodes) of the opcode at the given address.
288 unsigned OpcodeArity(const byte* pc, const byte* end);
289
290 // A simple forward iterator for bytecodes. 361 // A simple forward iterator for bytecodes.
291 class BytecodeIterator : public Decoder { 362 class BytecodeIterator : public Decoder {
292 public: 363 public:
293 // If one wants to iterate over the bytecode without looking at {pc_offset()}. 364 // If one wants to iterate over the bytecode without looking at {pc_offset()}.
294 class iterator { 365 class iterator {
295 public: 366 public:
296 inline iterator& operator++() { 367 inline iterator& operator++() {
297 DCHECK_LT(ptr_, end_); 368 DCHECK_LT(ptr_, end_);
298 ptr_ += OpcodeLength(ptr_, end_); 369 ptr_ += OpcodeLength(ptr_, end_);
299 return *this; 370 return *this;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 } 409 }
339 410
340 bool has_next() { return pc_ < end_; } 411 bool has_next() { return pc_ < end_; }
341 }; 412 };
342 413
343 } // namespace wasm 414 } // namespace wasm
344 } // namespace internal 415 } // namespace internal
345 } // namespace v8 416 } // namespace v8
346 417
347 #endif // V8_WASM_AST_DECODER_H_ 418 #endif // V8_WASM_AST_DECODER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698