blob: 72d627791bb24fc468f61b68b722ff067fcaf2c5 [file] [log] [blame]
swissChili2999dd12021-07-02 14:19:53 -07001;;; TODO: figure out if I need to do something special with the GC here.
2
3 [bits 32]
4 [global _call_list]
5 [extern length]
6 [extern elt]
7 ;;; This function should call it's first argument with the arguments from
8 ;;; the cons-list passed as its second argument.
9
swissChiliddc97542021-07-04 11:47:42 -070010 ;;; _call_list(function pointer, cons list, edi)
swissChili2999dd12021-07-02 14:19:53 -070011_call_list:
swissChiliddc97542021-07-04 11:47:42 -070012 ;; esi and edi are callee-saved on x86, these are the only registers
13 ;; we clobber.
14 push esi
15 push edi
swissChili2999dd12021-07-02 14:19:53 -070016 push ebp
17 mov ebp, esp
18
swissChiliddc97542021-07-04 11:47:42 -070019 mov edi, [ebp + 20] ; Cons list
swissChili2999dd12021-07-02 14:19:53 -070020
21 push edi
22 call length ; Length of cons list in eax
23 add esp, 4
24
25 mov ecx, eax ; Store length in counter
26
27 ;; Reserve space for all the stack items
28 shl eax, 2
29 sub esp, eax
30
31 mov esi, esp ; Pointer to top of stack
32
33 ;; Skip all of this if there are no arguments
34 cmp ecx, 0
35 je .done
36
37.loop:
38 ;; Get the previous item. At the start ecx = the length so to get the last
39 ;; index we need to subtract 1
40 dec ecx
41
42 push ecx
43 push edi
44 call elt
45 add esp, 4
46 pop ecx ; This is a scratch register, remember
47
48 ;; We now have the ecx-th item in eax
49 ;; Remember esi is the top of the stack area reserved, so
50 mov [esi + 4 * ecx], eax
51
52 jcxz .done
53 jmp .loop
54
55.done:
swissChiliddc97542021-07-04 11:47:42 -070056 mov ebx, [ebp + 16] ; Function pointer
57 mov edi, [ebp + 24] ; Closure data pointer
swissChili2999dd12021-07-02 14:19:53 -070058 call ebx
59
60 mov esp, ebp
61 pop ebp
swissChiliddc97542021-07-04 11:47:42 -070062 pop edi
63 pop esi
swissChili2999dd12021-07-02 14:19:53 -070064 ret