| 41 | } |
| 42 | |
| 43 | Expect<void> Loader::loadComponent(AST::Component::Component &Comp, |
| 44 | std::optional<uint64_t> Bound) { |
| 45 | auto ReportError = [](auto E) { |
| 46 | spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Component)); |
| 47 | return E; |
| 48 | }; |
| 49 | // component ::= <preamble> s*:<section>* => (component flatten(s*)) |
| 50 | // section ::= section_0(<core:custom>) => ϵ |
| 51 | // | m: section_1(<core:module>) => [core-prefix(m)] |
| 52 | // | i*:section_2(vec(<core:instance>)) => core-prefix(i)* |
| 53 | // | t*:section_3(vec(<core:type>)) => core-prefix(t)* |
| 54 | // | c: section_4(<component>) => [c] |
| 55 | // | i*:section_5(vec(<instance>)) => i* |
| 56 | // | a*:section_6(vec(<alias>)) => a* |
| 57 | // | t*:section_7(vec(<type>)) => t* |
| 58 | // | c*:section_8(vec(<canon>)) => c* |
| 59 | // | s: section_9(<start>) => [s] |
| 60 | // | i*:section_10(vec(<import>)) => i* |
| 61 | // | e*:section_11(vec(<export>)) => e* |
| 62 | // | v*:section_12(vec(<value>)) => v* 🪙 |
| 63 | uint64_t StartOffset = FMgr.getOffset(); |
| 64 | uint64_t Offset = FMgr.getOffset(); |
| 65 | Expect<Byte> ResSecId; |
| 66 | |
| 67 | while ((!Bound.has_value() || *Bound > Offset - StartOffset) && |
| 68 | (ResSecId = FMgr.readByte())) { |
| 69 | if (!ResSecId) { |
| 70 | return logLoadError(ResSecId.error(), FMgr.getLastOffset(), |
| 71 | ASTNodeAttr::Component); |
| 72 | } |
| 73 | // keep going only if we have new section ID |
| 74 | uint8_t NewSectionId = *ResSecId; |
| 75 | Comp.getSections().emplace_back(); |
| 76 | auto &Sec = Comp.getSections().back(); |
| 77 | |
| 78 | switch (NewSectionId) { |
| 79 | case 0x00: |
| 80 | EXPECTED_TRY(loadSection(Sec.emplace<AST::CustomSection>()) |
| 81 | .map_error(ReportError)); |
| 82 | break; |
| 83 | case 0x01: |
| 84 | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreModuleSection>()) |
| 85 | .map_error(ReportError)); |
| 86 | break; |
| 87 | case 0x02: |
| 88 | EXPECTED_TRY( |
| 89 | loadSection(Sec.emplace<AST::Component::CoreInstanceSection>()) |
| 90 | .map_error(ReportError)); |
| 91 | break; |
| 92 | case 0x03: |
| 93 | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreTypeSection>()) |
| 94 | .map_error(ReportError)); |
| 95 | break; |
| 96 | case 0x04: |
| 97 | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ComponentSection>()) |
| 98 | .map_error(ReportError)); |
| 99 | break; |
| 100 | case 0x05: |
nothing calls this directly
no test coverage detected