Implemented parameter passing for function pointers
This commit is contained in:
parent
751614e7c0
commit
df6f7d5a57
21
src/core/AfterCall.go
Normal file
21
src/core/AfterCall.go
Normal file
@ -0,0 +1,21 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
"git.urbach.dev/cli/q/src/cpu"
|
||||
)
|
||||
|
||||
// AfterCall pops used register values back from the stack.
|
||||
func (f *Function) AfterCall(registers []cpu.Register) {
|
||||
for _, register := range slices.Backward(f.CPU.General) {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.POP, register)
|
||||
}
|
||||
}
|
||||
|
||||
for _, register := range registers {
|
||||
f.FreeRegister(register)
|
||||
}
|
||||
}
|
18
src/core/BeforeCall.go
Normal file
18
src/core/BeforeCall.go
Normal file
@ -0,0 +1,18 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
)
|
||||
|
||||
// BeforeCall pushes used registers to the stack.
|
||||
func (f *Function) BeforeCall() {
|
||||
for _, register := range f.CPU.Output {
|
||||
f.SaveRegister(register)
|
||||
}
|
||||
|
||||
for _, register := range f.CPU.General {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.PUSH, register)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
"git.urbach.dev/cli/q/src/cpu"
|
||||
)
|
||||
|
||||
// CallSafe pushes used registers to the stack, executes the call and restores the original register value.
|
||||
func (f *Function) CallSafe(fn *Function, registers []cpu.Register) {
|
||||
for _, register := range f.CPU.Output {
|
||||
f.SaveRegister(register)
|
||||
}
|
||||
|
||||
for _, register := range f.CPU.General {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.PUSH, register)
|
||||
}
|
||||
}
|
||||
|
||||
f.Label(asm.CALL, fn.UniqueName)
|
||||
|
||||
for _, register := range slices.Backward(f.CPU.General) {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.POP, register)
|
||||
}
|
||||
}
|
||||
|
||||
for _, register := range registers {
|
||||
f.FreeRegister(register)
|
||||
}
|
||||
}
|
@ -59,14 +59,32 @@ func (f *Function) CompileCall(root *expression.Expression) ([]types.Type, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.CallSafe(fn, registers)
|
||||
f.BeforeCall()
|
||||
f.Label(asm.CALL, value.Label)
|
||||
f.AfterCall(registers)
|
||||
return fn.OutputTypes, nil
|
||||
|
||||
case *eval.Register:
|
||||
err := f.ExpressionsToRegisters(parameters, registers, nil, true)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.BeforeCall()
|
||||
f.Register(asm.CALL, value.Register)
|
||||
f.AfterCall(registers)
|
||||
|
||||
case *eval.Memory:
|
||||
err := f.ExpressionsToRegisters(parameters, registers, nil, true)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.BeforeCall()
|
||||
f.Memory(asm.CALL, value.Memory)
|
||||
f.AfterCall(registers)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
@ -23,7 +23,9 @@ func (f *Function) CompileDelete(root *expression.Expression) error {
|
||||
f.RegisterRegister(asm.MOVE, f.CPU.Input[0], variable.Value.Register)
|
||||
f.RegisterNumber(asm.MOVE, f.CPU.Input[1], variable.Value.Typ.(*types.Pointer).To.Size())
|
||||
free := f.All.Functions["mem.free"]
|
||||
f.CallSafe(free, f.CPU.Input[:2])
|
||||
f.BeforeCall()
|
||||
f.Label(asm.CALL, "mem.free")
|
||||
f.AfterCall(f.CPU.Input[:2])
|
||||
f.Dependencies = append(f.Dependencies, free)
|
||||
return nil
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ func (f *Function) CompileNew(root *expression.Expression) (types.Type, error) {
|
||||
f.SaveRegister(f.CPU.Input[0])
|
||||
f.RegisterNumber(asm.MOVE, f.CPU.Input[0], typ.Size())
|
||||
alloc := f.All.Functions["mem.alloc"]
|
||||
f.CallSafe(alloc, f.CPU.Input[:1])
|
||||
f.BeforeCall()
|
||||
f.Label(asm.CALL, "mem.alloc")
|
||||
f.AfterCall(f.CPU.Input[:1])
|
||||
f.Dependencies = append(f.Dependencies, alloc)
|
||||
return &types.Pointer{To: typ}, nil
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ struct Struct {
|
||||
main() {
|
||||
s := new(Struct)
|
||||
s.func = f
|
||||
s.func()
|
||||
s.func(0)
|
||||
sys.exit(1)
|
||||
}
|
||||
|
||||
f() {
|
||||
sys.exit(0)
|
||||
f(code int) {
|
||||
sys.exit(code)
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
import core
|
||||
import sys
|
||||
|
||||
main() {
|
||||
func := f
|
||||
func()
|
||||
func(0)
|
||||
sys.exit(1)
|
||||
}
|
||||
|
||||
f() {
|
||||
exit := core.exit
|
||||
exit()
|
||||
f(code int) {
|
||||
exit := sys.exit
|
||||
exit(code)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user