code wiki / _hdl_build / nx_wasm_emit2.nx
nx_wasm_emit2.nx source
↩ module page · 84 lines · 3651 B
1// nx_wasm_emit2.nx -- G-WASM-001 milestone 2: emit a REAL function module byte-by-byte
2// (memory section + param + local + local.get/set + i64.const + i64.add + multi-export),
3// the encoding actual game code needs. Reuses leb128.nx. Verified byte-exact vs WABT used
4// ONCE as an alignment oracle, then WABT leaves the path. NO node/python/WABT in this organ.
5// Target module:
6// (module (memory (export "memory") 1)
7// (func (export "f") (param i64) (result i64) (local i64)
8// local.get 0 i64.const 5 i64.add local.set 1 local.get 1))
9// license_tier: ORIGINAL
10import "leb128.nx"
11import "nx_syscalls.nx"
12const K_MAGIC_1024: i64 = 1024
13
14func w8(b: *u8, p: i64, v: i64) -> i64 { b[p] = v as u8; return p + 1 }
15func wcopy(dst: *u8, dp: i64, src: *u8, n: i64) -> i64 {
16 var i: i64 = 0
17 while i < n { dst[dp + i] = src[i]; i = i + 1 }
18 return dp + n
19}
20func emit_section(out: *u8, p: i64, id: i64, sc: *u8, sclen: i64) -> i64 {
21 var q: i64 = w8(out, p, id)
22 q = q + uleb128_encode(sclen, out, q)
23 q = wcopy(out, q, sc, sclen)
24 return q
25}
26
27func main() -> i64 {
28 let out: *u8 = sys_mmap(K_MAGIC_1024)
29 let sc: *u8 = sys_mmap(K_MAGIC_1024)
30 let body: *u8 = sys_mmap(256)
31 var p: i64 = 0
32 p = w8(out, p, 0); p = w8(out, p, 0x61); p = w8(out, p, 0x73); p = w8(out, p, 0x6D)
33 p = w8(out, p, 1); p = w8(out, p, 0); p = w8(out, p, 0); p = w8(out, p, 0)
34 // type section: func (i64)->(i64)
35 var s: i64 = 0
36 s = w8(sc, s, 1) // type count
37 s = w8(sc, s, 0x60) // functype
38 s = w8(sc, s, 1) // param count
39 s = w8(sc, s, 0x7E) // i64 param
40 s = w8(sc, s, 1) // result count
41 s = w8(sc, s, 0x7E) // i64 result
42 p = emit_section(out, p, 1, sc, s)
43 // function section
44 s = 0
45 s = w8(sc, s, 1); s = w8(sc, s, 0)
46 p = emit_section(out, p, 3, sc, s)
47 // memory section: 1 mem, limits flag 0 min 1
48 s = 0
49 s = w8(sc, s, 1); s = w8(sc, s, 0); s = w8(sc, s, 1)
50 p = emit_section(out, p, 5, sc, s)
51 // export section: "memory"(mem 0) + "f"(func 0)
52 s = 0
53 s = w8(sc, s, 2) // export count
54 s = w8(sc, s, 6) // "memory" len
55 s = w8(sc, s, 0x6D); s = w8(sc, s, 0x65); s = w8(sc, s, 0x6D); s = w8(sc, s, 0x6F); s = w8(sc, s, 0x72); s = w8(sc, s, 0x79)
56 s = w8(sc, s, 2); s = w8(sc, s, 0) // kind mem, idx 0
57 s = w8(sc, s, 1) // "f" len
58 s = w8(sc, s, 0x66)
59 s = w8(sc, s, 0); s = w8(sc, s, 0) // kind func, idx 0
60 p = emit_section(out, p, 7, sc, s)
61 // code section: locals (1 i64) + local.get 0; i64.const 5; i64.add; local.set 1; local.get 1; end
62 var bp: i64 = 0
63 bp = w8(body, bp, 1) // local group count
64 bp = w8(body, bp, 1) // count in group
65 bp = w8(body, bp, 0x7E) // i64
66 bp = w8(body, bp, 0x20); bp = bp + uleb128_encode(0, body, bp) // local.get 0
67 bp = w8(body, bp, 0x42); bp = bp + sleb128_encode(5, body, bp) // i64.const 5
68 bp = w8(body, bp, 0x7C) // i64.add
69 bp = w8(body, bp, 0x21); bp = bp + uleb128_encode(1, body, bp) // local.set 1
70 bp = w8(body, bp, 0x20); bp = bp + uleb128_encode(1, body, bp) // local.get 1
71 bp = w8(body, bp, 0x0B) // end
72 s = 0
73 s = w8(sc, s, 1) // code count
74 s = s + uleb128_encode(bp, sc, s) // code entry size
75 s = wcopy(sc, s, body, bp)
76 p = emit_section(out, p, 10, sc, s)
77 let fd: i64 = sys_openat_wr("knowledge/status/_seed2.wasm" as *u8, 0x1a4)
78 if fd < 0 { sys_exit(1); return 1 }
79 sys_write(fd, out, p)
80 sys_close(fd)
81 sys_write(1, "nx_wasm_emit2: wrote knowledge/status/_seed2.wasm\n" as *u8, 49)
82 sys_exit(0)
83 return 0
84}