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 #include "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
6 | 6 |
7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 goto done; | 101 goto done; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 // Decode the module sections. | 105 // Decode the module sections. |
106 while (pc_ < limit_) { | 106 while (pc_ < limit_) { |
107 TRACE("DecodeSection\n"); | 107 TRACE("DecodeSection\n"); |
108 pos = pc_; | 108 pos = pc_; |
109 | 109 |
110 // Read the section name. | 110 // Read the section name. |
111 int string_leb_length = 0; | 111 unsigned string_leb_length = 0; |
112 uint32_t string_length = | 112 uint32_t string_length = |
113 consume_u32v(&string_leb_length, "section name length"); | 113 consume_u32v(&string_leb_length, "section name length"); |
114 const byte* section_name_start = pc_; | 114 const byte* section_name_start = pc_; |
115 consume_bytes(string_length); | 115 consume_bytes(string_length); |
116 if (failed()) { | 116 if (failed()) { |
117 TRACE("Section name of length %u couldn't be read\n", string_length); | 117 TRACE("Section name of length %u couldn't be read\n", string_length); |
118 break; | 118 break; |
119 } | 119 } |
120 | 120 |
121 TRACE(" +%d section name : \"%.*s\"\n", | 121 TRACE(" +%d section name : \"%.*s\"\n", |
122 static_cast<int>(section_name_start - start_), | 122 static_cast<int>(section_name_start - start_), |
123 string_length < 20 ? string_length : 20, section_name_start); | 123 string_length < 20 ? string_length : 20, section_name_start); |
124 | 124 |
125 WasmSection::Code section = | 125 WasmSection::Code section = |
126 WasmSection::lookup(section_name_start, string_length); | 126 WasmSection::lookup(section_name_start, string_length); |
127 | 127 |
128 // Read and check the section size. | 128 // Read and check the section size. |
129 int section_leb_length = 0; | 129 unsigned section_leb_length = 0; |
130 uint32_t section_length = | 130 uint32_t section_length = |
131 consume_u32v(§ion_leb_length, "section length"); | 131 consume_u32v(§ion_leb_length, "section length"); |
132 if (!checkAvailable(section_length)) { | 132 if (!checkAvailable(section_length)) { |
133 // The section would extend beyond the end of the module. | 133 // The section would extend beyond the end of the module. |
134 break; | 134 break; |
135 } | 135 } |
136 const byte* section_start = pc_; | 136 const byte* section_start = pc_; |
137 const byte* expected_section_end = pc_ + section_length; | 137 const byte* expected_section_end = pc_ + section_length; |
138 | 138 |
139 current_order = CheckSectionOrder(current_order, section); | 139 current_order = CheckSectionOrder(current_order, section); |
140 | 140 |
141 switch (section) { | 141 switch (section) { |
142 case WasmSection::Code::End: | 142 case WasmSection::Code::End: |
143 // Terminate section decoding. | 143 // Terminate section decoding. |
144 limit_ = pc_; | 144 limit_ = pc_; |
145 break; | 145 break; |
146 case WasmSection::Code::Memory: { | 146 case WasmSection::Code::Memory: { |
147 int length; | 147 unsigned length; |
148 module->min_mem_pages = consume_u32v(&length, "min memory"); | 148 module->min_mem_pages = consume_u32v(&length, "min memory"); |
149 module->max_mem_pages = consume_u32v(&length, "max memory"); | 149 module->max_mem_pages = consume_u32v(&length, "max memory"); |
150 module->mem_export = consume_u8("export memory") != 0; | 150 module->mem_export = consume_u8("export memory") != 0; |
151 break; | 151 break; |
152 } | 152 } |
153 case WasmSection::Code::Signatures: { | 153 case WasmSection::Code::Signatures: { |
154 int length; | 154 unsigned length; |
155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
156 module->signatures.reserve(SafeReserve(signatures_count)); | 156 module->signatures.reserve(SafeReserve(signatures_count)); |
157 // Decode signatures. | 157 // Decode signatures. |
158 for (uint32_t i = 0; i < signatures_count; i++) { | 158 for (uint32_t i = 0; i < signatures_count; i++) { |
159 if (failed()) break; | 159 if (failed()) break; |
160 TRACE("DecodeSignature[%d] module+%d\n", i, | 160 TRACE("DecodeSignature[%d] module+%d\n", i, |
161 static_cast<int>(pc_ - start_)); | 161 static_cast<int>(pc_ - start_)); |
162 FunctionSig* s = consume_sig(); | 162 FunctionSig* s = consume_sig(); |
163 module->signatures.push_back(s); | 163 module->signatures.push_back(s); |
164 } | 164 } |
165 break; | 165 break; |
166 } | 166 } |
167 case WasmSection::Code::FunctionSignatures: { | 167 case WasmSection::Code::FunctionSignatures: { |
168 int length; | 168 unsigned length; |
169 uint32_t functions_count = consume_u32v(&length, "functions count"); | 169 uint32_t functions_count = consume_u32v(&length, "functions count"); |
170 module->functions.reserve(SafeReserve(functions_count)); | 170 module->functions.reserve(SafeReserve(functions_count)); |
171 for (uint32_t i = 0; i < functions_count; i++) { | 171 for (uint32_t i = 0; i < functions_count; i++) { |
172 module->functions.push_back({nullptr, // sig | 172 module->functions.push_back({nullptr, // sig |
173 i, // func_index | 173 i, // func_index |
174 0, // sig_index | 174 0, // sig_index |
175 0, // name_offset | 175 0, // name_offset |
176 0, // name_length | 176 0, // name_length |
177 0, // code_start_offset | 177 0, // code_start_offset |
178 0}); // code_end_offset | 178 0}); // code_end_offset |
179 WasmFunction* function = &module->functions.back(); | 179 WasmFunction* function = &module->functions.back(); |
180 function->sig_index = consume_sig_index(module, &function->sig); | 180 function->sig_index = consume_sig_index(module, &function->sig); |
181 } | 181 } |
182 break; | 182 break; |
183 } | 183 } |
184 case WasmSection::Code::FunctionBodies: { | 184 case WasmSection::Code::FunctionBodies: { |
185 int length; | 185 unsigned length; |
186 const byte* pos = pc_; | 186 const byte* pos = pc_; |
187 uint32_t functions_count = consume_u32v(&length, "functions count"); | 187 uint32_t functions_count = consume_u32v(&length, "functions count"); |
188 if (functions_count != module->functions.size()) { | 188 if (functions_count != module->functions.size()) { |
189 error(pos, pos, "function body count %u mismatch (%u expected)", | 189 error(pos, pos, "function body count %u mismatch (%u expected)", |
190 functions_count, | 190 functions_count, |
191 static_cast<uint32_t>(module->functions.size())); | 191 static_cast<uint32_t>(module->functions.size())); |
192 break; | 192 break; |
193 } | 193 } |
194 for (uint32_t i = 0; i < functions_count; i++) { | 194 for (uint32_t i = 0; i < functions_count; i++) { |
195 WasmFunction* function = &module->functions[i]; | 195 WasmFunction* function = &module->functions[i]; |
196 int length; | 196 unsigned length; |
197 uint32_t size = consume_u32v(&length, "body size"); | 197 uint32_t size = consume_u32v(&length, "body size"); |
198 function->code_start_offset = pc_offset(); | 198 function->code_start_offset = pc_offset(); |
199 function->code_end_offset = pc_offset() + size; | 199 function->code_end_offset = pc_offset() + size; |
200 | 200 |
201 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 201 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
202 size); | 202 size); |
203 pc_ += size; | 203 pc_ += size; |
204 if (pc_ > limit_) { | 204 if (pc_ > limit_) { |
205 error(pc_, "function body extends beyond end of file"); | 205 error(pc_, "function body extends beyond end of file"); |
206 } | 206 } |
207 } | 207 } |
208 break; | 208 break; |
209 } | 209 } |
210 case WasmSection::Code::Names: { | 210 case WasmSection::Code::Names: { |
211 int length; | 211 unsigned length; |
212 const byte* pos = pc_; | 212 const byte* pos = pc_; |
213 uint32_t functions_count = consume_u32v(&length, "functions count"); | 213 uint32_t functions_count = consume_u32v(&length, "functions count"); |
214 if (functions_count != module->functions.size()) { | 214 if (functions_count != module->functions.size()) { |
215 error(pos, pos, "function name count %u mismatch (%u expected)", | 215 error(pos, pos, "function name count %u mismatch (%u expected)", |
216 functions_count, | 216 functions_count, |
217 static_cast<uint32_t>(module->functions.size())); | 217 static_cast<uint32_t>(module->functions.size())); |
218 break; | 218 break; |
219 } | 219 } |
220 | 220 |
221 for (uint32_t i = 0; i < functions_count; i++) { | 221 for (uint32_t i = 0; i < functions_count; i++) { |
222 WasmFunction* function = &module->functions[i]; | 222 WasmFunction* function = &module->functions[i]; |
223 function->name_offset = | 223 function->name_offset = |
224 consume_string(&function->name_length, false); | 224 consume_string(&function->name_length, false); |
225 | 225 |
226 uint32_t local_names_count = | 226 uint32_t local_names_count = |
227 consume_u32v(&length, "local names count"); | 227 consume_u32v(&length, "local names count"); |
228 for (uint32_t j = 0; j < local_names_count; j++) { | 228 for (uint32_t j = 0; j < local_names_count; j++) { |
229 uint32_t unused = 0; | 229 uint32_t unused = 0; |
230 uint32_t offset = consume_string(&unused, false); | 230 uint32_t offset = consume_string(&unused, false); |
231 USE(unused); | 231 USE(unused); |
232 USE(offset); | 232 USE(offset); |
233 } | 233 } |
234 } | 234 } |
235 break; | 235 break; |
236 } | 236 } |
237 case WasmSection::Code::Globals: { | 237 case WasmSection::Code::Globals: { |
238 int length; | 238 unsigned length; |
239 uint32_t globals_count = consume_u32v(&length, "globals count"); | 239 uint32_t globals_count = consume_u32v(&length, "globals count"); |
240 module->globals.reserve(SafeReserve(globals_count)); | 240 module->globals.reserve(SafeReserve(globals_count)); |
241 // Decode globals. | 241 // Decode globals. |
242 for (uint32_t i = 0; i < globals_count; i++) { | 242 for (uint32_t i = 0; i < globals_count; i++) { |
243 if (failed()) break; | 243 if (failed()) break; |
244 TRACE("DecodeGlobal[%d] module+%d\n", i, | 244 TRACE("DecodeGlobal[%d] module+%d\n", i, |
245 static_cast<int>(pc_ - start_)); | 245 static_cast<int>(pc_ - start_)); |
246 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 246 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
247 WasmGlobal* global = &module->globals.back(); | 247 WasmGlobal* global = &module->globals.back(); |
248 DecodeGlobalInModule(global); | 248 DecodeGlobalInModule(global); |
249 } | 249 } |
250 break; | 250 break; |
251 } | 251 } |
252 case WasmSection::Code::DataSegments: { | 252 case WasmSection::Code::DataSegments: { |
253 int length; | 253 unsigned length; |
254 uint32_t data_segments_count = | 254 uint32_t data_segments_count = |
255 consume_u32v(&length, "data segments count"); | 255 consume_u32v(&length, "data segments count"); |
256 module->data_segments.reserve(SafeReserve(data_segments_count)); | 256 module->data_segments.reserve(SafeReserve(data_segments_count)); |
257 // Decode data segments. | 257 // Decode data segments. |
258 for (uint32_t i = 0; i < data_segments_count; i++) { | 258 for (uint32_t i = 0; i < data_segments_count; i++) { |
259 if (failed()) break; | 259 if (failed()) break; |
260 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 260 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
261 static_cast<int>(pc_ - start_)); | 261 static_cast<int>(pc_ - start_)); |
262 module->data_segments.push_back({0, // dest_addr | 262 module->data_segments.push_back({0, // dest_addr |
263 0, // source_offset | 263 0, // source_offset |
264 0, // source_size | 264 0, // source_size |
265 false}); // init | 265 false}); // init |
266 WasmDataSegment* segment = &module->data_segments.back(); | 266 WasmDataSegment* segment = &module->data_segments.back(); |
267 DecodeDataSegmentInModule(module, segment); | 267 DecodeDataSegmentInModule(module, segment); |
268 } | 268 } |
269 break; | 269 break; |
270 } | 270 } |
271 case WasmSection::Code::FunctionTable: { | 271 case WasmSection::Code::FunctionTable: { |
272 // An indirect function table requires functions first. | 272 // An indirect function table requires functions first. |
273 CheckForFunctions(module, section); | 273 CheckForFunctions(module, section); |
274 int length; | 274 unsigned length; |
275 uint32_t function_table_count = | 275 uint32_t function_table_count = |
276 consume_u32v(&length, "function table count"); | 276 consume_u32v(&length, "function table count"); |
277 module->function_table.reserve(SafeReserve(function_table_count)); | 277 module->function_table.reserve(SafeReserve(function_table_count)); |
278 // Decode function table. | 278 // Decode function table. |
279 for (uint32_t i = 0; i < function_table_count; i++) { | 279 for (uint32_t i = 0; i < function_table_count; i++) { |
280 if (failed()) break; | 280 if (failed()) break; |
281 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 281 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
282 static_cast<int>(pc_ - start_)); | 282 static_cast<int>(pc_ - start_)); |
283 uint16_t index = consume_u32v(&length); | 283 uint16_t index = consume_u32v(&length); |
284 if (index >= module->functions.size()) { | 284 if (index >= module->functions.size()) { |
(...skipping 14 matching lines...) Expand all Loading... |
299 WasmFunction* func; | 299 WasmFunction* func; |
300 const byte* pos = pc_; | 300 const byte* pos = pc_; |
301 module->start_function_index = consume_func_index(module, &func); | 301 module->start_function_index = consume_func_index(module, &func); |
302 if (func && func->sig->parameter_count() > 0) { | 302 if (func && func->sig->parameter_count() > 0) { |
303 error(pos, "invalid start function: non-zero parameter count"); | 303 error(pos, "invalid start function: non-zero parameter count"); |
304 break; | 304 break; |
305 } | 305 } |
306 break; | 306 break; |
307 } | 307 } |
308 case WasmSection::Code::ImportTable: { | 308 case WasmSection::Code::ImportTable: { |
309 int length; | 309 unsigned length; |
310 uint32_t import_table_count = | 310 uint32_t import_table_count = |
311 consume_u32v(&length, "import table count"); | 311 consume_u32v(&length, "import table count"); |
312 module->import_table.reserve(SafeReserve(import_table_count)); | 312 module->import_table.reserve(SafeReserve(import_table_count)); |
313 // Decode import table. | 313 // Decode import table. |
314 for (uint32_t i = 0; i < import_table_count; i++) { | 314 for (uint32_t i = 0; i < import_table_count; i++) { |
315 if (failed()) break; | 315 if (failed()) break; |
316 TRACE("DecodeImportTable[%d] module+%d\n", i, | 316 TRACE("DecodeImportTable[%d] module+%d\n", i, |
317 static_cast<int>(pc_ - start_)); | 317 static_cast<int>(pc_ - start_)); |
318 | 318 |
319 module->import_table.push_back({nullptr, // sig | 319 module->import_table.push_back({nullptr, // sig |
(...skipping 12 matching lines...) Expand all Loading... |
332 error(pos, "import module name cannot be NULL"); | 332 error(pos, "import module name cannot be NULL"); |
333 } | 333 } |
334 import->function_name_offset = | 334 import->function_name_offset = |
335 consume_string(&import->function_name_length, true); | 335 consume_string(&import->function_name_length, true); |
336 } | 336 } |
337 break; | 337 break; |
338 } | 338 } |
339 case WasmSection::Code::ExportTable: { | 339 case WasmSection::Code::ExportTable: { |
340 // Declares an export table. | 340 // Declares an export table. |
341 CheckForFunctions(module, section); | 341 CheckForFunctions(module, section); |
342 int length; | 342 unsigned length; |
343 uint32_t export_table_count = | 343 uint32_t export_table_count = |
344 consume_u32v(&length, "export table count"); | 344 consume_u32v(&length, "export table count"); |
345 module->export_table.reserve(SafeReserve(export_table_count)); | 345 module->export_table.reserve(SafeReserve(export_table_count)); |
346 // Decode export table. | 346 // Decode export table. |
347 for (uint32_t i = 0; i < export_table_count; i++) { | 347 for (uint32_t i = 0; i < export_table_count; i++) { |
348 if (failed()) break; | 348 if (failed()) break; |
349 TRACE("DecodeExportTable[%d] module+%d\n", i, | 349 TRACE("DecodeExportTable[%d] module+%d\n", i, |
350 static_cast<int>(pc_ - start_)); | 350 static_cast<int>(pc_ - start_)); |
351 | 351 |
352 module->export_table.push_back({0, // func_index | 352 module->export_table.push_back({0, // func_index |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 | 464 |
465 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { | 465 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
466 if (offset > limit) return false; | 466 if (offset > limit) return false; |
467 if ((offset + size) < offset) return false; // overflow | 467 if ((offset + size) < offset) return false; // overflow |
468 return (offset + size) <= limit; | 468 return (offset + size) <= limit; |
469 } | 469 } |
470 | 470 |
471 // Decodes a single data segment entry inside a module starting at {pc_}. | 471 // Decodes a single data segment entry inside a module starting at {pc_}. |
472 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 472 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
473 const byte* start = pc_; | 473 const byte* start = pc_; |
474 int length; | 474 unsigned length; |
475 segment->dest_addr = consume_u32v(&length, "destination"); | 475 segment->dest_addr = consume_u32v(&length, "destination"); |
476 segment->source_size = consume_u32v(&length, "source size"); | 476 segment->source_size = consume_u32v(&length, "source size"); |
477 segment->source_offset = static_cast<uint32_t>(pc_ - start_); | 477 segment->source_offset = static_cast<uint32_t>(pc_ - start_); |
478 segment->init = true; | 478 segment->init = true; |
479 | 479 |
480 // Validate the data is in the module. | 480 // Validate the data is in the module. |
481 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 481 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
482 if (!IsWithinLimit(module_limit, segment->source_offset, | 482 if (!IsWithinLimit(module_limit, segment->source_offset, |
483 segment->source_size)) { | 483 segment->source_size)) { |
484 error(start, "segment out of bounds of module"); | 484 error(start, "segment out of bounds of module"); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 uint32_t offset = consume_u32(name ? name : "offset"); | 548 uint32_t offset = consume_u32(name ? name : "offset"); |
549 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 549 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
550 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 550 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
551 } | 551 } |
552 return offset; | 552 return offset; |
553 } | 553 } |
554 | 554 |
555 // Reads a length-prefixed string, checking that it is within bounds. Returns | 555 // Reads a length-prefixed string, checking that it is within bounds. Returns |
556 // the offset of the string, and the length as an out parameter. | 556 // the offset of the string, and the length as an out parameter. |
557 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | 557 uint32_t consume_string(uint32_t* length, bool validate_utf8) { |
558 int varint_length; | 558 unsigned varint_length; |
559 *length = consume_u32v(&varint_length, "string length"); | 559 *length = consume_u32v(&varint_length, "string length"); |
560 uint32_t offset = pc_offset(); | 560 uint32_t offset = pc_offset(); |
561 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); | 561 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); |
562 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { | 562 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { |
563 error(pc_, "no valid UTF-8 string"); | 563 error(pc_, "no valid UTF-8 string"); |
564 } | 564 } |
565 consume_bytes(*length); | 565 consume_bytes(*length); |
566 return offset; | 566 return offset; |
567 } | 567 } |
568 | 568 |
569 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { | 569 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { |
570 const byte* pos = pc_; | 570 const byte* pos = pc_; |
571 int length; | 571 unsigned length; |
572 uint32_t sig_index = consume_u32v(&length, "signature index"); | 572 uint32_t sig_index = consume_u32v(&length, "signature index"); |
573 if (sig_index >= module->signatures.size()) { | 573 if (sig_index >= module->signatures.size()) { |
574 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 574 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
575 sig_index, static_cast<int>(module->signatures.size())); | 575 sig_index, static_cast<int>(module->signatures.size())); |
576 *sig = nullptr; | 576 *sig = nullptr; |
577 return 0; | 577 return 0; |
578 } | 578 } |
579 *sig = module->signatures[sig_index]; | 579 *sig = module->signatures[sig_index]; |
580 return sig_index; | 580 return sig_index; |
581 } | 581 } |
582 | 582 |
583 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { | 583 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { |
584 const byte* pos = pc_; | 584 const byte* pos = pc_; |
585 int length; | 585 unsigned length; |
586 uint32_t func_index = consume_u32v(&length, "function index"); | 586 uint32_t func_index = consume_u32v(&length, "function index"); |
587 if (func_index >= module->functions.size()) { | 587 if (func_index >= module->functions.size()) { |
588 error(pos, pos, "function index %u out of bounds (%d functions)", | 588 error(pos, pos, "function index %u out of bounds (%d functions)", |
589 func_index, static_cast<int>(module->functions.size())); | 589 func_index, static_cast<int>(module->functions.size())); |
590 *func = nullptr; | 590 *func = nullptr; |
591 return 0; | 591 return 0; |
592 } | 592 } |
593 *func = &module->functions[func_index]; | 593 *func = &module->functions[func_index]; |
594 return func_index; | 594 return func_index; |
595 } | 595 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 | 650 |
651 // Parses a type entry, which is currently limited to functions only. | 651 // Parses a type entry, which is currently limited to functions only. |
652 FunctionSig* consume_sig() { | 652 FunctionSig* consume_sig() { |
653 const byte* pos = pc_; | 653 const byte* pos = pc_; |
654 byte form = consume_u8("type form"); | 654 byte form = consume_u8("type form"); |
655 if (form != kWasmFunctionTypeForm) { | 655 if (form != kWasmFunctionTypeForm) { |
656 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 656 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
657 kWasmFunctionTypeForm, form); | 657 kWasmFunctionTypeForm, form); |
658 return nullptr; | 658 return nullptr; |
659 } | 659 } |
660 int length; | 660 unsigned length; |
661 // parse parameter types | 661 // parse parameter types |
662 uint32_t param_count = consume_u32v(&length, "param count"); | 662 uint32_t param_count = consume_u32v(&length, "param count"); |
663 std::vector<LocalType> params; | 663 std::vector<LocalType> params; |
664 for (uint32_t i = 0; i < param_count; i++) { | 664 for (uint32_t i = 0; i < param_count; i++) { |
665 LocalType param = consume_local_type(); | 665 LocalType param = consume_local_type(); |
666 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 666 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
667 params.push_back(param); | 667 params.push_back(param); |
668 } | 668 } |
669 | 669 |
670 // parse return types | 670 // parse return types |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 return FunctionError("size > maximum function size"); | 758 return FunctionError("size > maximum function size"); |
759 isolate->counters()->wasm_function_size_bytes()->AddSample( | 759 isolate->counters()->wasm_function_size_bytes()->AddSample( |
760 static_cast<int>(size)); | 760 static_cast<int>(size)); |
761 WasmFunction* function = new WasmFunction(); | 761 WasmFunction* function = new WasmFunction(); |
762 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 762 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
763 return decoder.DecodeSingleFunction(module_env, function); | 763 return decoder.DecodeSingleFunction(module_env, function); |
764 } | 764 } |
765 } // namespace wasm | 765 } // namespace wasm |
766 } // namespace internal | 766 } // namespace internal |
767 } // namespace v8 | 767 } // namespace v8 |
OLD | NEW |