diff --git a/examples/x11.zr b/examples/x11.zr new file mode 100644 index 0000000..1c2a02b --- /dev/null +++ b/examples/x11.zr @@ -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) diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 6385ac1..1b03ef2 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -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"); diff --git a/test.zr b/test.zr index 6dc2cc3..9994569 100644 --- a/test.zr +++ b/test.zr @@ -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()