Emit string data sections at the start of c_program(). After all function definitions and before the main function, emit:
(memory (export "memory") 1)
(data (i32.const 60000) "hello")
(data (i32.const 60005) "world")
Each string gets a (data ...) section that writes its bytes into linear memory at the right address.
fn emit_string_table() void {
emit_str("(memory (export \"memory\") 1)\n");
for (0..str_count) |i| {
emit_str("(data (i32.const ");
emit_num(@intCast(str_addrs[i]));
emit_str(") \"");
// emit bytes, escaping non-printable chars
for (str_table[i]) |c| {
if (c >= 32 and c < 127 and c != '"' and c != '\\') {
emit_byte(c);
} else {
emit_byte('\\');
emit_byte("0123456789abcdef"[c >> 4]);
emit_byte("0123456789abcdef"[c & 0xf]);
}
}
emit_str("\")\n");
}
}
Call emit_string_table() from c_program() after emitting function definitions.