calculate needed stack space with a disgusting hack
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
func concat[a: i64, b: i64] : i64
|
func concat[a: i64, b: i64] : i64
|
||||||
ab_str := _stackalloc(50)
|
ab_str := _stackalloc(50) as str
|
||||||
io.snprintf(ab_str, 50, "%d%d", a, b)
|
io.snprintf(ab_str, 50, "%d%d", a, b)
|
||||||
return str.parse_i64(ab_str)
|
return str.parse_i64(ab_str)
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ struct Var {
|
|||||||
pub var_type: String,
|
pub var_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
const STACK_SIZE: usize = 256; // TODO: eww
|
|
||||||
|
|
||||||
pub struct Env {
|
pub struct Env {
|
||||||
scopes: Vec<HashMap<String, Var>>,
|
scopes: Vec<HashMap<String, Var>>,
|
||||||
next_offset: usize,
|
next_offset: usize,
|
||||||
@@ -173,9 +171,8 @@ _start:
|
|||||||
mov [rax], rdx
|
mov [rax], rdx
|
||||||
; align stack
|
; align stack
|
||||||
and rsp, -16
|
and rsp, -16
|
||||||
; main()
|
; exit(main())
|
||||||
call main
|
call main
|
||||||
; exit
|
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
mov rax, 60
|
mov rax, 60
|
||||||
syscall
|
syscall
|
||||||
@@ -354,8 +351,9 @@ _builtin_environ:
|
|||||||
emit!(&mut self.output, "{}:", name.lexeme);
|
emit!(&mut self.output, "{}:", name.lexeme);
|
||||||
emit!(&mut self.output, " push rbp");
|
emit!(&mut self.output, " push rbp");
|
||||||
emit!(&mut self.output, " mov rbp, rsp");
|
emit!(&mut self.output, " mov rbp, rsp");
|
||||||
let stack_size = (STACK_SIZE + 15) & !15;
|
|
||||||
emit!(&mut self.output, " sub rsp, {}", stack_size);
|
let prologue_offset = self.output.len();
|
||||||
|
emit!(&mut self.output, " sub rsp, {:<10}", 0);
|
||||||
|
|
||||||
match params {
|
match params {
|
||||||
Params::Normal(params) => {
|
Params::Normal(params) => {
|
||||||
@@ -399,6 +397,11 @@ _builtin_environ:
|
|||||||
emit!(&mut self.output, " pop rbp");
|
emit!(&mut self.output, " pop rbp");
|
||||||
emit!(&mut self.output, " ret");
|
emit!(&mut self.output, " ret");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// patch the stack size after we know how much we actually need
|
||||||
|
let patch = format!(" sub rsp, {:<10}", (env.next_offset + 15) & !15);
|
||||||
|
self.output
|
||||||
|
.replace_range(prologue_offset..prologue_offset + patch.len(), &patch);
|
||||||
}
|
}
|
||||||
Stmt::Return { keyword: _, exprs } => {
|
Stmt::Return { keyword: _, exprs } => {
|
||||||
if exprs.len() == 2 {
|
if exprs.len() == 2 {
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
|
|||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
|
|
||||||
if args.include_stdlib {
|
if args.include_stdlib {
|
||||||
parse_std_file!(statements, "std/syscalls.zr");
|
|
||||||
parse_std_file!(statements, "std/std.zr");
|
parse_std_file!(statements, "std/std.zr");
|
||||||
parse_std_file!(statements, "std/net.zr");
|
parse_std_file!(statements, "std/net.zr");
|
||||||
|
parse_std_file!(statements, "std/linux_constants.zr");
|
||||||
}
|
}
|
||||||
|
|
||||||
let tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source);
|
let tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source);
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
// https://github.com/torvalds/linux/blob/19272b37aa4f83ca52bdf9c16d5d81bdd1354494/arch/x86/entry/syscalls/syscall_64.tbl
|
const S_IFDIR = 0o040000
|
||||||
|
const S_IFMT = 0o170000
|
||||||
|
const PROT_READ = 1
|
||||||
|
const PROT_WRITE = 2
|
||||||
|
const MAP_PRIVATE = 2
|
||||||
|
const MAP_ANONYMOUS = 32
|
||||||
|
const O_RDONLY = 0
|
||||||
|
const O_WRONLY = 1
|
||||||
|
const O_CREAT = 64
|
||||||
|
const O_TRUNC = 512
|
||||||
|
const SEEK_SET = 0
|
||||||
|
const SEEK_END = 2
|
||||||
|
|
||||||
const SYS_read = 0
|
const SYS_read = 0
|
||||||
const SYS_write = 1
|
const SYS_write = 1
|
||||||
const SYS_open = 2
|
const SYS_open = 2
|
||||||
@@ -1,16 +1,3 @@
|
|||||||
const S_IFDIR = 0o040000
|
|
||||||
const S_IFMT = 0o170000
|
|
||||||
const PROT_READ = 1
|
|
||||||
const PROT_WRITE = 2
|
|
||||||
const MAP_PRIVATE = 2
|
|
||||||
const MAP_ANONYMOUS = 32
|
|
||||||
const O_RDONLY = 0
|
|
||||||
const O_WRONLY = 1
|
|
||||||
const O_CREAT = 64
|
|
||||||
const O_TRUNC = 512
|
|
||||||
const SEEK_SET = 0
|
|
||||||
const SEEK_END = 2
|
|
||||||
|
|
||||||
func panic[msg: str] : void
|
func panic[msg: str] : void
|
||||||
io.print("PANIC: ")
|
io.print("PANIC: ")
|
||||||
io.println(msg)
|
io.println(msg)
|
||||||
@@ -26,7 +13,7 @@ struct mem.Block
|
|||||||
next: mem.Block
|
next: mem.Block
|
||||||
prev: mem.Block
|
prev: mem.Block
|
||||||
|
|
||||||
func mem._align[x: i64] : i64
|
func mem.align[x: i64] : i64
|
||||||
return (x + 7) & -8
|
return (x + 7) & -8
|
||||||
|
|
||||||
func mem._split_block[blk: mem.Block, needed: i64] : void
|
func mem._split_block[blk: mem.Block, needed: i64] : void
|
||||||
@@ -70,7 +57,7 @@ func mem.alloc[size: i64] : ptr
|
|||||||
if size <= 0
|
if size <= 0
|
||||||
panic("mem.alloc: called with nonpositive size")
|
panic("mem.alloc: called with nonpositive size")
|
||||||
|
|
||||||
size = mem._align(size)
|
size = mem.align(size)
|
||||||
|
|
||||||
cur := mem.read64(_builtin_heap_head()) as mem.Block
|
cur := mem.read64(_builtin_heap_head()) as mem.Block
|
||||||
while cur as ptr
|
while cur as ptr
|
||||||
@@ -145,7 +132,7 @@ func mem.realloc[x: ptr, new_size: i64] : ptr
|
|||||||
mem.free(x)
|
mem.free(x)
|
||||||
return 0 as ptr
|
return 0 as ptr
|
||||||
|
|
||||||
new_size = mem._align(new_size)
|
new_size = mem.align(new_size)
|
||||||
|
|
||||||
blk := (x - MEM_BLOCK_SIZE) as mem.Block
|
blk := (x - MEM_BLOCK_SIZE) as mem.Block
|
||||||
if blk->size >= new_size
|
if blk->size >= new_size
|
||||||
@@ -1081,7 +1068,7 @@ func os.run_shell_command[command: str] : i64, bool
|
|||||||
if pid == 0
|
if pid == 0
|
||||||
argv := ["sh", "-c", command, 0] // gets freed after child process exits
|
argv := ["sh", "-c", command, 0] // gets freed after child process exits
|
||||||
_builtin_syscall(SYS_execve, "/bin/sh", argv->data, _builtin_environ())
|
_builtin_syscall(SYS_execve, "/bin/sh", argv->data, _builtin_environ())
|
||||||
_builtin_syscall(SYS_exit, 1)
|
os.exit(1)
|
||||||
else
|
else
|
||||||
status := 0
|
status := 0
|
||||||
wp := _builtin_syscall(SYS_wait4, pid, ^status, 0, 0)
|
wp := _builtin_syscall(SYS_wait4, pid, ^status, 0, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user