Added build result struct
This commit is contained in:
42
src/build/Result.go
Normal file
42
src/build/Result.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user