MCPcopy Create free account
hub / github.com/WasmVM/WasmVM / parse_memoryinstr

Method parse_memoryinstr

src/lib/parse/instr_parse.cpp:412–505  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

410// ── Memory instructions ───────────────────────────────────────────────────────
411
412WasmInstr ParseContext::parse_memoryinstr(const std::string& name) {
413 if (name == "data.drop") return Instr::Data_drop(parse_dataidx());
414
415 if (name == "memory.copy") {
416 index_t dst = 0, src = 0;
417 if (tok_.peek().type == TokenType::Integer || tok_.peek().type == TokenType::Id) {
418 dst = parse_memidx(); src = parse_memidx();
419 }
420 return Instr::Memory_copy(dst, src);
421 }
422
423 // memory.{size,grow,fill,init}: optional memidx
424 if (name.starts_with("memory.")) {
425 index_t memidx = 0;
426 if (tok_.peek().type == TokenType::Integer || tok_.peek().type == TokenType::Id)
427 memidx = parse_memidx();
428 if (name == "memory.size") return Instr::Memory_size(memidx);
429 if (name == "memory.grow") return Instr::Memory_grow(memidx);
430 if (name == "memory.fill") return Instr::Memory_fill(memidx);
431 if (name == "memory.init") {
432 // memidx? dataidx
433 if (tok_.peek().type == TokenType::Integer || tok_.peek().type == TokenType::Id) {
434 // had memidx, now get dataidx
435 return Instr::Memory_init(memidx, parse_dataidx());
436 }
437 // only one index: it was dataidx
438 return Instr::Memory_init(0, memidx);
439 }
440 }
441
442 // Load/store: optional memidx then memarg
443 index_t memidx = 0;
444 if (tok_.peek().type == TokenType::Integer || tok_.peek().type == TokenType::Id) {
445 // Could be memidx before offset=, but memidx is only present if followed by another token
446 // that is also an index or the next token is offset=/align=
447 // Simple heuristic: if the next token is an integer/id and no offset/align follows immediately
448 // For now: if tok[0] is integer/id and tok[1] is integer/id/offset/align/RParen/EOF → tok[0] is memidx
449 // Actually the WAT spec says memidx is optional and only present in multi-memory proposal.
450 // For simplicity: just try to parse memidx if there's an integer/id before offset= or end
451 // The tokenizer returns Offset/Align for those, so any integer/id here would be memidx.
452 // But we need to be careful — if there's only one integer and it could be the value of
453 // i32.const etc. that came before... no, those are not in memoryinstr context.
454 // The only integer/id that can appear before offset= in a memory instr is memidx.
455 memidx = parse_u32();
456 // Check if there's actually more (otherwise treat as... hmm)
457 // Actually per grammar: memidx? is only for multi-memory. In practice single-memory
458 // modules don't use it. But we should support it.
459 // The ambiguity is: if there's ONE integer before offset/align/end, is it memidx or not?
460 // In single-memory WAT: no memidx appears. In multi-memory: memidx appears.
461 // The grammar says "memidx?" so it's optional. Since an integer here is always memidx
462 // (there's nothing else an integer would be), we're fine.
463 }
464 auto [offset, align] = parse_memarg();
465
466 // Default alignment based on instruction width
467 if (!align.has_value()) {
468 if (name.ends_with("8") || name.ends_with("8_s") || name.ends_with("8_u")) align = 0;
469 else if (name.ends_with("16") || name.ends_with("16_s") || name.ends_with("16_u")) align = 1;

Callers

nothing calls this directly

Calls 5

Memory_copyClass · 0.85
Memory_initClass · 0.85
peekMethod · 0.80
starts_withMethod · 0.80
has_valueMethod · 0.45

Tested by

no test coverage detected