From 92f33efa0cb88654e1b182416dbac631abf2be49 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 16 Nov 2021 20:49:01 +0100 Subject: Move ret pointer before closed vars in proc calls The previous call convention we had the following before the function call: [ PROC_ADDR | CLOSED_VARS | ARGS | RP ] This was made to be compatible with the `call` instruction and the `cdecl` calling convention. This commit changes the structure to: [ RP | PROC_ADDR | CLOSED_VARS | ARGS ] With this convention, the stack frame can be discarded in its entirety if we have a tail optimized procedure. --- src/compiler.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index d1952ed..1ef81e3 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -343,6 +343,13 @@ compile_cdr(Object *obj) { void compile_call(Object *obj) { context_printf(" ;; --> compile_call\n"); + + // Prepare return pointer. + char *lab_end = generate_label("BDLL"); + context_printf(" lea rcx, [%s]\n", lab_end); + context_printf(" push rcx\n"); + + // Compile operator. compile_object(obj->head); context_printf(" pop rax\n"); context_printf(" mov rcx, PTR_MASK\n"); @@ -379,10 +386,7 @@ compile_call(Object *obj) { compile_object(obj->head); } - char *lab_end = generate_label("BDLL"); context_printf(" mov rax, [rsp + %zu]\n", 8 * offset); - context_printf(" lea rcx, [%s]\n", lab_end); - context_printf(" push rcx\n"); context_printf(" jmp rax\n"); context_printf("%s:\n", lab_end); @@ -535,7 +539,11 @@ compile_lambda(Object *obj) { context_printf(" pop rax\n"); // Restore the previous call frame. - context_printf(" mov rdi, [rbp + 8]\n"); + size_t n_locals = array_size(current_env->locals); + size_t n_params = array_size(current_env->params); + size_t n_captured = array_size(current_env->captured); + size_t offset = 8 * (n_locals + n_params + n_captured + 2); + context_printf(" mov rdi, [rbp + %zu]\n", offset); context_printf(" mov rsp, rbp\n"); context_printf(" add rsp, %zu\n", 8 * array_size(current_env->locals)); context_printf(" pop rbp\n"); @@ -602,7 +610,7 @@ compile_symbol(Object *obj) { size_t n_locals = array_size(current_env->locals); size_t n_params = array_size(current_env->params); size_t n_cap = array_size(current_env->captured); - size_t offset = 8 * (n_locals + n_params + n_cap - idx + 1); + size_t offset = 8 * (n_locals + n_params + n_cap - idx); context_printf(" mov rcx, [rbp + %ld]\n", offset); context_printf(" mov rax, [rcx]\n"); context_printf(" push rax\n"); @@ -624,7 +632,7 @@ compile_symbol(Object *obj) { if (idx != -1) { size_t n_locals = array_size(current_env->locals); size_t n_params = array_size(current_env->params); - size_t offset = 8 * (n_locals + n_params - idx + 1); + size_t offset = 8 * (n_locals + n_params - idx); context_printf(" mov rax, [rbp + %ld]\n", offset); context_printf(" push rax\n"); context_printf(" ;; <-- compile_symbol\n"); -- cgit v1.2.1