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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 goto done; | 103 goto done; |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 // Decode the module sections. | 107 // Decode the module sections. |
108 while (pc_ < limit_) { | 108 while (pc_ < limit_) { |
109 TRACE("DecodeSection\n"); | 109 TRACE("DecodeSection\n"); |
110 pos = pc_; | 110 pos = pc_; |
111 | 111 |
112 // Read the section name. | 112 // Read the section name. |
113 int string_leb_length = 0; | 113 uint32_t string_length = consume_u32v("section name length"); |
114 uint32_t string_length = | |
115 consume_u32v(&string_leb_length, "section name length"); | |
116 const byte* section_name_start = pc_; | 114 const byte* section_name_start = pc_; |
117 consume_bytes(string_length); | 115 consume_bytes(string_length); |
118 if (failed()) { | 116 if (failed()) { |
119 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); |
120 break; | 118 break; |
121 } | 119 } |
122 | 120 |
123 TRACE(" +%d section name : \"%.*s\"\n", | 121 TRACE(" +%d section name : \"%.*s\"\n", |
124 static_cast<int>(section_name_start - start_), | 122 static_cast<int>(section_name_start - start_), |
125 string_length < 20 ? string_length : 20, section_name_start); | 123 string_length < 20 ? string_length : 20, section_name_start); |
126 | 124 |
127 WasmSection::Code section = | 125 WasmSection::Code section = |
128 WasmSection::lookup(section_name_start, string_length); | 126 WasmSection::lookup(section_name_start, string_length); |
129 | 127 |
130 // Read and check the section size. | 128 // Read and check the section size. |
131 int section_leb_length = 0; | 129 uint32_t section_length = consume_u32v("section length"); |
132 uint32_t section_length = | |
133 consume_u32v(§ion_leb_length, "section length"); | |
134 if (!checkAvailable(section_length)) { | 130 if (!checkAvailable(section_length)) { |
135 // The section would extend beyond the end of the module. | 131 // The section would extend beyond the end of the module. |
136 break; | 132 break; |
137 } | 133 } |
138 const byte* section_start = pc_; | 134 const byte* section_start = pc_; |
139 const byte* expected_section_end = pc_ + section_length; | 135 const byte* expected_section_end = pc_ + section_length; |
140 | 136 |
141 current_order = CheckSectionOrder(current_order, section); | 137 current_order = CheckSectionOrder(current_order, section); |
142 | 138 |
143 switch (section) { | 139 switch (section) { |
144 case WasmSection::Code::End: | 140 case WasmSection::Code::End: |
145 // Terminate section decoding. | 141 // Terminate section decoding. |
146 limit_ = pc_; | 142 limit_ = pc_; |
147 break; | 143 break; |
148 case WasmSection::Code::Memory: { | 144 case WasmSection::Code::Memory: { |
149 int length; | 145 module->min_mem_pages = consume_u32v("min memory"); |
150 module->min_mem_pages = consume_u32v(&length, "min memory"); | 146 module->max_mem_pages = consume_u32v("max memory"); |
151 module->max_mem_pages = consume_u32v(&length, "max memory"); | |
152 module->mem_export = consume_u8("export memory") != 0; | 147 module->mem_export = consume_u8("export memory") != 0; |
153 break; | 148 break; |
154 } | 149 } |
155 case WasmSection::Code::Signatures: { | 150 case WasmSection::Code::Signatures: { |
156 int length; | 151 uint32_t signatures_count = consume_u32v("signatures count"); |
157 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | |
158 module->signatures.reserve(SafeReserve(signatures_count)); | 152 module->signatures.reserve(SafeReserve(signatures_count)); |
159 // Decode signatures. | 153 // Decode signatures. |
160 for (uint32_t i = 0; i < signatures_count; ++i) { | 154 for (uint32_t i = 0; i < signatures_count; ++i) { |
161 if (failed()) break; | 155 if (failed()) break; |
162 TRACE("DecodeSignature[%d] module+%d\n", i, | 156 TRACE("DecodeSignature[%d] module+%d\n", i, |
163 static_cast<int>(pc_ - start_)); | 157 static_cast<int>(pc_ - start_)); |
164 FunctionSig* s = consume_sig(); | 158 FunctionSig* s = consume_sig(); |
165 module->signatures.push_back(s); | 159 module->signatures.push_back(s); |
166 } | 160 } |
167 break; | 161 break; |
168 } | 162 } |
169 case WasmSection::Code::FunctionSignatures: { | 163 case WasmSection::Code::FunctionSignatures: { |
170 int length; | 164 uint32_t functions_count = consume_u32v("functions count"); |
171 uint32_t functions_count = consume_u32v(&length, "functions count"); | |
172 module->functions.reserve(SafeReserve(functions_count)); | 165 module->functions.reserve(SafeReserve(functions_count)); |
173 for (uint32_t i = 0; i < functions_count; ++i) { | 166 for (uint32_t i = 0; i < functions_count; ++i) { |
174 module->functions.push_back({nullptr, // sig | 167 module->functions.push_back({nullptr, // sig |
175 i, // func_index | 168 i, // func_index |
176 0, // sig_index | 169 0, // sig_index |
177 0, // name_offset | 170 0, // name_offset |
178 0, // name_length | 171 0, // name_length |
179 0, // code_start_offset | 172 0, // code_start_offset |
180 0}); // code_end_offset | 173 0}); // code_end_offset |
181 WasmFunction* function = &module->functions.back(); | 174 WasmFunction* function = &module->functions.back(); |
182 function->sig_index = consume_sig_index(module, &function->sig); | 175 function->sig_index = consume_sig_index(module, &function->sig); |
183 } | 176 } |
184 break; | 177 break; |
185 } | 178 } |
186 case WasmSection::Code::FunctionBodies: { | 179 case WasmSection::Code::FunctionBodies: { |
187 int length; | |
188 const byte* pos = pc_; | 180 const byte* pos = pc_; |
189 uint32_t functions_count = consume_u32v(&length, "functions count"); | 181 uint32_t functions_count = consume_u32v("functions count"); |
190 if (functions_count != module->functions.size()) { | 182 if (functions_count != module->functions.size()) { |
191 error(pos, pos, "function body count %u mismatch (%u expected)", | 183 error(pos, pos, "function body count %u mismatch (%u expected)", |
192 functions_count, | 184 functions_count, |
193 static_cast<uint32_t>(module->functions.size())); | 185 static_cast<uint32_t>(module->functions.size())); |
194 break; | 186 break; |
195 } | 187 } |
196 for (uint32_t i = 0; i < functions_count; ++i) { | 188 for (uint32_t i = 0; i < functions_count; ++i) { |
197 WasmFunction* function = &module->functions[i]; | 189 WasmFunction* function = &module->functions[i]; |
198 int length; | 190 uint32_t size = consume_u32v("body size"); |
199 uint32_t size = consume_u32v(&length, "body size"); | |
200 function->code_start_offset = pc_offset(); | 191 function->code_start_offset = pc_offset(); |
201 function->code_end_offset = pc_offset() + size; | 192 function->code_end_offset = pc_offset() + size; |
202 | 193 |
203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 194 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
204 size); | 195 size); |
205 pc_ += size; | 196 pc_ += size; |
206 if (pc_ > limit_) { | 197 if (pc_ > limit_) { |
207 error(pc_, "function body extends beyond end of file"); | 198 error(pc_, "function body extends beyond end of file"); |
208 } | 199 } |
209 } | 200 } |
210 break; | 201 break; |
211 } | 202 } |
212 case WasmSection::Code::Names: { | 203 case WasmSection::Code::Names: { |
213 int length; | |
214 const byte* pos = pc_; | 204 const byte* pos = pc_; |
215 uint32_t functions_count = consume_u32v(&length, "functions count"); | 205 uint32_t functions_count = consume_u32v("functions count"); |
216 if (functions_count != module->functions.size()) { | 206 if (functions_count != module->functions.size()) { |
217 error(pos, pos, "function name count %u mismatch (%u expected)", | 207 error(pos, pos, "function name count %u mismatch (%u expected)", |
218 functions_count, | 208 functions_count, |
219 static_cast<uint32_t>(module->functions.size())); | 209 static_cast<uint32_t>(module->functions.size())); |
220 break; | 210 break; |
221 } | 211 } |
222 | 212 |
223 for (uint32_t i = 0; i < functions_count; ++i) { | 213 for (uint32_t i = 0; i < functions_count; ++i) { |
224 WasmFunction* function = &module->functions[i]; | 214 WasmFunction* function = &module->functions[i]; |
225 function->name_offset = | 215 function->name_offset = |
226 consume_string(&function->name_length, false); | 216 consume_string(&function->name_length, false); |
227 | 217 |
228 uint32_t local_names_count = | 218 uint32_t local_names_count = consume_u32v("local names count"); |
229 consume_u32v(&length, "local names count"); | |
230 for (uint32_t j = 0; j < local_names_count; j++) { | 219 for (uint32_t j = 0; j < local_names_count; j++) { |
231 uint32_t unused = 0; | 220 uint32_t unused = 0; |
232 uint32_t offset = consume_string(&unused, false); | 221 uint32_t offset = consume_string(&unused, false); |
233 USE(unused); | 222 USE(unused); |
234 USE(offset); | 223 USE(offset); |
235 } | 224 } |
236 } | 225 } |
237 break; | 226 break; |
238 } | 227 } |
239 case WasmSection::Code::Globals: { | 228 case WasmSection::Code::Globals: { |
240 int length; | 229 uint32_t globals_count = consume_u32v("globals count"); |
241 uint32_t globals_count = consume_u32v(&length, "globals count"); | |
242 module->globals.reserve(SafeReserve(globals_count)); | 230 module->globals.reserve(SafeReserve(globals_count)); |
243 // Decode globals. | 231 // Decode globals. |
244 for (uint32_t i = 0; i < globals_count; ++i) { | 232 for (uint32_t i = 0; i < globals_count; ++i) { |
245 if (failed()) break; | 233 if (failed()) break; |
246 TRACE("DecodeGlobal[%d] module+%d\n", i, | 234 TRACE("DecodeGlobal[%d] module+%d\n", i, |
247 static_cast<int>(pc_ - start_)); | 235 static_cast<int>(pc_ - start_)); |
248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 236 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
249 WasmGlobal* global = &module->globals.back(); | 237 WasmGlobal* global = &module->globals.back(); |
250 DecodeGlobalInModule(global); | 238 DecodeGlobalInModule(global); |
251 } | 239 } |
252 break; | 240 break; |
253 } | 241 } |
254 case WasmSection::Code::DataSegments: { | 242 case WasmSection::Code::DataSegments: { |
255 int length; | 243 uint32_t data_segments_count = consume_u32v("data segments count"); |
256 uint32_t data_segments_count = | |
257 consume_u32v(&length, "data segments count"); | |
258 module->data_segments.reserve(SafeReserve(data_segments_count)); | 244 module->data_segments.reserve(SafeReserve(data_segments_count)); |
259 // Decode data segments. | 245 // Decode data segments. |
260 for (uint32_t i = 0; i < data_segments_count; ++i) { | 246 for (uint32_t i = 0; i < data_segments_count; ++i) { |
261 if (failed()) break; | 247 if (failed()) break; |
262 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 248 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
263 static_cast<int>(pc_ - start_)); | 249 static_cast<int>(pc_ - start_)); |
264 module->data_segments.push_back({0, // dest_addr | 250 module->data_segments.push_back({0, // dest_addr |
265 0, // source_offset | 251 0, // source_offset |
266 0, // source_size | 252 0, // source_size |
267 false}); // init | 253 false}); // init |
268 WasmDataSegment* segment = &module->data_segments.back(); | 254 WasmDataSegment* segment = &module->data_segments.back(); |
269 DecodeDataSegmentInModule(module, segment); | 255 DecodeDataSegmentInModule(module, segment); |
270 } | 256 } |
271 break; | 257 break; |
272 } | 258 } |
273 case WasmSection::Code::FunctionTablePad: { | 259 case WasmSection::Code::FunctionTablePad: { |
274 if (!FLAG_wasm_jit_prototype) { | 260 if (!FLAG_wasm_jit_prototype) { |
275 error("FunctionTablePad section without jiting enabled"); | 261 error("FunctionTablePad section without jiting enabled"); |
276 } | 262 } |
277 // An indirect function table requires functions first. | 263 // An indirect function table requires functions first. |
278 int length; | 264 module->indirect_table_size = consume_u32v("indirect entry count"); |
279 module->indirect_table_size = | |
280 consume_u32v(&length, "indirect entry count"); | |
281 if (module->indirect_table_size > 0 && | 265 if (module->indirect_table_size > 0 && |
282 module->indirect_table_size < module->function_table.size()) { | 266 module->indirect_table_size < module->function_table.size()) { |
283 error("more predefined indirect entries than table can hold"); | 267 error("more predefined indirect entries than table can hold"); |
284 } | 268 } |
285 break; | 269 break; |
286 } | 270 } |
287 case WasmSection::Code::FunctionTable: { | 271 case WasmSection::Code::FunctionTable: { |
288 // An indirect function table requires functions first. | 272 // An indirect function table requires functions first. |
289 CheckForFunctions(module, section); | 273 CheckForFunctions(module, section); |
290 int length; | 274 uint32_t function_table_count = consume_u32v("function table count"); |
291 uint32_t function_table_count = | |
292 consume_u32v(&length, "function table count"); | |
293 module->function_table.reserve(SafeReserve(function_table_count)); | 275 module->function_table.reserve(SafeReserve(function_table_count)); |
294 // Decode function table. | 276 // Decode function table. |
295 for (uint32_t i = 0; i < function_table_count; ++i) { | 277 for (uint32_t i = 0; i < function_table_count; ++i) { |
296 if (failed()) break; | 278 if (failed()) break; |
297 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 279 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
298 static_cast<int>(pc_ - start_)); | 280 static_cast<int>(pc_ - start_)); |
299 uint16_t index = consume_u32v(&length); | 281 uint16_t index = consume_u32v(); |
300 if (index >= module->functions.size()) { | 282 if (index >= module->functions.size()) { |
301 error(pc_ - 2, "invalid function index"); | 283 error(pc_ - 2, "invalid function index"); |
302 break; | 284 break; |
303 } | 285 } |
304 module->function_table.push_back(index); | 286 module->function_table.push_back(index); |
305 } | 287 } |
306 if (module->indirect_table_size > 0 && | 288 if (module->indirect_table_size > 0 && |
307 module->indirect_table_size < module->function_table.size()) { | 289 module->indirect_table_size < module->function_table.size()) { |
308 error("more predefined indirect entries than table can hold"); | 290 error("more predefined indirect entries than table can hold"); |
309 } | 291 } |
310 break; | 292 break; |
311 } | 293 } |
312 case WasmSection::Code::StartFunction: { | 294 case WasmSection::Code::StartFunction: { |
313 // Declares a start function for a module. | 295 // Declares a start function for a module. |
314 CheckForFunctions(module, section); | 296 CheckForFunctions(module, section); |
315 if (module->start_function_index >= 0) { | 297 if (module->start_function_index >= 0) { |
316 error("start function already declared"); | 298 error("start function already declared"); |
317 break; | 299 break; |
318 } | 300 } |
319 WasmFunction* func; | 301 WasmFunction* func; |
320 const byte* pos = pc_; | 302 const byte* pos = pc_; |
321 module->start_function_index = consume_func_index(module, &func); | 303 module->start_function_index = consume_func_index(module, &func); |
322 if (func && func->sig->parameter_count() > 0) { | 304 if (func && func->sig->parameter_count() > 0) { |
323 error(pos, "invalid start function: non-zero parameter count"); | 305 error(pos, "invalid start function: non-zero parameter count"); |
324 break; | 306 break; |
325 } | 307 } |
326 break; | 308 break; |
327 } | 309 } |
328 case WasmSection::Code::ImportTable: { | 310 case WasmSection::Code::ImportTable: { |
329 int length; | 311 uint32_t import_table_count = consume_u32v("import table count"); |
330 uint32_t import_table_count = | |
331 consume_u32v(&length, "import table count"); | |
332 module->import_table.reserve(SafeReserve(import_table_count)); | 312 module->import_table.reserve(SafeReserve(import_table_count)); |
333 // Decode import table. | 313 // Decode import table. |
334 for (uint32_t i = 0; i < import_table_count; ++i) { | 314 for (uint32_t i = 0; i < import_table_count; ++i) { |
335 if (failed()) break; | 315 if (failed()) break; |
336 TRACE("DecodeImportTable[%d] module+%d\n", i, | 316 TRACE("DecodeImportTable[%d] module+%d\n", i, |
337 static_cast<int>(pc_ - start_)); | 317 static_cast<int>(pc_ - start_)); |
338 | 318 |
339 module->import_table.push_back({nullptr, // sig | 319 module->import_table.push_back({nullptr, // sig |
340 0, // sig_index | 320 0, // sig_index |
341 0, // module_name_offset | 321 0, // module_name_offset |
(...skipping 10 matching lines...) Expand all Loading... |
352 error(pos, "import module name cannot be NULL"); | 332 error(pos, "import module name cannot be NULL"); |
353 } | 333 } |
354 import->function_name_offset = | 334 import->function_name_offset = |
355 consume_string(&import->function_name_length, true); | 335 consume_string(&import->function_name_length, true); |
356 } | 336 } |
357 break; | 337 break; |
358 } | 338 } |
359 case WasmSection::Code::ExportTable: { | 339 case WasmSection::Code::ExportTable: { |
360 // Declares an export table. | 340 // Declares an export table. |
361 CheckForFunctions(module, section); | 341 CheckForFunctions(module, section); |
362 int length; | 342 uint32_t export_table_count = consume_u32v("export table count"); |
363 uint32_t export_table_count = | |
364 consume_u32v(&length, "export table count"); | |
365 module->export_table.reserve(SafeReserve(export_table_count)); | 343 module->export_table.reserve(SafeReserve(export_table_count)); |
366 // Decode export table. | 344 // Decode export table. |
367 for (uint32_t i = 0; i < export_table_count; ++i) { | 345 for (uint32_t i = 0; i < export_table_count; ++i) { |
368 if (failed()) break; | 346 if (failed()) break; |
369 TRACE("DecodeExportTable[%d] module+%d\n", i, | 347 TRACE("DecodeExportTable[%d] module+%d\n", i, |
370 static_cast<int>(pc_ - start_)); | 348 static_cast<int>(pc_ - start_)); |
371 | 349 |
372 module->export_table.push_back({0, // func_index | 350 module->export_table.push_back({0, // func_index |
373 0, // name_offset | 351 0, // name_offset |
374 0}); // name_length | 352 0}); // name_length |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 | 488 |
511 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { | 489 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
512 if (offset > limit) return false; | 490 if (offset > limit) return false; |
513 if ((offset + size) < offset) return false; // overflow | 491 if ((offset + size) < offset) return false; // overflow |
514 return (offset + size) <= limit; | 492 return (offset + size) <= limit; |
515 } | 493 } |
516 | 494 |
517 // Decodes a single data segment entry inside a module starting at {pc_}. | 495 // Decodes a single data segment entry inside a module starting at {pc_}. |
518 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 496 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
519 const byte* start = pc_; | 497 const byte* start = pc_; |
520 int length; | 498 segment->dest_addr = consume_u32v("destination"); |
521 segment->dest_addr = consume_u32v(&length, "destination"); | 499 segment->source_size = consume_u32v("source size"); |
522 segment->source_size = consume_u32v(&length, "source size"); | |
523 segment->source_offset = static_cast<uint32_t>(pc_ - start_); | 500 segment->source_offset = static_cast<uint32_t>(pc_ - start_); |
524 segment->init = true; | 501 segment->init = true; |
525 | 502 |
526 // Validate the data is in the module. | 503 // Validate the data is in the module. |
527 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 504 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
528 if (!IsWithinLimit(module_limit, segment->source_offset, | 505 if (!IsWithinLimit(module_limit, segment->source_offset, |
529 segment->source_size)) { | 506 segment->source_size)) { |
530 error(start, "segment out of bounds of module"); | 507 error(start, "segment out of bounds of module"); |
531 } | 508 } |
532 | 509 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 uint32_t offset = consume_u32(name ? name : "offset"); | 571 uint32_t offset = consume_u32(name ? name : "offset"); |
595 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 572 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
596 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 573 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
597 } | 574 } |
598 return offset; | 575 return offset; |
599 } | 576 } |
600 | 577 |
601 // Reads a length-prefixed string, checking that it is within bounds. Returns | 578 // Reads a length-prefixed string, checking that it is within bounds. Returns |
602 // the offset of the string, and the length as an out parameter. | 579 // the offset of the string, and the length as an out parameter. |
603 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | 580 uint32_t consume_string(uint32_t* length, bool validate_utf8) { |
604 int varint_length; | 581 *length = consume_u32v("string length"); |
605 *length = consume_u32v(&varint_length, "string length"); | |
606 uint32_t offset = pc_offset(); | 582 uint32_t offset = pc_offset(); |
607 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); | 583 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); |
608 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { | 584 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { |
609 error(pc_, "no valid UTF-8 string"); | 585 error(pc_, "no valid UTF-8 string"); |
610 } | 586 } |
611 consume_bytes(*length); | 587 consume_bytes(*length); |
612 return offset; | 588 return offset; |
613 } | 589 } |
614 | 590 |
615 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { | 591 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { |
616 const byte* pos = pc_; | 592 const byte* pos = pc_; |
617 int length; | 593 uint32_t sig_index = consume_u32v("signature index"); |
618 uint32_t sig_index = consume_u32v(&length, "signature index"); | |
619 if (sig_index >= module->signatures.size()) { | 594 if (sig_index >= module->signatures.size()) { |
620 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 595 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
621 sig_index, static_cast<int>(module->signatures.size())); | 596 sig_index, static_cast<int>(module->signatures.size())); |
622 *sig = nullptr; | 597 *sig = nullptr; |
623 return 0; | 598 return 0; |
624 } | 599 } |
625 *sig = module->signatures[sig_index]; | 600 *sig = module->signatures[sig_index]; |
626 return sig_index; | 601 return sig_index; |
627 } | 602 } |
628 | 603 |
629 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { | 604 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { |
630 const byte* pos = pc_; | 605 const byte* pos = pc_; |
631 int length; | 606 uint32_t func_index = consume_u32v("function index"); |
632 uint32_t func_index = consume_u32v(&length, "function index"); | |
633 if (func_index >= module->functions.size()) { | 607 if (func_index >= module->functions.size()) { |
634 error(pos, pos, "function index %u out of bounds (%d functions)", | 608 error(pos, pos, "function index %u out of bounds (%d functions)", |
635 func_index, static_cast<int>(module->functions.size())); | 609 func_index, static_cast<int>(module->functions.size())); |
636 *func = nullptr; | 610 *func = nullptr; |
637 return 0; | 611 return 0; |
638 } | 612 } |
639 *func = &module->functions[func_index]; | 613 *func = &module->functions[func_index]; |
640 return func_index; | 614 return func_index; |
641 } | 615 } |
642 | 616 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 | 670 |
697 // Parses a type entry, which is currently limited to functions only. | 671 // Parses a type entry, which is currently limited to functions only. |
698 FunctionSig* consume_sig() { | 672 FunctionSig* consume_sig() { |
699 const byte* pos = pc_; | 673 const byte* pos = pc_; |
700 byte form = consume_u8("type form"); | 674 byte form = consume_u8("type form"); |
701 if (form != kWasmFunctionTypeForm) { | 675 if (form != kWasmFunctionTypeForm) { |
702 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 676 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
703 kWasmFunctionTypeForm, form); | 677 kWasmFunctionTypeForm, form); |
704 return nullptr; | 678 return nullptr; |
705 } | 679 } |
706 int length; | |
707 // parse parameter types | 680 // parse parameter types |
708 uint32_t param_count = consume_u32v(&length, "param count"); | 681 uint32_t param_count = consume_u32v("param count"); |
709 std::vector<LocalType> params; | 682 std::vector<LocalType> params; |
710 for (uint32_t i = 0; i < param_count; ++i) { | 683 for (uint32_t i = 0; i < param_count; ++i) { |
711 LocalType param = consume_local_type(); | 684 LocalType param = consume_local_type(); |
712 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 685 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
713 params.push_back(param); | 686 params.push_back(param); |
714 } | 687 } |
715 | 688 |
716 // parse return types | 689 // parse return types |
717 const byte* pt = pc_; | 690 const byte* pt = pc_; |
718 uint32_t return_count = consume_u32v(&length, "return count"); | 691 uint32_t return_count = consume_u32v("return count"); |
719 if (return_count > kMaxReturnCount) { | 692 if (return_count > kMaxReturnCount) { |
720 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, | 693 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, |
721 kMaxReturnCount); | 694 kMaxReturnCount); |
722 return nullptr; | 695 return nullptr; |
723 } | 696 } |
724 std::vector<LocalType> returns; | 697 std::vector<LocalType> returns; |
725 for (uint32_t i = 0; i < return_count; ++i) { | 698 for (uint32_t i = 0; i < return_count; ++i) { |
726 LocalType ret = consume_local_type(); | 699 LocalType ret = consume_local_type(); |
727 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); | 700 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); |
728 returns.push_back(ret); | 701 returns.push_back(ret); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 Decoder decoder(module_start, module_end); | 743 Decoder decoder(module_start, module_end); |
771 | 744 |
772 uint32_t magic_word = decoder.consume_u32("wasm magic"); | 745 uint32_t magic_word = decoder.consume_u32("wasm magic"); |
773 if (magic_word != kWasmMagic) decoder.error("wrong magic word"); | 746 if (magic_word != kWasmMagic) decoder.error("wrong magic word"); |
774 | 747 |
775 uint32_t magic_version = decoder.consume_u32("wasm version"); | 748 uint32_t magic_version = decoder.consume_u32("wasm version"); |
776 if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); | 749 if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); |
777 | 750 |
778 while (decoder.more() && decoder.ok()) { | 751 while (decoder.more() && decoder.ok()) { |
779 // Read the section name. | 752 // Read the section name. |
780 int string_leb_length = 0; | 753 uint32_t string_length = decoder.consume_u32v("section name length"); |
781 uint32_t string_length = | |
782 decoder.consume_u32v(&string_leb_length, "section name length"); | |
783 const byte* section_name_start = decoder.pc(); | 754 const byte* section_name_start = decoder.pc(); |
784 decoder.consume_bytes(string_length); | 755 decoder.consume_bytes(string_length); |
785 if (decoder.failed()) break; | 756 if (decoder.failed()) break; |
786 | 757 |
787 WasmSection::Code section = | 758 WasmSection::Code section = |
788 WasmSection::lookup(section_name_start, string_length); | 759 WasmSection::lookup(section_name_start, string_length); |
789 | 760 |
790 // Read and check the section size. | 761 // Read and check the section size. |
791 int section_leb_length = 0; | 762 uint32_t section_length = decoder.consume_u32v("section length"); |
792 uint32_t section_length = | |
793 decoder.consume_u32v(§ion_leb_length, "section length"); | |
794 | 763 |
795 const byte* section_start = decoder.pc(); | 764 const byte* section_start = decoder.pc(); |
796 decoder.consume_bytes(section_length); | 765 decoder.consume_bytes(section_length); |
797 if (section == code && decoder.ok()) { | 766 if (section == code && decoder.ok()) { |
798 return Vector<const uint8_t>(section_start, section_length); | 767 return Vector<const uint8_t>(section_start, section_length); |
799 } | 768 } |
800 } | 769 } |
801 | 770 |
802 return Vector<const uint8_t>(); | 771 return Vector<const uint8_t>(); |
803 } | 772 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 return decoder.DecodeSingleFunction(module_env, function); | 817 return decoder.DecodeSingleFunction(module_env, function); |
849 } | 818 } |
850 | 819 |
851 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, | 820 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, |
852 const byte* module_end) { | 821 const byte* module_end) { |
853 Vector<const byte> code_section = | 822 Vector<const byte> code_section = |
854 FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); | 823 FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); |
855 Decoder decoder(code_section.start(), code_section.end()); | 824 Decoder decoder(code_section.start(), code_section.end()); |
856 if (!code_section.start()) decoder.error("no code section"); | 825 if (!code_section.start()) decoder.error("no code section"); |
857 | 826 |
858 int length; | 827 uint32_t functions_count = decoder.consume_u32v("functions count"); |
859 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); | |
860 FunctionOffsets table; | 828 FunctionOffsets table; |
861 // Take care of invalid input here. | 829 // Take care of invalid input here. |
862 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) | 830 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) |
863 table.reserve(functions_count); | 831 table.reserve(functions_count); |
864 int section_offset = static_cast<int>(code_section.start() - module_start); | 832 int section_offset = static_cast<int>(code_section.start() - module_start); |
865 DCHECK_LE(0, section_offset); | 833 DCHECK_LE(0, section_offset); |
866 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { | 834 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { |
867 uint32_t size = decoder.consume_u32v(&length, "body size"); | 835 uint32_t size = decoder.consume_u32v("body size"); |
868 int offset = static_cast<int>(section_offset + decoder.pc_offset()); | 836 int offset = static_cast<int>(section_offset + decoder.pc_offset()); |
869 table.push_back(std::make_pair(offset, static_cast<int>(size))); | 837 table.push_back(std::make_pair(offset, static_cast<int>(size))); |
870 DCHECK(table.back().first >= 0 && table.back().second >= 0); | 838 DCHECK(table.back().first >= 0 && table.back().second >= 0); |
871 decoder.consume_bytes(size); | 839 decoder.consume_bytes(size); |
872 } | 840 } |
873 if (decoder.more()) decoder.error("unexpected additional bytes"); | 841 if (decoder.more()) decoder.error("unexpected additional bytes"); |
874 | 842 |
875 return decoder.toResult(std::move(table)); | 843 return decoder.toResult(std::move(table)); |
876 } | 844 } |
877 | 845 |
878 } // namespace wasm | 846 } // namespace wasm |
879 } // namespace internal | 847 } // namespace internal |
880 } // namespace v8 | 848 } // namespace v8 |
OLD | NEW |