Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Last active August 31, 2025 23:01
Show Gist options
  • Save andrewrk/838a3408d10b2eb220c42311fa2716a4 to your computer and use it in GitHub Desktop.
Save andrewrk/838a3408d10b2eb220c42311fa2716a4 to your computer and use it in GitHub Desktop.
litmus test for restricted function pointer types
andy@bark ~/d/z/build-release (master) [1]> stage3/bin/zig build-obj test.zig -target avr-freestanding -OReleaseFast
andy@bark ~/d/z/build-release (master)> ~/local/llvm20-assert/bin/llvm-objdump -d test.o
test.o: file format elf32-avr
Disassembly of section .text:
00000000 <example>:
0: 6f 92 7f 92 <unknown>
4: 8f 92 9f 92 <unknown>
8: af 92 bf 92 <unknown>
c: cf 92 df 92 <unknown>
10: ef 92 ff 92 <unknown>
14: 0f 93 1f 93 <unknown>
18: cf 93 df 93 <unknown>
1c: cd b7 in r28, 0x3d
1e: de b7 in r29, 0x3e
20: 28 97 0f b6 <unknown>
24: f8 94 cli
26: de bf out 0x3e, r29
28: 0f be out 0x3f, r0
2a: cd bf out 0x3d, r28
2c: 00 e0 ldi r16, 0x0
2e: 10 e0 ldi r17, 0x0
30: c0 90 00 00 <unknown>
34: d0 90 00 00 <unknown>
38: e0 90 00 00 <unknown>
3c: f0 90 00 00 <unknown>
40: 8c 2f mov r24, r28
42: 9d 2f mov r25, r29
44: 01 96 a8 2e <unknown>
48: b9 2e mov r11, r25
4a: 84 e0 ldi r24, 0x4
4c: 90 e0 ldi r25, 0x0
4e: 88 2e mov r8, r24
50: 99 2e mov r9, r25
52: 8c 2f mov r24, r28
54: 9d 2f mov r25, r29
56: 05 96 68 2e <unknown>
5a: 79 2e mov r7, r25
5c: 4a 2d mov r20, r10
5e: 5b 2d mov r21, r11
60: 40 0f add r20, r16
62: 51 1f adc r21, r17
64: 28 2d mov r18, r8
66: 39 2d mov r19, r9
68: 20 1b sub r18, r16
6a: 31 0b sbc r19, r17
6c: 86 2d mov r24, r6
6e: 97 2d mov r25, r7
70: 6e 2d mov r22, r14
72: 7f 2d mov r23, r15
74: ec 2d mov r30, r12
76: fd 2d mov r31, r13
78: 09 95 8d 81 <unknown>
7c: 9e 81 ldd r25, Y+6
7e: 08 0f add r16, r24
80: 19 1f adc r17, r25
82: 04 30 cpi r16, 0x4
84: 11 05 cpc r17, r1
86: 50 f3 brlo .-44
88: 8b 81 ldd r24, Y+3
8a: 9c 81 ldd r25, Y+4
8c: 69 81 ldd r22, Y+1
8e: 7a 81 ldd r23, Y+2
90: 28 96 0f b6 <unknown>
94: f8 94 cli
96: de bf out 0x3e, r29
98: 0f be out 0x3f, r0
9a: cd bf out 0x3d, r28
9c: df 91 cf 91 <unknown>
a0: 1f 91 0f 91 <unknown>
a4: ff 90 ef 90 <unknown>
a8: df 90 cf 90 <unknown>
ac: bf 90 af 90 <unknown>
b0: 9f 90 8f 90 <unknown>
b4: 7f 90 6f 90 <unknown>
b8: 08 95 ret
000000ba <io.GenericReader(void,error{},(function 'read')).typeErasedReadFn>:
ba: a4 2f mov r26, r20
bc: b5 2f mov r27, r21
be: 20 91 be ba <unknown>
c2: 2c 93 st X, r18
c4: 20 e0 ldi r18, 0x0
c6: 30 e0 ldi r19, 0x0
c8: e8 2f mov r30, r24
ca: f9 2f mov r31, r25
cc: 33 83 std Z+3, r19
ce: 22 83 std Z+2, r18
d0: 81 e0 ldi r24, 0x1
d2: 90 e0 ldi r25, 0x0
d4: 91 83 std Z+1, r25
d6: 80 83 std Z+0, r24
d8: 08 95 ret
const std = @import("std");
const uart: *volatile u8 = @ptrFromInt(0xbabe);
fn read(context: void, buffer: []u8) error{}!usize {
_ = context;
buffer[0] = uart.*;
return 1;
}
export fn example() u32 {
var reader: std.io.GenericReader(void, error{}, read) = .{
.context = {},
};
return reader.readInt(u32, .little) catch unreachable;
}
andy@bark ~/s/z/build-release (wrangle-writer-buffering) [1]> stage3/bin/zig build-obj test.zig -OReleaseFast -target avr-freestanding
andy@bark ~/s/z/build-release (wrangle-writer-buffering)> ~/local/llvm21-assert/bin/llvm-objdump -d test.o
test.o: file format elf32-avr
Disassembly of section .text:
00000000 <example>:
0: af 92 bf 92 <unknown>
4: cf 92 df 92 <unknown>
8: ef 92 ff 92 <unknown>
c: 0f 93 1f 93 <unknown>
10: cf 93 df 93 <unknown>
14: cd b7 in r28, 0x3d
16: de b7 in r29, 0x3e
18: 66 97 0f b6 <unknown>
1c: f8 94 cli
1e: de bf out 0x3e, r29
20: 0f be out 0x3f, r0
22: cd bf out 0x3d, r28
24: 84 e0 ldi r24, 0x4
26: 90 e0 ldi r25, 0x0
28: 9a 87 std Y+2, r25
2a: 89 87 std Y+1, r24
2c: 8c 2f mov r24, r28
2e: 9d 2f mov r25, r29
30: 01 96 98 87 <unknown>
34: 8f 83 std Y+7, r24
36: 80 e0 ldi r24, 0x0
38: 90 e0 ldi r25, 0x0
3a: 9e 87 std Y+6, r25
3c: 8d 87 std Y+5, r24
3e: 9c 87 std Y+4, r25
40: 8b 87 std Y+3, r24
42: 20 e0 ldi r18, 0x0
44: 30 e0 ldi r19, 0x0
46: 3e 83 std Y+6, r19
48: 2d 83 std Y+5, r18
4a: 9a 8b std Y+2, r25
4c: 89 8b std Y+1, r24
4e: 20 e0 ldi r18, 0x0
50: 30 e0 ldi r19, 0x0
52: 38 8b std Y+0, r19
54: 2f 87 std Y+7, r18
56: 2c 2f mov r18, r28
58: 3d 2f mov r19, r29
5a: 2d 5e subi r18, 0xed
5c: 3f 4f sbci r19, 0xff
5e: e2 2e mov r14, r18
60: f3 2e mov r15, r19
62: 2c 2f mov r18, r28
64: 3d 2f mov r19, r29
66: 2b 5f subi r18, 0xfb
68: 3f 4f sbci r19, 0xff
6a: c2 2e mov r12, r18
6c: d3 2e mov r13, r19
6e: 0c 2f mov r16, r28
70: 1d 2f mov r17, r29
72: 01 5f subi r16, 0xf1
74: 1f 4f sbci r17, 0xff
76: 21 e0 ldi r18, 0x1
78: 30 e0 ldi r19, 0x0
7a: a2 2e mov r10, r18
7c: b3 2e mov r11, r19
7e: 28 2f mov r18, r24
80: 39 2f mov r19, r25
82: e8 2f mov r30, r24
84: f9 2f mov r31, r25
86: 34 96 2e 17 <unknown>
8a: 3f 07 cpc r19, r31
8c: a0 f4 brsh .+40
8e: ed 81 ldd r30, Y+5
90: fe 81 ldd r31, Y+6
92: a4 81 ldd r26, Z+4
94: b5 81 ldd r27, Z+5
96: 8e 2d mov r24, r14
98: 9f 2d mov r25, r15
9a: 6c 2d mov r22, r12
9c: 7d 2d mov r23, r13
9e: 40 2f mov r20, r16
a0: 51 2f mov r21, r17
a2: 2a 2d mov r18, r10
a4: 3b 2d mov r19, r11
a6: ea 2f mov r30, r26
a8: fb 2f mov r31, r27
aa: 09 95 8b 85 <unknown>
ae: 9c 85 ldd r25, Y+4
b0: 2d 85 ldd r18, Y+5
b2: 3e 85 ldd r19, Y+6
b4: e6 cf rjmp .-52
b6: fc 87 std Y+4, r31
b8: eb 87 std Y+3, r30
ba: 2f 81 ldd r18, Y+7
bc: 38 85 ldd r19, Y+0
be: 28 0f add r18, r24
c0: 39 1f adc r19, r25
c2: e2 2f mov r30, r18
c4: f3 2f mov r31, r19
c6: 60 81 ldd r22, Z+0
c8: 71 81 ldd r23, Z+1
ca: 82 81 ldd r24, Z+2
cc: 93 81 ldd r25, Z+3
ce: 66 96 0f b6 <unknown>
d2: f8 94 cli
d4: de bf out 0x3e, r29
d6: 0f be out 0x3f, r0
d8: cd bf out 0x3d, r28
da: df 91 cf 91 <unknown>
de: 1f 91 0f 91 <unknown>
e2: ff 90 ef 90 <unknown>
e6: df 90 cf 90 <unknown>
ea: bf 90 af 90 <unknown>
ee: 08 95 ret
000000f0 <test.stream>:
f0: 2f 92 3f 92 <unknown>
f4: 4f 92 5f 92 <unknown>
f8: 6f 92 7f 92 <unknown>
fc: 8f 92 9f 92 <unknown>
100: bf 92 cf 92 <unknown>
104: df 92 ef 92 <unknown>
108: ff 92 0f 93 <unknown>
10c: 1f 93 cf 93 <unknown>
110: df 93 cd b7 <unknown>
114: de b7 in r29, 0x3e
116: 2d 97 0f b6 <unknown>
11a: f8 94 cli
11c: de bf out 0x3e, r29
11e: 0f be out 0x3f, r0
120: cd bf out 0x3d, r28
122: c4 2e mov r12, r20
124: d5 2e mov r13, r21
126: e8 2e mov r14, r24
128: f9 2e mov r15, r25
12a: 21 15 cp r18, r1
12c: 31 05 cpc r19, r1
12e: 09 f4 brne .+2
130: 5d c0 rjmp .+186
132: b0 90 be ba <unknown>
136: ec 2d mov r30, r12
138: fd 2d mov r31, r13
13a: 01 e0 ldi r16, 0x1
13c: 10 e0 ldi r17, 0x0
13e: ac 2f mov r26, r28
140: bd 2f mov r27, r29
142: 14 96 8c 2f <unknown>
146: 9d 2f mov r25, r29
148: 0a 96 4c 2f <unknown>
14c: 5d 2f mov r21, r29
14e: 4b 5f subi r20, 0xfb
150: 5f 4f sbci r21, 0xff
152: 66 81 ldd r22, Z+6
154: 77 81 ldd r23, Z+7
156: 24 81 ldd r18, Z+4
158: 35 81 ldd r19, Z+5
15a: 26 17 cp r18, r22
15c: 37 07 cpc r19, r23
15e: 09 f0 breq .+2
160: 30 c0 rjmp .+96
162: 8e 2e mov r8, r30
164: 9f 2e mov r9, r31
166: 20 81 ldd r18, Z+0
168: 31 81 ldd r19, Z+1
16a: e2 2f mov r30, r18
16c: f3 2f mov r31, r19
16e: 20 81 ldd r18, Z+0
170: 31 81 ldd r19, Z+1
172: 3b 83 std Y+3, r19
174: 2a 83 std Y+2, r18
176: 18 87 std Y+0, r17
178: 0f 83 std Y+7, r16
17a: 6a 2e mov r6, r26
17c: 7b 2e mov r7, r27
17e: be 83 std Y+6, r27
180: ad 83 std Y+5, r26
182: bc 82 std Y+4, r11
184: 48 2e mov r4, r24
186: 59 2e mov r5, r25
188: 6c 2d mov r22, r12
18a: 7d 2d mov r23, r13
18c: 24 2e mov r2, r20
18e: 35 2e mov r3, r21
190: 20 2f mov r18, r16
192: 31 2f mov r19, r17
194: ea 81 ldd r30, Y+2
196: fb 81 ldd r31, Y+3
198: 09 95 8c 85 <unknown>
19c: 9d 85 ldd r25, Y+5
19e: 81 15 cp r24, r1
1a0: 91 05 cpc r25, r1
1a2: 09 f0 breq .+2
1a4: 43 c0 rjmp .+134
1a6: 8a 85 ldd r24, Y+2
1a8: 9b 85 ldd r25, Y+3
1aa: 81 15 cp r24, r1
1ac: 91 05 cpc r25, r1
1ae: e8 2d mov r30, r8
1b0: f9 2d mov r31, r9
1b2: a6 2d mov r26, r6
1b4: b7 2d mov r27, r7
1b6: 84 2d mov r24, r4
1b8: 95 2d mov r25, r5
1ba: 42 2d mov r20, r2
1bc: 53 2d mov r21, r3
1be: 69 f4 brne .+26
1c0: c8 cf rjmp .-112
1c2: ec 2d mov r30, r12
1c4: fd 2d mov r31, r13
1c6: a2 81 ldd r26, Z+2
1c8: b3 81 ldd r27, Z+3
1ca: a6 0f add r26, r22
1cc: b7 1f adc r27, r23
1ce: bc 92 st X, r11
1d0: 86 81 ldd r24, Z+6
1d2: 97 81 ldd r25, Z+7
1d4: 01 96 97 83 <unknown>
1d8: 86 83 std Z+6, r24
1da: 80 e0 ldi r24, 0x0
1dc: 90 e0 ldi r25, 0x0
1de: ee 2d mov r30, r14
1e0: ff 2d mov r31, r15
1e2: 93 83 std Z+3, r25
1e4: 82 83 std Z+2, r24
1e6: 11 83 std Z+1, r17
1e8: 00 83 std Z+0, r16
1ea: 08 c0 rjmp .+16
1ec: 80 e0 ldi r24, 0x0
1ee: 90 e0 ldi r25, 0x0
1f0: ee 2d mov r30, r14
1f2: ff 2d mov r31, r15
1f4: 93 83 std Z+3, r25
1f6: 82 83 std Z+2, r24
1f8: 91 83 std Z+1, r25
1fa: 80 83 std Z+0, r24
1fc: 2d 96 0f b6 <unknown>
200: f8 94 cli
202: de bf out 0x3e, r29
204: 0f be out 0x3f, r0
206: cd bf out 0x3d, r28
208: df 91 cf 91 <unknown>
20c: 1f 91 0f 91 <unknown>
210: ff 90 ef 90 <unknown>
214: df 90 cf 90 <unknown>
218: bf 90 9f 90 <unknown>
21c: 8f 90 7f 90 <unknown>
220: 6f 90 5f 90 <unknown>
224: 4f 90 3f 90 <unknown>
228: 2f 90 08 95 <unknown>
22c: ee 2d mov r30, r14
22e: ff 2d mov r31, r15
230: 93 83 std Z+3, r25
232: 82 83 std Z+2, r24
234: e3 cf rjmp .-58
00000236 <test.discard>:
236: 41 15 cp r20, r1
238: 51 05 cpc r21, r1
23a: 39 f0 breq .+14
23c: 20 91 be ba <unknown>
240: 40 e0 ldi r20, 0x0
242: 50 e0 ldi r21, 0x0
244: 21 e0 ldi r18, 0x1
246: 30 e0 ldi r19, 0x0
248: 04 c0 rjmp .+8
24a: 20 e0 ldi r18, 0x0
24c: 30 e0 ldi r19, 0x0
24e: 42 2f mov r20, r18
250: 53 2f mov r21, r19
252: e8 2f mov r30, r24
254: f9 2f mov r31, r25
256: 31 83 std Z+1, r19
258: 20 83 std Z+0, r18
25a: 53 83 std Z+3, r21
25c: 42 83 std Z+2, r20
25e: 08 95 ret
00000260 <test.readVec>:
260: e4 2f mov r30, r20
262: f5 2f mov r31, r21
264: a0 81 ldd r26, Z+0
266: b1 81 ldd r27, Z+1
268: 20 91 be ba <unknown>
26c: 2c 93 st X, r18
26e: 20 e0 ldi r18, 0x0
270: 30 e0 ldi r19, 0x0
272: e8 2f mov r30, r24
274: f9 2f mov r31, r25
276: 33 83 std Z+3, r19
278: 22 83 std Z+2, r18
27a: 81 e0 ldi r24, 0x1
27c: 90 e0 ldi r25, 0x0
27e: 91 83 std Z+1, r25
280: 80 83 std Z+0, r24
282: 08 95 ret
00000284 <Io.Reader.defaultRebase>:
284: ef 92 ff 92 <unknown>
288: 0f 93 1f 93 <unknown>
28c: e8 2f mov r30, r24
28e: f9 2f mov r31, r25
290: 26 81 ldd r18, Z+6
292: 37 81 ldd r19, Z+7
294: 82 81 ldd r24, Z+2
296: 93 81 ldd r25, Z+3
298: 68 2f mov r22, r24
29a: 79 2f mov r23, r25
29c: 62 0f add r22, r18
29e: 73 1f adc r23, r19
2a0: 00 85 ldd r16, Z+0
2a2: 11 85 ldd r17, Z+1
2a4: ee 2e mov r14, r30
2a6: ff 2e mov r15, r31
2a8: 02 1b sub r16, r18
2aa: 13 0b sbc r17, r19
2ac: 40 2f mov r20, r16
2ae: 51 2f mov r21, r17
2b0: ff df rcall .-2
2b2: ee 2d mov r30, r14
2b4: ff 2d mov r31, r15
2b6: 11 87 std Z+1, r17
2b8: 00 87 std Z+0, r16
2ba: 80 e0 ldi r24, 0x0
2bc: 90 e0 ldi r25, 0x0
2be: 97 83 std Z+7, r25
2c0: 86 83 std Z+6, r24
2c2: 1f 91 0f 91 <unknown>
2c6: ff 90 ef 90 <unknown>
2ca: 08 95 ret
const std = @import("std");
const uart: *volatile u8 = @ptrFromInt(0xbabe);
fn stream(r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize {
_ = r;
if (limit == .nothing) return 0;
try w.writeByte(uart.*);
return 1;
}
fn discard(r: *std.Io.Reader, limit: std.Io.Limit) std.Io.Reader.Error!usize {
_ = r;
if (limit == .nothing) return 0;
_ = uart.*;
return 1;
}
fn readVec(r: *std.Io.Reader, data: []const []u8) std.Io.Reader.Error!usize {
_ = r;
data[0][0] = uart.*;
return 1;
}
export fn example() u32 {
var buffer: [4]u8 = undefined;
var reader: std.Io.Reader = .{
.buffer = &buffer,
.vtable = &.{
.stream = stream,
.readVec = readVec,
.discard = discard,
},
.seek = 0,
.end = 0,
};
return reader.takeInt(u32, .little) catch unreachable;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment