support more than 6 function args, x11 example

This commit is contained in:
2025-11-13 21:22:27 +01:00
parent 852c463532
commit 552a404d73
3 changed files with 67 additions and 7 deletions

38
examples/x11.zr Normal file
View File

@@ -0,0 +1,38 @@
// musl doesnt like dlopen, needs to be compiled with -m
func main[] : I64
let x11: Ptr = c.dlopen("libX11.so", 2)
let XOpenDisplay: Ptr = c.dlsym(x11, "XOpenDisplay")
let XDefaultRootWindow: Ptr = c.dlsym(x11, "XDefaultRootWindow")
let XCreateSimpleWindow: Ptr = c.dlsym(x11, "XCreateSimpleWindow")
let XMapWindow: Ptr = c.dlsym(x11, "XMapWindow")
let XSelectInput: Ptr = c.dlsym(x11, "XSelectInput")
let XNextEvent: Ptr = c.dlsym(x11, "XNextEvent")
let XBlackPixel: Ptr = c.dlsym(x11, "XBlackPixel")
let XWhitePixel: Ptr = c.dlsym(x11, "XWhitePixel")
let XSetForeground: Ptr = c.dlsym(x11, "XSetForeground")
let XCreateGC: Ptr = c.dlsym(x11, "XCreateGC")
let XDefaultScreen: Ptr = c.dlsym(x11, "XDefaultScreen")
let XDrawString: Ptr = c.dlsym(x11, "XDrawString")
let dpy: Ptr = XOpenDisplay(0)
let screen: Ptr = XDefaultScreen(dpy)
let white: Ptr = XWhitePixel(dpy, screen)
let black: Ptr = XBlackPixel(dpy, screen)
let win: Ptr = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy), 0, 0, 200, 100, 0, black, white)
XSelectInput(dpy, win, 1 << 15)
XMapWindow(dpy, win)
let gc: Ptr = XCreateGC(dpy, win, 0, 0)
XSetForeground(dpy, gc, black)
let ev: Ptr = mem.alloc(256)
while true
XNextEvent(dpy, ev)
if ev[0] == 12
XDrawString(dpy, win, gc, 20, 50, "Hello, World!", 13)

View File

@@ -466,12 +466,28 @@ _builtin_set64:
emit!(&mut self.output, " push rax");
}
for i in (0..args.len()).rev() {
let reg = match REGISTERS.get(i) {
Some(x) => x,
None => return error!(&paren.loc, "only up to 6 args allowed"),
};
emit!(&mut self.output, " pop {}", reg);
let arg_count = args.len();
if arg_count <= 6 {
for i in (0..arg_count).rev() {
emit!(&mut self.output, " pop {}", REGISTERS[i]);
}
} else {
for (i, reg) in REGISTERS.iter().enumerate() {
let offset = 8 * (arg_count - 1 - i);
emit!(
&mut self.output,
" mov {}, QWORD [rsp + {}]",
reg,
offset
);
}
let num_stack = arg_count - 6;
for i in 0..num_stack {
let arg_idx = arg_count - 1 - i;
let offset = 8 * (arg_count - 1 - arg_idx);
emit!(&mut self.output, " mov rax, QWORD [rsp + {}]", offset);
emit!(&mut self.output, " push rax");
}
}
match env.get_var(&callee) {
@@ -487,6 +503,12 @@ _builtin_set64:
emit!(&mut self.output, " call {}", callee);
}
};
if arg_count > 6 {
let num_stack = arg_count - 6;
emit!(&mut self.output, " add rsp, {}", 8 * num_stack);
emit!(&mut self.output, " add rsp, {}", 8 * arg_count);
}
}
Expr::ArrayLiteral(exprs) => {
emit!(&mut self.output, " call array.new");

View File

@@ -10,7 +10,7 @@ func run_test[x: String] : Void
mem.free(cmd)
c.printf(" %ldms\n", build_end_time - build_start_time)
if str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr") | str.equal(x, "raylib.zr")
if str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr") | str.equal(x, "raylib.zr") | str.equal(x, "x11.zr")
c.printf("\033[93mSkipping %s...\033[0m\n", x)
else
let run_start_time: I64 = os.time()