OLD | NEW |
---|---|
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 Loading... | |
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; | |
ahaas
2016/09/16 11:21:31
What does {types} actually contain? I'm quite sure
titzer
2016/09/16 12:13:21
It points to the first byte where the encoded type
ahaas
2016/09/19 11:36:02
Could you add that as a comment, or call it start_
| |
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; | |
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 { | |
ahaas
2016/09/16 11:21:31
Could you add a comment about what is happening in
titzer
2016/09/16 12:13:21
Done.
| |
110 if (!FLAG_wasm_mv_prototype) { | |
111 decoder->error(pc, pc + 1, "invalid block arity > 1"); | |
112 return; | |
113 } | |
114 if (val != kMultivalBlock) { | |
115 decoder->error(pc, pc + 1, "invalid block type"); | |
116 return; | |
117 } | |
118 unsigned len = 0; | |
119 uint32_t count = decoder->checked_read_u32v(pc, 2, &len, "block arity"); | |
120 arity = count + 2; | |
ahaas
2016/09/16 11:21:31
please add a comment why arity = count + 2
titzer
2016/09/16 12:13:21
Done.
| |
121 length = 1 + len + arity; | |
122 types = pc + 1 + 1 + len; | |
123 | |
124 for (uint32_t i = 0; i < arity; i++) { | |
125 uint32_t offset = 1 + 1 + len + i; | |
126 val = decoder->checked_read_u8(pc, offset, "block type"); | |
127 decode_local_type(val, &type); | |
128 if (type == kAstStmt) { | |
129 decoder->error(pc, pc + offset, "invalid block type"); | |
130 return; | |
131 } | |
132 } | |
133 } | |
134 } | |
135 bool decode_local_type(uint8_t val, LocalType* result) { | |
ahaas
2016/09/16 11:21:31
Could you add a comment which describes the return
titzer
2016/09/16 12:13:21
Done.
| |
136 switch (static_cast<LocalTypeCode>(val)) { | |
137 case kLocalVoid: | |
138 *result = kAstStmt; | |
139 return true; | |
140 case kLocalI32: | |
141 *result = kAstI32; | |
142 return true; | |
143 case kLocalI64: | |
144 *result = kAstI64; | |
145 return true; | |
146 case kLocalF32: | |
147 *result = kAstF32; | |
148 return true; | |
149 case kLocalF64: | |
150 *result = kAstF64; | |
151 return true; | |
152 default: | |
153 *result = kAstStmt; | |
154 return false; | |
155 } | |
156 } | |
157 LocalType read_entry(unsigned index) { | |
158 DCHECK_LT(index, arity); | |
159 LocalType result; | |
160 CHECK(decode_local_type(types[index], &result)); | |
161 return result; | |
162 } | |
163 }; | |
164 | |
92 struct Control; | 165 struct Control; |
93 struct BreakDepthOperand { | 166 struct BreakDepthOperand { |
94 uint32_t arity; | |
95 uint32_t depth; | 167 uint32_t depth; |
96 Control* target; | 168 Control* target; |
97 unsigned length; | 169 unsigned length; |
98 inline BreakDepthOperand(Decoder* decoder, const byte* pc) { | 170 inline BreakDepthOperand(Decoder* decoder, const byte* pc) { |
99 unsigned len1 = 0; | 171 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; | 172 target = nullptr; |
105 } | 173 } |
106 }; | 174 }; |
107 | 175 |
108 struct CallIndirectOperand { | 176 struct CallIndirectOperand { |
109 uint32_t arity; | |
110 uint32_t index; | 177 uint32_t index; |
111 FunctionSig* sig; | 178 FunctionSig* sig; |
112 unsigned length; | 179 unsigned length; |
113 inline CallIndirectOperand(Decoder* decoder, const byte* pc) { | 180 inline CallIndirectOperand(Decoder* decoder, const byte* pc) { |
114 unsigned len1 = 0; | 181 unsigned len1 = 0; |
115 unsigned len2 = 0; | 182 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"); | 183 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "signature index"); |
118 length = len1 + len2; | 184 length = len1 + len2; |
119 sig = nullptr; | 185 sig = nullptr; |
120 } | 186 } |
121 }; | 187 }; |
122 | 188 |
123 struct CallFunctionOperand { | 189 struct CallFunctionOperand { |
124 uint32_t arity; | |
125 uint32_t index; | 190 uint32_t index; |
126 FunctionSig* sig; | 191 FunctionSig* sig; |
127 unsigned length; | 192 unsigned length; |
128 inline CallFunctionOperand(Decoder* decoder, const byte* pc) { | 193 inline CallFunctionOperand(Decoder* decoder, const byte* pc) { |
129 unsigned len1 = 0; | 194 unsigned len1 = 0; |
130 unsigned len2 = 0; | 195 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"); | 196 index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "function index"); |
133 length = len1 + len2; | 197 length = len1 + len2; |
134 sig = nullptr; | 198 sig = nullptr; |
135 } | 199 } |
136 }; | 200 }; |
137 | 201 |
138 struct CallImportOperand { | |
139 uint32_t arity; | |
140 uint32_t index; | |
141 FunctionSig* sig; | |
142 unsigned length; | |
143 inline CallImportOperand(Decoder* decoder, const byte* pc) { | |
144 unsigned len1 = 0; | |
145 unsigned 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; | |
149 sig = nullptr; | |
150 } | |
151 }; | |
152 | |
153 struct BranchTableOperand { | 202 struct BranchTableOperand { |
154 uint32_t arity; | |
155 uint32_t table_count; | 203 uint32_t table_count; |
156 const byte* table; | 204 const byte* table; |
157 unsigned length; | 205 unsigned length; |
158 inline BranchTableOperand(Decoder* decoder, const byte* pc) { | 206 inline BranchTableOperand(Decoder* decoder, const byte* pc) { |
159 unsigned len1 = 0; | 207 unsigned len1 = 0; |
160 unsigned len2 = 0; | 208 table_count = decoder->checked_read_u32v(pc, 1, &len1, "table count"); |
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 || | 209 if (table_count > (UINT_MAX / sizeof(uint32_t)) - 1 || |
165 len1 + len2 > UINT_MAX - (table_count + 1) * sizeof(uint32_t)) { | 210 len1 > UINT_MAX - (table_count + 1) * sizeof(uint32_t)) { |
166 decoder->error(pc, "branch table size overflow"); | 211 decoder->error(pc, "branch table size overflow"); |
167 } | 212 } |
168 length = len1 + len2 + (table_count + 1) * sizeof(uint32_t); | 213 length = len1 + (table_count + 1) * sizeof(uint32_t); |
169 | 214 |
170 uint32_t table_start = 1 + len1 + len2; | 215 uint32_t table_start = 1 + len1; |
171 if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t), | 216 if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t), |
172 "expected <table entries>")) { | 217 "expected <table entries>")) { |
173 table = pc + table_start; | 218 table = pc + table_start; |
174 } else { | 219 } else { |
175 table = nullptr; | 220 table = nullptr; |
176 } | 221 } |
177 } | 222 } |
178 inline uint32_t read_entry(Decoder* decoder, unsigned i) { | 223 inline uint32_t read_entry(Decoder* decoder, unsigned i) { |
179 DCHECK(i <= table_count); | 224 DCHECK(i <= table_count); |
180 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0; | 225 return table ? decoder->read_u32(table + i * sizeof(uint32_t)) : 0; |
(...skipping 15 matching lines...) Expand all Loading... | |
196 "actual alignment is %u", | 241 "actual alignment is %u", |
197 max_alignment, alignment); | 242 max_alignment, alignment); |
198 } | 243 } |
199 unsigned offset_length; | 244 unsigned offset_length; |
200 offset = decoder->checked_read_u32v(pc, 1 + alignment_length, | 245 offset = decoder->checked_read_u32v(pc, 1 + alignment_length, |
201 &offset_length, "offset"); | 246 &offset_length, "offset"); |
202 length = alignment_length + offset_length; | 247 length = alignment_length + offset_length; |
203 } | 248 } |
204 }; | 249 }; |
205 | 250 |
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; | 251 typedef compiler::WasmGraphBuilder TFBuilder; |
216 struct ModuleEnv; // forward declaration of module interface. | 252 struct ModuleEnv; // forward declaration of module interface. |
217 | 253 |
218 // All of the various data structures necessary to decode a function body. | 254 // All of the various data structures necessary to decode a function body. |
219 struct FunctionBody { | 255 struct FunctionBody { |
220 ModuleEnv* module; // module environment | 256 ModuleEnv* module; // module environment |
221 FunctionSig* sig; // function signature | 257 FunctionSig* sig; // function signature |
222 const byte* base; // base of the module bytes, for error reporting | 258 const byte* base; // base of the module bytes, for error reporting |
223 const byte* start; // start of the function body | 259 const byte* start; // start of the function body |
224 const byte* end; // end of the function body | 260 const byte* end; // end of the function body |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 : decls_encoded_size(0), total_local_count(0), local_types(zone) {} | 314 : decls_encoded_size(0), total_local_count(0), local_types(zone) {} |
279 }; | 315 }; |
280 | 316 |
281 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end); | 317 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, const byte* end); |
282 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 318 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
283 const byte* start, const byte* end); | 319 const byte* start, const byte* end); |
284 | 320 |
285 // Computes the length of the opcode at the given address. | 321 // Computes the length of the opcode at the given address. |
286 unsigned OpcodeLength(const byte* pc, const byte* end); | 322 unsigned OpcodeLength(const byte* pc, const byte* end); |
287 | 323 |
288 // Computes the arity (number of sub-nodes) of the opcode at the given address. | |
289 unsigned OpcodeArity(const byte* pc, const byte* end); | |
290 | |
291 // A simple forward iterator for bytecodes. | 324 // A simple forward iterator for bytecodes. |
292 class BytecodeIterator : public Decoder { | 325 class BytecodeIterator : public Decoder { |
293 public: | 326 public: |
294 // If one wants to iterate over the bytecode without looking at {pc_offset()}. | 327 // If one wants to iterate over the bytecode without looking at {pc_offset()}. |
295 class iterator { | 328 class iterator { |
296 public: | 329 public: |
297 inline iterator& operator++() { | 330 inline iterator& operator++() { |
298 DCHECK_LT(ptr_, end_); | 331 DCHECK_LT(ptr_, end_); |
299 ptr_ += OpcodeLength(ptr_, end_); | 332 ptr_ += OpcodeLength(ptr_, end_); |
300 return *this; | 333 return *this; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 } | 372 } |
340 | 373 |
341 bool has_next() { return pc_ < end_; } | 374 bool has_next() { return pc_ < end_; } |
342 }; | 375 }; |
343 | 376 |
344 } // namespace wasm | 377 } // namespace wasm |
345 } // namespace internal | 378 } // namespace internal |
346 } // namespace v8 | 379 } // namespace v8 |
347 | 380 |
348 #endif // V8_WASM_AST_DECODER_H_ | 381 #endif // V8_WASM_AST_DECODER_H_ |
OLD | NEW |