1 ;;; ========================================
2 ;;; Dynamic memory management. Allocated with MALLOC and released with
6 ;; Allocates memory (using brk)
7 WORD p_malloc,'MALLOC',fasm
8 pushr rsi ; pretend it's a FORTH word since it
9 ; ends via sys_mmap_asm
11 push qword 0 ; address of mapping (suggestion)
12 push rax ; length of mapping
13 push qword 3 ; protection mode PROT_READ | PROT_WRITE
14 push qword 8226 ; flags PRIVATE | ANONYMOUS | LOCKED
17 jmp sys_mmap_asm ; exit via sys_mmap
19 ;;; ========================================
20 ;;; Input stream handling.
22 ;;; An input stream for a file descriptor has a stream buffer that is
23 ;;; gradually filled on needs basis. The stream buffer includes a
24 ;;; header portion with:
25 ;;; * size of buffer (excluding the 32 byte head)
26 ;;; * source file descriptor (or -1 for pure in-core data)
28 ;;; * current read position
30 ;;; An input stream for a memory block as a "detached" stream head
35 ;;; * current read position (starts at 8 = after block size)
37 WORD p_stream,'STREAM',fasm
38 ;; ( fd size -- addr ) or ( block -1 -- addr )
39 ;; Allocates a stream buffer of the given size and initializes
40 ;; it to be filled from the given input file descriptor.
46 DOFORTH p_malloc ; ( fd size addr )
48 push qword [rsp+16] ; ( fd size addr addr size )
49 DOFORTH p_erase ; ( fd size addr )
50 pop rax ; addr ( fd size )
52 sub rbx,32 ; reduce by header size
60 push 32 ; size of detached header (wastefull?)
61 DOFORTH p_malloc ; ( block addr )
62 pop rax ; header address
63 pop rbx ; block address
64 mov rcx,[rbx] ; block content size (excludes size field)
65 add rbx,8 ; block content address
66 mov qword [rax],rbx ; save block content address
67 mov qword [rax+8],-1 ; -1 = memblock flag
68 mov qword [rax+16],rcx ; save block content size
69 mov qword [rax+24],0 ; current position
73 ;;; ========================================
75 ;;; READ-STREAM-CHAR ( stream -- ch )
77 WORD p_read_stream_char,'READ-STREAM-CHAR',fasm
81 mov rbx,[rax+16] ; fill
83 p_read_stream_char.READ:
84 mov rcx,[rax+24] ; current
86 jg p_read_stream_char.CHAR
88 ;; pull in more from the source, if any
89 cmp qword [rax+8],-1 ; fd == -1 for "no source"
90 je p_read_stream_char.EOF
92 push qword [rax+8] ; fd
95 push qword [rax] ; size
102 jle p_read_stream_char.EOF
103 mov qword[rax+16],rbx
104 jmp p_read_stream_char.READ
106 p_read_stream_char.EOF:
111 p_read_stream_char.CHAR:
120 ;;; ========================================
123 WORD p_pad,'PAD',dovariable
124 ;; A buffer for holding a word
127 WORD p_read_word,'READ-WORD',fasm
128 ;; ( stream -- char* length )
129 ;; Read next word from the given stream into the PAD
136 p_read_word_skipblanks:
139 dq p_read_stream_char
143 jl p_read_word_nomore
145 jle p_read_word_skipblanks
147 p_read_word_readword:
148 ;; ( buffer length stream )
149 mov rax,qword [rsp+16]
150 mov rcx,qword [rsp+8]
155 dq p_read_stream_char
159 jl p_read_word_nomore
161 jg p_read_word_readword
168 WORD p_tell,'TELL',fasm
170 ;; Write n bytes from chars* to stdout
184 WORD p_emit,'EMIT',fasm
186 ;; Write byte to stdout
189 mov [p_emit_buffer],al