implemented realloc as well as a bunch of fixes and some small changes like changing the order of arguments for !, making alloc drop etc.

This commit is contained in:
IgorCielniak
2026-02-02 15:51:58 +01:00
parent ec826c31b2
commit 5ea020100e
9 changed files with 100 additions and 46 deletions

16
main.py
View File

@@ -2290,18 +2290,18 @@ class Assembler:
"%define RSTK_BYTES 65536", "%define RSTK_BYTES 65536",
"%define PRINT_BUF_BYTES 128", "%define PRINT_BUF_BYTES 128",
"global _start", "global _start",
"global argc", "global sys_argc",
"global argv", "global sys_argv",
"section .data", "section .data",
"argc: dq 0", "sys_argc: dq 0",
"argv: dq 0", "sys_argv: dq 0",
"section .text", "section .text",
"_start:", "_start:",
" ; Linux x86-64 startup: argc/argv from stack", " ; Linux x86-64 startup: argc/argv from stack",
" mov rdi, [rsp]", # argc " mov rdi, [rsp]", # argc
" lea rsi, [rsp+8]", # argv " lea rsi, [rsp+8]", # argv
" mov [rel argc], rdi", " mov [rel sys_argc], rdi",
" mov [rel argv], rsi", " mov [rel sys_argv], rsi",
" ; initialize data/return stack pointers", " ; initialize data/return stack pointers",
" lea r12, [rel dstack_top]", " lea r12, [rel dstack_top]",
" mov r15, r12", " mov r15, r12",
@@ -2480,6 +2480,7 @@ def macro_with(ctx: MacroContext) -> Optional[List[Op]]:
for name in reversed(names): for name in reversed(names):
helper = helper_for[name] helper = helper_for[name]
emitted.append(helper) emitted.append(helper)
emitted.append("swap")
emitted.append("!") emitted.append("!")
i = 0 i = 0
@@ -2491,6 +2492,7 @@ def macro_with(ctx: MacroContext) -> Optional[List[Op]]:
next_tok = body[i + 1] if i + 1 < len(body) else None next_tok = body[i + 1] if i + 1 < len(body) else None
if next_tok is not None and next_tok.lexeme == "!": if next_tok is not None and next_tok.lexeme == "!":
emitted.append(helper) emitted.append(helper)
emitted.append("swap")
emitted.append("!") emitted.append("!")
i += 2 i += 2
continue continue
@@ -3210,7 +3212,7 @@ def macro_struct_begin(ctx: MacroContext) -> Optional[List[Op]]:
generated, generated,
name_token, name_token,
f"{struct_name}.{field.name}!", f"{struct_name}.{field.name}!",
[offset_word, "+", "!"], ["swap", offset_word, "+", "swap", "!"],
) )
parser.tokens[parser.pos:parser.pos] = generated parser.tokens[parser.pos:parser.pos] = generated

15
nob.sl
View File

@@ -31,25 +31,20 @@ word sh
0 0
c! c!
mem
"/bin/sh" drop "/bin/sh" drop
0
mem +
! !
mem 8 +
"-c" drop "-c" drop
8
mem +
! !
mem 16 +
0 rpick 0 rpick
16
mem +
! !
mem 24 +
0 0
24
mem +
! !
mem 32 +
0 0
32
mem +
! !
syscall.fork syscall.fork

View File

@@ -11,8 +11,8 @@
# : argc ( -- n ) # : argc ( -- n )
:asm argc { :asm argc {
extern argc extern sys_argc
mov rax, [rel argc] mov rax, [rel sys_argc]
sub r12, 8 sub r12, 8
mov [r12], rax mov [r12], rax
ret ret
@@ -21,8 +21,8 @@
# : argv ( -- ptr ) # : argv ( -- ptr )
:asm argv { :asm argv {
extern argv extern sys_argv
mov rax, [rel argv] mov rax, [rel sys_argv]
sub r12, 8 sub r12, 8
mov [r12], rax mov [r12], rax
ret ret
@@ -31,9 +31,9 @@
# : argv@ ( n -- ptr ) # : argv@ ( n -- ptr )
:asm argv@ { :asm argv@ {
extern argv extern sys_argv
mov rbx, [r12] ; n mov rbx, [r12] ; n
mov rax, [rel argv] mov rax, [rel sys_argv]
mov rax, [rax + rbx*8] mov rax, [rax + rbx*8]
mov [r12], rax mov [r12], rax
ret ret
@@ -54,6 +54,7 @@
mov rax, [r12] ; get address from stack mov rax, [r12] ; get address from stack
add r12, 8 ; pop address add r12, 8 ; pop address
mov rbx, [r12] ; get byte value mov rbx, [r12] ; get byte value
add r12, 8
mov [rbx], al ; store byte at address mov [rbx], al ; store byte at address
ret ret
} }
@@ -310,11 +311,11 @@
# : ! ( x addr -- ) # : ! ( x addr -- )
:asm ! { :asm ! {
mov rax, [r12] ; get address mov rax, [r12] ; get value (TOS)
add r12, 8 ; pop address
mov rbx, [r12] ; get value
mov [rax], rbx ; store value at address
add r12, 8 ; pop value add r12, 8 ; pop value
mov rbx, [r12] ; get addr (NOS)
add r12, 8 ; pop addr
mov [rbx], rax ; store value at address
} }
; ;

View File

@@ -8,6 +8,7 @@ word alloc
-1 # fd -1 # fd
0 # offset 0 # offset
mmap mmap
swap drop
end end
word free word free
@@ -21,7 +22,6 @@ word memcpy #(dst_addr src_addr len -- dst_addr len)
dup c@ dup c@
3 pick swap 3 pick swap
c! c!
drop
swap swap
for for
1 + dup 1 + dup
@@ -33,10 +33,30 @@ word memcpy #(dst_addr src_addr len -- dst_addr len)
dup dup
rot rot
c! c!
drop
swap swap
end end
swap swap
nip nip
r> dup -rot - swap r> dup -rot - swap
end
word memset #( value len addr -- )
swap
0 swap for
-rot swap 2 pick + 2dup swap ! 1 + -rot swap
end
2drop drop
end
word memdump #( len addr -- addr )
for
dup c@ puti cr 1 +
end
end
word realloc #( addr old_len new_len -- new_addr )
2 pick swap alloc
rot rot swap
memcpy
swap -rot free
end end

View File

@@ -99,7 +99,7 @@ word tostr
dup dup
count_digits count_digits
2dup >r alloc 2dup >r alloc
nip swap rot swap swap rot swap
for for
dup 10 % swap 10 / dup 10 % swap 10 /
end end
@@ -114,7 +114,6 @@ word tostr
2 + pick 2 + pick
3 pick rot + 3 pick rot +
swap 48 + swap 1 - swap c! swap 48 + swap 1 - swap c!
drop
swap swap
1 + 1 +
swap swap

View File

@@ -3,7 +3,7 @@ import ../stdlib/io.sl
import ../stdlib/mem.sl import ../stdlib/mem.sl
word test-mem-alloc word test-mem-alloc
4096 alloc dup 1337 swap ! # allocate 4096 bytes, store 1337 at start 4096 alloc dup 1337 ! # allocate 4096 bytes, store 1337 at start
dup @ puti cr # print value at start dup @ puti cr # print value at start
4096 free # free the memory 4096 free # free the memory
end end
@@ -16,9 +16,9 @@ end
word main word main
32 alloc # allocate 32 bytes (enough for a Point struct) 32 alloc # allocate 32 bytes (enough for a Point struct)
dup dup
dup 111 swap Point.x! dup 111 Point.x! # store 111 at offset 0 (Point.x)
dup 222 swap Point.y! dup 222 Point.y! # store 222 at offset 8 (Point.y)
dup Point.x@ puti cr dup Point.x@ puti cr # print x
Point.y@ puti cr dup Point.y@ puti cr # print y
32 free # free the memory 32 free # free the memory
end end

View File

@@ -66,7 +66,7 @@ end
word test-store word test-store
mem-slot dup mem-slot dup
123 swap ! 123 !
@ puti cr @ puti cr
end end
@@ -80,7 +80,7 @@ word test-mmap
0 # offset 0 # offset
mmap mmap
dup dup
1337 swap ! 1337 !
dup dup
@ puti cr @ puti cr
4096 munmap drop 4096 munmap drop
@@ -132,10 +132,10 @@ end
word test-struct word test-struct
mem-slot mem-slot
dup 111 swap Point.x! dup 111 ! # Point.x = 111
dup 222 swap Point.y! dup 8 + 222 ! # Point.y = 222
dup Point.x@ puti cr dup @ puti cr # print Point.x
Point.y@ puti cr dup 8 + @ puti cr # print Point.y
Point.size puti cr Point.size puti cr
end end

View File

@@ -1,2 +1,9 @@
5 5
6 6
aaaaaaaaaa
111
222
111
222
333
444

View File

@@ -1,9 +1,39 @@
import ../stdlib/stdlib.sl import ../stdlib/stdlib.sl
import ../stdlib/io.sl
word main word main
mem 5 swap ! mem 5 !
mem 8 + 6 swap ! mem 8 + 6 !
mem @ puti cr mem @ puti cr
mem 8 + @ puti cr mem 8 + @ puti cr
10 alloc
dup
10 97 memset
10 2dup puts
free
# Test realloc: allocate 16 bytes, fill with data, then grow to 32 bytes
16 alloc
dup 111 ! # Store 111 at offset 0
dup 8 + 222 ! # Store 222 at offset 8
# Realloc to 32 bytes
16 32 realloc # ( addr old_len=16 new_len=32 ) -> ( new_addr )
# Verify old data is preserved
dup @ puti cr # Should print 111
dup 8 + @ puti cr # Should print 222
# Write new data to the expanded region
dup 16 + 333 ! # Store 333 at offset 16
dup 24 + 444 ! # Store 444 at offset 24
# Print all values to verify
dup @ puti cr # 111
dup 8 + @ puti cr # 222
dup 16 + @ puti cr # 333
dup 24 + @ puti cr # 444
32 free
end end