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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 353 |
354 module->export_table.push_back({0, // func_index | 354 module->export_table.push_back({0, // func_index |
355 0, // name_offset | 355 0, // name_offset |
356 0}); // name_length | 356 0}); // name_length |
357 WasmExport* exp = &module->export_table.back(); | 357 WasmExport* exp = &module->export_table.back(); |
358 | 358 |
359 WasmFunction* func; | 359 WasmFunction* func; |
360 exp->func_index = consume_func_index(module, &func); | 360 exp->func_index = consume_func_index(module, &func); |
361 exp->name_offset = consume_string(&exp->name_length, true); | 361 exp->name_offset = consume_string(&exp->name_length, true); |
362 } | 362 } |
| 363 // Check for duplicate exports. |
| 364 if (ok() && module->export_table.size() > 1) { |
| 365 std::vector<WasmExport> sorted_exports(module->export_table); |
| 366 const byte* base = start_; |
| 367 auto cmp_less = [base](const WasmExport& a, const WasmExport& b) { |
| 368 // Return true if a < b. |
| 369 uint32_t len = a.name_length; |
| 370 if (len != b.name_length) return len < b.name_length; |
| 371 return memcmp(base + a.name_offset, base + b.name_offset, len) < |
| 372 0; |
| 373 }; |
| 374 std::stable_sort(sorted_exports.begin(), sorted_exports.end(), |
| 375 cmp_less); |
| 376 auto it = sorted_exports.begin(); |
| 377 WasmExport* last = &*it++; |
| 378 for (auto end = sorted_exports.end(); it != end; last = &*it++) { |
| 379 DCHECK(!cmp_less(*it, *last)); // Vector must be sorted. |
| 380 if (!cmp_less(*last, *it)) { |
| 381 const byte* pc = start_ + it->name_offset; |
| 382 error(pc, pc, |
| 383 "Duplicate export name '%.*s' for functions %d and %d", |
| 384 it->name_length, pc, last->func_index, it->func_index); |
| 385 break; |
| 386 } |
| 387 } |
| 388 } |
363 break; | 389 break; |
364 } | 390 } |
365 case WasmSection::Code::Max: | 391 case WasmSection::Code::Max: |
366 // Skip unknown sections. | 392 // Skip unknown sections. |
367 TRACE("Unknown section: '"); | 393 TRACE("Unknown section: '"); |
368 for (uint32_t i = 0; i != string_length; ++i) { | 394 for (uint32_t i = 0; i != string_length; ++i) { |
369 TRACE("%c", *(section_name_start + i)); | 395 TRACE("%c", *(section_name_start + i)); |
370 } | 396 } |
371 TRACE("'\n"); | 397 TRACE("'\n"); |
372 consume_bytes(section_length); | 398 consume_bytes(section_length); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 decoder.consume_bytes(size); | 853 decoder.consume_bytes(size); |
828 } | 854 } |
829 if (decoder.more()) decoder.error("unexpected additional bytes"); | 855 if (decoder.more()) decoder.error("unexpected additional bytes"); |
830 | 856 |
831 return decoder.toResult(std::move(table)); | 857 return decoder.toResult(std::move(table)); |
832 } | 858 } |
833 | 859 |
834 } // namespace wasm | 860 } // namespace wasm |
835 } // namespace internal | 861 } // namespace internal |
836 } // namespace v8 | 862 } // namespace v8 |
OLD | NEW |