~swisschili/bluejay

ref: 84aabeddd1cc358e0fc505d6226fe9c9468da2da bluejay/src/lisp/call_list.s -rw-r--r-- 1.3 KiB
84aabeddswissChili Add GC segmented stack 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;;; 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