Added build result struct

This commit is contained in:
2024-06-26 20:16:18 +02:00
parent 3268f7a7ee
commit 988a538661
7 changed files with 61 additions and 54 deletions

42
src/build/Result.go Normal file
View File

@ -0,0 +1,42 @@
package build
import (
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/os/linux"
)
// Result contains all the compiled functions in a build.
type Result struct {
Functions map[string]*Function
instructionCount int
}
// Finalize generates the final machine code.
func (r Result) Finalize() ([]byte, []byte) {
// This will be the entry point of the executable.
// The only job of the entry function is to call `main` and exit cleanly.
// The reason we call `main` instead of using `main` itself is to place
// a return address on the stack, which allows return statements in `main`.
final := asm.Assembler{
Instructions: make([]asm.Instruction, 0, r.instructionCount+4),
}
final.Call("main")
final.RegisterNumber(asm.MOVE, x64.SyscallRegisters[0], linux.Exit)
final.RegisterNumber(asm.MOVE, x64.SyscallRegisters[1], 0)
final.Syscall()
// Place the `main` function immediately after the entry point.
main := r.Functions["main"]
delete(r.Functions, "main")
final.Merge(&main.Assembler)
// Merge all the remaining functions.
for _, f := range r.Functions {
final.Merge(&f.Assembler)
}
code, data := final.Finalize()
return code, data
}