| 598 | // ── Section parsers ─────────────────────────────────────────────────────────── |
| 599 | |
| 600 | void ParseContext::parse_importsection() { |
| 601 | tok_.expect(TokenType::LParen); |
| 602 | tok_.expect_keyword("import"); |
| 603 | std::string mod = parse_string_to_bytes(tok_.expect(TokenType::String).text); |
| 604 | std::string name = parse_string_to_bytes(tok_.expect(TokenType::String).text); |
| 605 | // importdesc |
| 606 | tok_.expect(TokenType::LParen); |
| 607 | Token kw = tok_.expect(TokenType::Keyword, "func/table/memory/global"); |
| 608 | WasmImport& import = module_.imports.emplace_back(); |
| 609 | import.module = mod; import.name = name; |
| 610 | if (kw.text == "func") { |
| 611 | // optional Id |
| 612 | if (tok_.peek().type == TokenType::Id) { |
| 613 | std::string id = tok_.consume().text; |
| 614 | if (func_map_.id_map.contains(id)) |
| 615 | throw Exception::Parse("duplicated func id '" + id + "'", tok_.location()); |
| 616 | func_map_.id_map[id] = func_map_.records.size(); |
| 617 | } |
| 618 | func_map_.records.emplace_back(IndexSpace::Type::Import); |
| 619 | import.desc = parse_typeuse(); |
| 620 | } else if (kw.text == "table") { |
| 621 | if (tok_.peek().type == TokenType::Id) { |
| 622 | std::string id = tok_.consume().text; |
| 623 | if (table_map_.id_map.contains(id)) |
| 624 | throw Exception::Parse("duplicated table id '" + id + "'", tok_.location()); |
| 625 | table_map_.id_map[id] = table_map_.records.size(); |
| 626 | } |
| 627 | table_map_.records.emplace_back(IndexSpace::Type::Import); |
| 628 | import.desc = parse_tabletype(); |
| 629 | } else if (kw.text == "memory") { |
| 630 | if (tok_.peek().type == TokenType::Id) { |
| 631 | std::string id = tok_.consume().text; |
| 632 | if (mem_map_.id_map.contains(id)) |
| 633 | throw Exception::Parse("duplicated memory id '" + id + "'", tok_.location()); |
| 634 | mem_map_.id_map[id] = mem_map_.records.size(); |
| 635 | } |
| 636 | mem_map_.records.emplace_back(IndexSpace::Type::Import); |
| 637 | import.desc = parse_memtype(); |
| 638 | } else if (kw.text == "global") { |
| 639 | if (tok_.peek().type == TokenType::Id) { |
| 640 | std::string id = tok_.consume().text; |
| 641 | if (global_map_.id_map.contains(id)) |
| 642 | throw Exception::Parse("duplicated global id '" + id + "'", tok_.location()); |
| 643 | global_map_.id_map[id] = global_map_.records.size(); |
| 644 | } |
| 645 | global_map_.records.emplace_back(IndexSpace::Type::Import); |
| 646 | import.desc = parse_globaltype(); |
| 647 | } else { |
| 648 | throw Exception::Parse("unknown import desc '" + kw.text + "'", {kw.line, kw.column}); |
| 649 | } |
| 650 | tok_.expect(TokenType::RParen); // close importdesc |
| 651 | tok_.expect(TokenType::RParen); // close import section |
| 652 | } |
| 653 | |
| 654 | void ParseContext::parse_funcsection() { |
| 655 | tok_.expect(TokenType::LParen); |