blob: 72d627791bb24fc468f61b68b722ff067fcaf2c5 [file] [log] [blame]
;;; TODO: figure out if I need to do something special with the GC here.
[bits 32]
[global _call_list]
[extern length]
[extern elt]
;;; This function should call it's first argument with the arguments from
;;; the cons-list passed as its second argument.
;;; _call_list(function pointer, cons list, edi)
_call_list:
;; esi and edi are callee-saved on x86, these are the only registers
;; we clobber.
push esi
push edi
push ebp
mov ebp, esp
mov edi, [ebp + 20] ; Cons list
push edi
call length ; Length of cons list in eax
add esp, 4
mov ecx, eax ; Store length in counter
;; Reserve space for all the stack items
shl eax, 2
sub esp, eax
mov esi, esp ; Pointer to top of stack
;; Skip all of this if there are no arguments
cmp ecx, 0
je .done
.loop:
;; Get the previous item. At the start ecx = the length so to get the last
;; index we need to subtract 1
dec ecx
push ecx
push edi
call elt
add esp, 4
pop ecx ; This is a scratch register, remember
;; We now have the ecx-th item in eax
;; Remember esi is the top of the stack area reserved, so
mov [esi + 4 * ecx], eax
jcxz .done
jmp .loop
.done:
mov ebx, [ebp + 16] ; Function pointer
mov edi, [ebp + 24] ; Closure data pointer
call ebx
mov esp, ebp
pop ebp
pop edi
pop esi
ret