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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 module->min_mem_pages = consume_u32v(&length, "min memory"); | 150 module->min_mem_pages = consume_u32v(&length, "min memory"); |
151 module->max_mem_pages = consume_u32v(&length, "max memory"); | 151 module->max_mem_pages = consume_u32v(&length, "max memory"); |
152 module->mem_export = consume_u8("export memory") != 0; | 152 module->mem_export = consume_u8("export memory") != 0; |
153 break; | 153 break; |
154 } | 154 } |
155 case WasmSection::Code::Signatures: { | 155 case WasmSection::Code::Signatures: { |
156 int length; | 156 int length; |
157 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 157 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
158 module->signatures.reserve(SafeReserve(signatures_count)); | 158 module->signatures.reserve(SafeReserve(signatures_count)); |
159 // Decode signatures. | 159 // Decode signatures. |
160 for (uint32_t i = 0; i < signatures_count; i++) { | 160 for (uint32_t i = 0; i < signatures_count; ++i) { |
161 if (failed()) break; | 161 if (failed()) break; |
162 TRACE("DecodeSignature[%d] module+%d\n", i, | 162 TRACE("DecodeSignature[%d] module+%d\n", i, |
163 static_cast<int>(pc_ - start_)); | 163 static_cast<int>(pc_ - start_)); |
164 FunctionSig* s = consume_sig(); | 164 FunctionSig* s = consume_sig(); |
165 module->signatures.push_back(s); | 165 module->signatures.push_back(s); |
166 } | 166 } |
167 break; | 167 break; |
168 } | 168 } |
169 case WasmSection::Code::FunctionSignatures: { | 169 case WasmSection::Code::FunctionSignatures: { |
170 int length; | 170 int length; |
171 uint32_t functions_count = consume_u32v(&length, "functions count"); | 171 uint32_t functions_count = consume_u32v(&length, "functions count"); |
172 module->functions.reserve(SafeReserve(functions_count)); | 172 module->functions.reserve(SafeReserve(functions_count)); |
173 for (uint32_t i = 0; i < functions_count; i++) { | 173 for (uint32_t i = 0; i < functions_count; ++i) { |
174 module->functions.push_back({nullptr, // sig | 174 module->functions.push_back({nullptr, // sig |
175 i, // func_index | 175 i, // func_index |
176 0, // sig_index | 176 0, // sig_index |
177 0, // name_offset | 177 0, // name_offset |
178 0, // name_length | 178 0, // name_length |
179 0, // code_start_offset | 179 0, // code_start_offset |
180 0}); // code_end_offset | 180 0}); // code_end_offset |
181 WasmFunction* function = &module->functions.back(); | 181 WasmFunction* function = &module->functions.back(); |
182 function->sig_index = consume_sig_index(module, &function->sig); | 182 function->sig_index = consume_sig_index(module, &function->sig); |
183 } | 183 } |
184 break; | 184 break; |
185 } | 185 } |
186 case WasmSection::Code::FunctionBodies: { | 186 case WasmSection::Code::FunctionBodies: { |
187 int length; | 187 int length; |
188 const byte* pos = pc_; | 188 const byte* pos = pc_; |
189 uint32_t functions_count = consume_u32v(&length, "functions count"); | 189 uint32_t functions_count = consume_u32v(&length, "functions count"); |
190 if (functions_count != module->functions.size()) { | 190 if (functions_count != module->functions.size()) { |
191 error(pos, pos, "function body count %u mismatch (%u expected)", | 191 error(pos, pos, "function body count %u mismatch (%u expected)", |
192 functions_count, | 192 functions_count, |
193 static_cast<uint32_t>(module->functions.size())); | 193 static_cast<uint32_t>(module->functions.size())); |
194 break; | 194 break; |
195 } | 195 } |
196 for (uint32_t i = 0; i < functions_count; i++) { | 196 for (uint32_t i = 0; i < functions_count; ++i) { |
197 WasmFunction* function = &module->functions[i]; | 197 WasmFunction* function = &module->functions[i]; |
198 int length; | 198 int length; |
199 uint32_t size = consume_u32v(&length, "body size"); | 199 uint32_t size = consume_u32v(&length, "body size"); |
200 function->code_start_offset = pc_offset(); | 200 function->code_start_offset = pc_offset(); |
201 function->code_end_offset = pc_offset() + size; | 201 function->code_end_offset = pc_offset() + size; |
202 | 202 |
203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
204 size); | 204 size); |
205 pc_ += size; | 205 pc_ += size; |
206 if (pc_ > limit_) { | 206 if (pc_ > limit_) { |
207 error(pc_, "function body extends beyond end of file"); | 207 error(pc_, "function body extends beyond end of file"); |
208 } | 208 } |
209 } | 209 } |
210 break; | 210 break; |
211 } | 211 } |
212 case WasmSection::Code::Names: { | 212 case WasmSection::Code::Names: { |
213 int length; | 213 int length; |
214 const byte* pos = pc_; | 214 const byte* pos = pc_; |
215 uint32_t functions_count = consume_u32v(&length, "functions count"); | 215 uint32_t functions_count = consume_u32v(&length, "functions count"); |
216 if (functions_count != module->functions.size()) { | 216 if (functions_count != module->functions.size()) { |
217 error(pos, pos, "function name count %u mismatch (%u expected)", | 217 error(pos, pos, "function name count %u mismatch (%u expected)", |
218 functions_count, | 218 functions_count, |
219 static_cast<uint32_t>(module->functions.size())); | 219 static_cast<uint32_t>(module->functions.size())); |
220 break; | 220 break; |
221 } | 221 } |
222 | 222 |
223 for (uint32_t i = 0; i < functions_count; i++) { | 223 for (uint32_t i = 0; i < functions_count; ++i) { |
224 WasmFunction* function = &module->functions[i]; | 224 WasmFunction* function = &module->functions[i]; |
225 function->name_offset = | 225 function->name_offset = |
226 consume_string(&function->name_length, false); | 226 consume_string(&function->name_length, false); |
227 | 227 |
228 uint32_t local_names_count = | 228 uint32_t local_names_count = |
229 consume_u32v(&length, "local names count"); | 229 consume_u32v(&length, "local names count"); |
230 for (uint32_t j = 0; j < local_names_count; j++) { | 230 for (uint32_t j = 0; j < local_names_count; j++) { |
231 uint32_t unused = 0; | 231 uint32_t unused = 0; |
232 uint32_t offset = consume_string(&unused, false); | 232 uint32_t offset = consume_string(&unused, false); |
233 USE(unused); | 233 USE(unused); |
234 USE(offset); | 234 USE(offset); |
235 } | 235 } |
236 } | 236 } |
237 break; | 237 break; |
238 } | 238 } |
239 case WasmSection::Code::Globals: { | 239 case WasmSection::Code::Globals: { |
240 int length; | 240 int length; |
241 uint32_t globals_count = consume_u32v(&length, "globals count"); | 241 uint32_t globals_count = consume_u32v(&length, "globals count"); |
242 module->globals.reserve(SafeReserve(globals_count)); | 242 module->globals.reserve(SafeReserve(globals_count)); |
243 // Decode globals. | 243 // Decode globals. |
244 for (uint32_t i = 0; i < globals_count; i++) { | 244 for (uint32_t i = 0; i < globals_count; ++i) { |
245 if (failed()) break; | 245 if (failed()) break; |
246 TRACE("DecodeGlobal[%d] module+%d\n", i, | 246 TRACE("DecodeGlobal[%d] module+%d\n", i, |
247 static_cast<int>(pc_ - start_)); | 247 static_cast<int>(pc_ - start_)); |
248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
249 WasmGlobal* global = &module->globals.back(); | 249 WasmGlobal* global = &module->globals.back(); |
250 DecodeGlobalInModule(global); | 250 DecodeGlobalInModule(global); |
251 } | 251 } |
252 break; | 252 break; |
253 } | 253 } |
254 case WasmSection::Code::DataSegments: { | 254 case WasmSection::Code::DataSegments: { |
255 int length; | 255 int length; |
256 uint32_t data_segments_count = | 256 uint32_t data_segments_count = |
257 consume_u32v(&length, "data segments count"); | 257 consume_u32v(&length, "data segments count"); |
258 module->data_segments.reserve(SafeReserve(data_segments_count)); | 258 module->data_segments.reserve(SafeReserve(data_segments_count)); |
259 // Decode data segments. | 259 // Decode data segments. |
260 for (uint32_t i = 0; i < data_segments_count; i++) { | 260 for (uint32_t i = 0; i < data_segments_count; ++i) { |
261 if (failed()) break; | 261 if (failed()) break; |
262 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 262 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
263 static_cast<int>(pc_ - start_)); | 263 static_cast<int>(pc_ - start_)); |
264 module->data_segments.push_back({0, // dest_addr | 264 module->data_segments.push_back({0, // dest_addr |
265 0, // source_offset | 265 0, // source_offset |
266 0, // source_size | 266 0, // source_size |
267 false}); // init | 267 false}); // init |
268 WasmDataSegment* segment = &module->data_segments.back(); | 268 WasmDataSegment* segment = &module->data_segments.back(); |
269 DecodeDataSegmentInModule(module, segment); | 269 DecodeDataSegmentInModule(module, segment); |
270 } | 270 } |
(...skipping 14 matching lines...) Expand all Loading... |
285 break; | 285 break; |
286 } | 286 } |
287 case WasmSection::Code::FunctionTable: { | 287 case WasmSection::Code::FunctionTable: { |
288 // An indirect function table requires functions first. | 288 // An indirect function table requires functions first. |
289 CheckForFunctions(module, section); | 289 CheckForFunctions(module, section); |
290 int length; | 290 int length; |
291 uint32_t function_table_count = | 291 uint32_t function_table_count = |
292 consume_u32v(&length, "function table count"); | 292 consume_u32v(&length, "function table count"); |
293 module->function_table.reserve(SafeReserve(function_table_count)); | 293 module->function_table.reserve(SafeReserve(function_table_count)); |
294 // Decode function table. | 294 // Decode function table. |
295 for (uint32_t i = 0; i < function_table_count; i++) { | 295 for (uint32_t i = 0; i < function_table_count; ++i) { |
296 if (failed()) break; | 296 if (failed()) break; |
297 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 297 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
298 static_cast<int>(pc_ - start_)); | 298 static_cast<int>(pc_ - start_)); |
299 uint16_t index = consume_u32v(&length); | 299 uint16_t index = consume_u32v(&length); |
300 if (index >= module->functions.size()) { | 300 if (index >= module->functions.size()) { |
301 error(pc_ - 2, "invalid function index"); | 301 error(pc_ - 2, "invalid function index"); |
302 break; | 302 break; |
303 } | 303 } |
304 module->function_table.push_back(index); | 304 module->function_table.push_back(index); |
305 } | 305 } |
(...skipping 18 matching lines...) Expand all Loading... |
324 break; | 324 break; |
325 } | 325 } |
326 break; | 326 break; |
327 } | 327 } |
328 case WasmSection::Code::ImportTable: { | 328 case WasmSection::Code::ImportTable: { |
329 int length; | 329 int length; |
330 uint32_t import_table_count = | 330 uint32_t import_table_count = |
331 consume_u32v(&length, "import table count"); | 331 consume_u32v(&length, "import table count"); |
332 module->import_table.reserve(SafeReserve(import_table_count)); | 332 module->import_table.reserve(SafeReserve(import_table_count)); |
333 // Decode import table. | 333 // Decode import table. |
334 for (uint32_t i = 0; i < import_table_count; i++) { | 334 for (uint32_t i = 0; i < import_table_count; ++i) { |
335 if (failed()) break; | 335 if (failed()) break; |
336 TRACE("DecodeImportTable[%d] module+%d\n", i, | 336 TRACE("DecodeImportTable[%d] module+%d\n", i, |
337 static_cast<int>(pc_ - start_)); | 337 static_cast<int>(pc_ - start_)); |
338 | 338 |
339 module->import_table.push_back({nullptr, // sig | 339 module->import_table.push_back({nullptr, // sig |
340 0, // sig_index | 340 0, // sig_index |
341 0, // module_name_offset | 341 0, // module_name_offset |
342 0, // module_name_length | 342 0, // module_name_length |
343 0, // function_name_offset | 343 0, // function_name_offset |
344 0}); // function_name_length | 344 0}); // function_name_length |
(...skipping 12 matching lines...) Expand all Loading... |
357 break; | 357 break; |
358 } | 358 } |
359 case WasmSection::Code::ExportTable: { | 359 case WasmSection::Code::ExportTable: { |
360 // Declares an export table. | 360 // Declares an export table. |
361 CheckForFunctions(module, section); | 361 CheckForFunctions(module, section); |
362 int length; | 362 int length; |
363 uint32_t export_table_count = | 363 uint32_t export_table_count = |
364 consume_u32v(&length, "export table count"); | 364 consume_u32v(&length, "export table count"); |
365 module->export_table.reserve(SafeReserve(export_table_count)); | 365 module->export_table.reserve(SafeReserve(export_table_count)); |
366 // Decode export table. | 366 // Decode export table. |
367 for (uint32_t i = 0; i < export_table_count; i++) { | 367 for (uint32_t i = 0; i < export_table_count; ++i) { |
368 if (failed()) break; | 368 if (failed()) break; |
369 TRACE("DecodeExportTable[%d] module+%d\n", i, | 369 TRACE("DecodeExportTable[%d] module+%d\n", i, |
370 static_cast<int>(pc_ - start_)); | 370 static_cast<int>(pc_ - start_)); |
371 | 371 |
372 module->export_table.push_back({0, // func_index | 372 module->export_table.push_back({0, // func_index |
373 0, // name_offset | 373 0, // name_offset |
374 0}); // name_length | 374 0}); // name_length |
375 WasmExport* exp = &module->export_table.back(); | 375 WasmExport* exp = &module->export_table.back(); |
376 | 376 |
377 WasmFunction* func; | 377 WasmFunction* func; |
(...skipping 24 matching lines...) Expand all Loading... |
402 it->name_length, pc, last->func_index, it->func_index); | 402 it->name_length, pc, last->func_index, it->func_index); |
403 break; | 403 break; |
404 } | 404 } |
405 } | 405 } |
406 } | 406 } |
407 break; | 407 break; |
408 } | 408 } |
409 case WasmSection::Code::Max: | 409 case WasmSection::Code::Max: |
410 // Skip unknown sections. | 410 // Skip unknown sections. |
411 TRACE("Unknown section: '"); | 411 TRACE("Unknown section: '"); |
412 for (uint32_t i = 0; i != string_length; i++) { | 412 for (uint32_t i = 0; i != string_length; ++i) { |
413 TRACE("%c", *(section_name_start + i)); | 413 TRACE("%c", *(section_name_start + i)); |
414 } | 414 } |
415 TRACE("'\n"); | 415 TRACE("'\n"); |
416 consume_bytes(section_length); | 416 consume_bytes(section_length); |
417 break; | 417 break; |
418 } | 418 } |
419 | 419 |
420 if (pc_ != expected_section_end) { | 420 if (pc_ != expected_section_end) { |
421 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; | 421 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; |
422 size_t expected_length = static_cast<size_t>(section_length); | 422 size_t expected_length = static_cast<size_t>(section_length); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 byte form = consume_u8("type form"); | 700 byte form = consume_u8("type form"); |
701 if (form != kWasmFunctionTypeForm) { | 701 if (form != kWasmFunctionTypeForm) { |
702 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 702 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
703 kWasmFunctionTypeForm, form); | 703 kWasmFunctionTypeForm, form); |
704 return nullptr; | 704 return nullptr; |
705 } | 705 } |
706 int length; | 706 int length; |
707 // parse parameter types | 707 // parse parameter types |
708 uint32_t param_count = consume_u32v(&length, "param count"); | 708 uint32_t param_count = consume_u32v(&length, "param count"); |
709 std::vector<LocalType> params; | 709 std::vector<LocalType> params; |
710 for (uint32_t i = 0; i < param_count; i++) { | 710 for (uint32_t i = 0; i < param_count; ++i) { |
711 LocalType param = consume_local_type(); | 711 LocalType param = consume_local_type(); |
712 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 712 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
713 params.push_back(param); | 713 params.push_back(param); |
714 } | 714 } |
715 | 715 |
716 // parse return types | 716 // parse return types |
717 const byte* pt = pc_; | 717 const byte* pt = pc_; |
718 uint32_t return_count = consume_u32v(&length, "return count"); | 718 uint32_t return_count = consume_u32v(&length, "return count"); |
719 if (return_count > kMaxReturnCount) { | 719 if (return_count > kMaxReturnCount) { |
720 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, | 720 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, |
721 kMaxReturnCount); | 721 kMaxReturnCount); |
722 return nullptr; | 722 return nullptr; |
723 } | 723 } |
724 std::vector<LocalType> returns; | 724 std::vector<LocalType> returns; |
725 for (uint32_t i = 0; i < return_count; i++) { | 725 for (uint32_t i = 0; i < return_count; ++i) { |
726 LocalType ret = consume_local_type(); | 726 LocalType ret = consume_local_type(); |
727 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); | 727 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); |
728 returns.push_back(ret); | 728 returns.push_back(ret); |
729 } | 729 } |
730 | 730 |
731 // FunctionSig stores the return types first. | 731 // FunctionSig stores the return types first. |
732 LocalType* buffer = | 732 LocalType* buffer = |
733 module_zone->NewArray<LocalType>(param_count + return_count); | 733 module_zone->NewArray<LocalType>(param_count + return_count); |
734 uint32_t b = 0; | 734 uint32_t b = 0; |
735 for (uint32_t i = 0; i < return_count; i++) buffer[b++] = returns[i]; | 735 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; |
736 for (uint32_t i = 0; i < param_count; i++) buffer[b++] = params[i]; | 736 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; |
737 | 737 |
738 return new (module_zone) FunctionSig(return_count, param_count, buffer); | 738 return new (module_zone) FunctionSig(return_count, param_count, buffer); |
739 } | 739 } |
740 }; | 740 }; |
741 | 741 |
742 // Helpers for nice error messages. | 742 // Helpers for nice error messages. |
743 class ModuleError : public ModuleResult { | 743 class ModuleError : public ModuleResult { |
744 public: | 744 public: |
745 explicit ModuleError(const char* msg) { | 745 explicit ModuleError(const char* msg) { |
746 error_code = kError; | 746 error_code = kError; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 if (!code_section.start()) decoder.error("no code section"); | 856 if (!code_section.start()) decoder.error("no code section"); |
857 | 857 |
858 int length; | 858 int length; |
859 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); | 859 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); |
860 FunctionOffsets table; | 860 FunctionOffsets table; |
861 // Take care of invalid input here. | 861 // Take care of invalid input here. |
862 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) | 862 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) |
863 table.reserve(functions_count); | 863 table.reserve(functions_count); |
864 int section_offset = static_cast<int>(code_section.start() - module_start); | 864 int section_offset = static_cast<int>(code_section.start() - module_start); |
865 DCHECK_LE(0, section_offset); | 865 DCHECK_LE(0, section_offset); |
866 for (uint32_t i = 0; i < functions_count && decoder.ok(); i++) { | 866 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { |
867 uint32_t size = decoder.consume_u32v(&length, "body size"); | 867 uint32_t size = decoder.consume_u32v(&length, "body size"); |
868 int offset = static_cast<int>(section_offset + decoder.pc_offset()); | 868 int offset = static_cast<int>(section_offset + decoder.pc_offset()); |
869 table.push_back(std::make_pair(offset, static_cast<int>(size))); | 869 table.push_back(std::make_pair(offset, static_cast<int>(size))); |
870 DCHECK(table.back().first >= 0 && table.back().second >= 0); | 870 DCHECK(table.back().first >= 0 && table.back().second >= 0); |
871 decoder.consume_bytes(size); | 871 decoder.consume_bytes(size); |
872 } | 872 } |
873 if (decoder.more()) decoder.error("unexpected additional bytes"); | 873 if (decoder.more()) decoder.error("unexpected additional bytes"); |
874 | 874 |
875 return decoder.toResult(std::move(table)); | 875 return decoder.toResult(std::move(table)); |
876 } | 876 } |
877 | 877 |
878 } // namespace wasm | 878 } // namespace wasm |
879 } // namespace internal | 879 } // namespace internal |
880 } // namespace v8 | 880 } // namespace v8 |
OLD | NEW |