| 946 | } |
| 947 | |
| 948 | void ParseContext::parse_datasection() { |
| 949 | tok_.expect(TokenType::LParen); |
| 950 | tok_.expect_keyword("data"); |
| 951 | index_t data_idx = module_.datas.size(); |
| 952 | // optional Id |
| 953 | if (tok_.peek().type == TokenType::Id) { |
| 954 | std::string id = tok_.consume().text; |
| 955 | if (data_map_.contains(id)) |
| 956 | throw Exception::Parse("duplicated data id '" + id + "'", tok_.location()); |
| 957 | data_map_[id] = data_idx; |
| 958 | } |
| 959 | |
| 960 | WasmData& data = module_.datas.emplace_back(); |
| 961 | data.mode.type = WasmData::DataMode::Mode::passive; |
| 962 | |
| 963 | // Check for memuse or offset |
| 964 | if (tok_.peek().type == TokenType::LParen) { |
| 965 | const Token& kw = tok_.peek2(); |
| 966 | if (kw.type == TokenType::Keyword) { |
| 967 | if (kw.text == "memory") { |
| 968 | // memuse: '(' 'memory' memidx ')' |
| 969 | tok_.consume(); tok_.consume(); |
| 970 | data.mode.memidx = parse_memidx(); |
| 971 | tok_.expect(TokenType::RParen); |
| 972 | } |
| 973 | // offset clause |
| 974 | if (tok_.peek().type == TokenType::LParen && |
| 975 | tok_.peek2().type == TokenType::Keyword && |
| 976 | (tok_.peek2().text == "offset" || |
| 977 | tok_.peek2().text == "i32.const" || tok_.peek2().text == "i64.const" || |
| 978 | tok_.peek2().text == "f32.const" || tok_.peek2().text == "f64.const" || |
| 979 | tok_.peek2().text == "ref.null" || tok_.peek2().text == "ref.func" || |
| 980 | tok_.peek2().text == "global.get")) { |
| 981 | tok_.consume(); // '(' |
| 982 | if (tok_.peek_keyword("offset")) tok_.consume(); |
| 983 | data.mode.offset = parse_constexpr(); |
| 984 | tok_.expect(TokenType::RParen); |
| 985 | data.mode.type = WasmData::DataMode::Mode::active; |
| 986 | if (!data.mode.memidx.has_value()) data.mode.memidx = 0; |
| 987 | } |
| 988 | } |
| 989 | } |
| 990 | |
| 991 | // String* — data bytes |
| 992 | while (tok_.peek().type == TokenType::String) { |
| 993 | std::string bytes = parse_string_to_bytes(tok_.consume().text); |
| 994 | size_t orig = data.init.size(); |
| 995 | data.init.resize(orig + bytes.size()); |
| 996 | std::memcpy(data.init.data() + orig, bytes.data(), bytes.size()); |
| 997 | } |
| 998 | tok_.expect(TokenType::RParen); |
| 999 | } |
| 1000 | |
| 1001 | // ── Tag section ─────────────────────────────────────────────────────────────── |
| 1002 |
nothing calls this directly
no test coverage detected