@@ -177,6 +177,10 @@ class BinaryReader {
177177 [[nodiscard]] Result ReadCustomSection (Index section_index,
178178 Offset section_size);
179179 [[nodiscard]] Result ReadTypeSection (Offset section_size);
180+ [[nodiscard]] Result ReadImport (Index i,
181+ std::string_view module_name,
182+ std::string_view field_name,
183+ ExternalKind kind);
180184 [[nodiscard]] Result ReadImportSection (Offset section_size);
181185 [[nodiscard]] Result ReadFunctionSection (Offset section_size);
182186 [[nodiscard]] Result ReadTableSection (Offset section_size);
@@ -2687,72 +2691,111 @@ Result BinaryReader::ReadTypeSection(Offset section_size) {
26872691 return Result::Ok;
26882692}
26892693
2694+ Result BinaryReader::ReadImport (Index i,
2695+ std::string_view module_name,
2696+ std::string_view field_name,
2697+ ExternalKind kind) {
2698+ CALLBACK (OnImport, i, kind, module_name, field_name);
2699+ switch (kind) {
2700+ case ExternalKind::Func: {
2701+ Index sig_index;
2702+ CHECK_RESULT (ReadIndex (&sig_index, " import signature index" ));
2703+ CALLBACK (OnImportFunc, i, module_name, field_name, num_func_imports_,
2704+ sig_index);
2705+ num_func_imports_++;
2706+ break ;
2707+ }
2708+
2709+ case ExternalKind::Table: {
2710+ Limits elem_limits;
2711+ Type elem_type;
2712+ CHECK_RESULT (ReadRefType (&elem_type, " table elem type" ));
2713+ CHECK_RESULT (ReadTable (&elem_limits));
2714+ CALLBACK (OnImportTable, i, module_name, field_name, num_table_imports_,
2715+ elem_type, &elem_limits);
2716+ num_table_imports_++;
2717+ break ;
2718+ }
2719+
2720+ case ExternalKind::Memory: {
2721+ Limits page_limits;
2722+ uint32_t page_size;
2723+ CHECK_RESULT (ReadMemory (&page_limits, &page_size));
2724+ CALLBACK (OnImportMemory, i, module_name, field_name, num_memory_imports_,
2725+ &page_limits, page_size);
2726+ num_memory_imports_++;
2727+ break ;
2728+ }
2729+
2730+ case ExternalKind::Global: {
2731+ Type type;
2732+ bool mutable_;
2733+ CHECK_RESULT (ReadGlobalHeader (&type, &mutable_));
2734+ CALLBACK (OnImportGlobal, i, module_name, field_name, num_global_imports_,
2735+ type, mutable_);
2736+ num_global_imports_++;
2737+ break ;
2738+ }
2739+
2740+ case ExternalKind::Tag: {
2741+ Index sig_index;
2742+ ERROR_UNLESS (options_.features .exceptions_enabled (),
2743+ " invalid import tag kind: exceptions not allowed" );
2744+ CHECK_RESULT (ReadTagType (&sig_index));
2745+ CALLBACK (OnImportTag, i, module_name, field_name, num_tag_imports_,
2746+ sig_index);
2747+ num_tag_imports_++;
2748+ break ;
2749+ }
2750+ }
2751+
2752+ return Result::Ok;
2753+ }
2754+
26902755Result BinaryReader::ReadImportSection (Offset section_size) {
26912756 CALLBACK (BeginImportSection, section_size);
26922757 Index num_imports;
26932758 CHECK_RESULT (ReadCount (&num_imports, " import count" ));
26942759 CALLBACK (OnImportCount, num_imports);
2695- for (Index i = 0 ; i < num_imports; ++i) {
2760+ Index i = 0 ;
2761+ while (i < num_imports) {
26962762 std::string_view module_name;
26972763 CHECK_RESULT (ReadStr (&module_name, " import module name" ));
26982764 std::string_view field_name;
26992765 CHECK_RESULT (ReadStr (&field_name, " import field name" ));
27002766
2701- ExternalKind kind;
2702- CHECK_RESULT (ReadExternalKind (&kind, " import kind" , " import" ));
2703- CALLBACK (OnImport, i, kind, module_name, field_name);
2704-
2705- switch (kind) {
2706- case ExternalKind::Func: {
2707- Index sig_index;
2708- CHECK_RESULT (ReadIndex (&sig_index, " import signature index" ));
2709- CALLBACK (OnImportFunc, i, module_name, field_name, num_func_imports_,
2710- sig_index);
2711- num_func_imports_++;
2712- break ;
2713- }
2714-
2715- case ExternalKind::Table: {
2716- Type elem_type;
2717- Limits elem_limits;
2718- CHECK_RESULT (ReadRefType (&elem_type, " table elem type" ));
2719- CHECK_RESULT (ReadTable (&elem_limits));
2720- CALLBACK (OnImportTable, i, module_name, field_name, num_table_imports_,
2721- elem_type, &elem_limits);
2722- num_table_imports_++;
2723- break ;
2724- }
2725-
2726- case ExternalKind::Memory: {
2727- Limits page_limits;
2728- uint32_t page_size;
2729- CHECK_RESULT (ReadMemory (&page_limits, &page_size));
2730- CALLBACK (OnImportMemory, i, module_name, field_name,
2731- num_memory_imports_, &page_limits, page_size);
2732- num_memory_imports_++;
2733- break ;
2734- }
2767+ uint8_t kind_u8;
2768+ CHECK_RESULT (ReadU8 (&kind_u8, " import kind" ));
27352769
2736- case ExternalKind::Global: {
2737- Type type;
2738- bool mutable_;
2739- CHECK_RESULT (ReadGlobalHeader (&type, &mutable_));
2740- CALLBACK (OnImportGlobal, i, module_name, field_name,
2741- num_global_imports_, type, mutable_);
2742- num_global_imports_++;
2743- break ;
2744- }
2745-
2746- case ExternalKind::Tag: {
2747- ERROR_UNLESS (options_.features .exceptions_enabled (),
2748- " invalid import tag kind: exceptions not allowed" );
2749- Index sig_index;
2750- CHECK_RESULT (ReadTagType (&sig_index));
2751- CALLBACK (OnImportTag, i, module_name, field_name, num_tag_imports_,
2752- sig_index);
2753- num_tag_imports_++;
2754- break ;
2770+ ExternalKind kind;
2771+ if (field_name == " " && (kind_u8 == 0x7F || kind_u8 == 0x7E )) {
2772+ ERROR_UNLESS (options_.features .compact_imports_enabled (),
2773+ " module uses compact imports, but feature not enabled" );
2774+ Index num_compact_imports;
2775+ if (kind_u8 == 0x7E ) {
2776+ // Read the import kind once and re-used for each of num_compact_imports
2777+ CHECK_RESULT (ReadExternalKind (&kind, " compact import kind" , " import" ));
2778+ CHECK_RESULT (ReadCount (&num_compact_imports, " compact import count" ));
2779+ for (Index j = 0 ; j < num_compact_imports; ++j) {
2780+ CHECK_RESULT (ReadStr (&field_name, " compact import field name" ));
2781+ CHECK_RESULT (ReadImport (i++, module_name, field_name, kind));
2782+ }
2783+ } else {
2784+ CHECK_RESULT (ReadCount (&num_compact_imports, " compact import count" ));
2785+ for (Index j = 0 ; j < num_compact_imports; ++j) {
2786+ CHECK_RESULT (ReadStr (&field_name, " compact import field name" ));
2787+ CHECK_RESULT (
2788+ ReadExternalKind (&kind, " compact import kind" , " import" ));
2789+ CHECK_RESULT (ReadImport (i++, module_name, field_name, kind));
2790+ }
27552791 }
2792+ } else {
2793+ // Normal non-compact import
2794+ // kind_u8 was not one of the special values above so rewind one
2795+ // byte so we can read it with ReadExternalKind
2796+ state_.offset --;
2797+ CHECK_RESULT (ReadExternalKind (&kind, " import kind" , " import" ));
2798+ CHECK_RESULT (ReadImport (i++, module_name, field_name, kind));
27562799 }
27572800 }
27582801
0 commit comments