The Compiler, in Its Own Language
self-string-table

String data table using arrays:

var str_addrs: [256]i64 = undefined;
var str_lens: [256]i64 = undefined;
var str_count: i64 = 0;

fn add_str(addr: i64, slen: i64) i64 {
    str_addrs[str_count] = addr;
    str_lens[str_count] = slen;
    str_count += 1;
    return 0;
}

fn emit_string_data() i64 {
    for (0..str_count) |i| {
        emit_s("(data (i32.const ");
        emit_num(str_addrs[i]);
        emit_s(") \"");
        for (0..str_lens[i]) |j| {
            emit_byte(load8(str_addrs[i] + j));
        }
        emit_s("\")\n");
    }
    return 0;
}

Two parallel arrays instead of packed 16-byte records. str_addrs[i] reads cleanly. Nested for loops iterate the table and the bytes.