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

Side by Side Diff: src/wasm/module-decoder.cc

Issue 2052623003: [wasm] improve handling of malformed input (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use unsigned, terminate loop analysis on error, add unit test Created 4 years, 6 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 #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
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(&section_leb_length, "section length"); 131 consume_u32v(&section_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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698