Skip to content

Commit

Permalink
gensyscall: replace syscall numbers with func pointers
Browse files Browse the repository at this point in the history
Instead of numbers and big switch statement, store functions pointers
directly on the syscall struct. The big switch statement was impossible
to extend outside of gensyscall. These new function pairs do not have
this problem.
  • Loading branch information
jellevandenhooff committed Nov 24, 2024
1 parent 7028ed1 commit 49ded66
Show file tree
Hide file tree
Showing 5 changed files with 984 additions and 1,116 deletions.
33 changes: 11 additions & 22 deletions internal/simulation/gensyscall/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (o *outputSorter) append(key, value string) {
}

func (o *outputSorter) output() string {
slices.SortFunc(o.outputs, func(a, b outputWithSortKey) int {
slices.SortStableFunc(o.outputs, func(a, b outputWithSortKey) int {
return cmp.Compare(a.sortKey, b.sortKey)
})
var out strings.Builder
Expand Down Expand Up @@ -477,7 +477,6 @@ func writeSyscalls(outputPath string, syscalls []syscallInfo, isMachine bool) {
}

callers := newOutputSorter()
dispatches := newOutputSorter()
checks := newOutputSorter()
ifaces := newOutputSorter()
for _, info := range syscalls {
Expand Down Expand Up @@ -569,14 +568,6 @@ func writeSyscalls(outputPath string, syscalls []syscallInfo, isMachine bool) {
parseDispatchText += "\t\tsyscall.Complete()\n"
}

dispatchText := fmt.Sprintf("\tcase %s:\n", sysVal) +
"\t\t// called by (for find references):\n" +
fmt.Sprintf("\t\t_ = %s\n", "Syscall"+ifaceName) +
prepareDispatch +
fmt.Sprintf("\t\t%sos.%s(%s)\n", dispatchRet, ifaceName, strings.Join(dispatchArgs, ", ")) +
parseDispatchText
dispatches.append(sysName, dispatchText)

if info.sysVal == 0 {
checkText := fmt.Sprintf("\tcase %s:\n", sysVal) +
"\t\treturn true\n"
Expand All @@ -588,18 +579,24 @@ func writeSyscalls(outputPath string, syscalls []syscallInfo, isMachine bool) {

callerText := "//go:norace\n" +
fmt.Sprintf("func %s(%s)%s {\n", "Syscall"+ifaceName, strings.Join(callerArgs, ", "), callerRet) +
"\t// invokes (for go to definition):\n" +
fmt.Sprintf("\t_ = (*%s).%s\n", osTypeName, ifaceName) +
"\tsyscall := syscallabi.GetGoroutineLocalSyscall()\n" +
fmt.Sprintf("\tsyscall.Trampoline = trampoline%s\n", ifaceName) +
fmt.Sprintf("\tsyscall.OS = %s\n", osImplName) +
fmt.Sprintf("\tsyscall.Trap = %s\n", sysVal) +
prepareCaller +
fmt.Sprintf("\t%s.dispatchSyscall(syscall)\n", osImplName) +
parseCallerText +
cleanupCallerText +
"\treturn\n" +
"}\n\n"
callers.append(sysName, callerText)

dispatchText := "//go:norace\n" +
fmt.Sprintf("func trampoline%s(syscall *syscallabi.Syscall) {\n", ifaceName) +
prepareDispatch +
fmt.Sprintf("\t\t%ssyscall.OS.(*%s).%s(%s)\n", dispatchRet, osTypeName, ifaceName, strings.Join(dispatchArgs, ", ")) +
parseDispatchText +
"}\n\n"
callers.append(sysName, dispatchText)
}

output := ""
Expand Down Expand Up @@ -647,15 +644,7 @@ func (os *%s) dispatchSyscall(s *syscallabi.Syscall) {
os.dispatcher.Dispatch(s)
}
//go:norace
func (os *%s) HandleSyscall(syscall *syscallabi.Syscall) {
switch (syscall.Trap) {
`, osIfaceName, osTypeName, osTypeName, osTypeName) + dispatches.output() + ` default:
panic("bad")
}
}
` + callers.output()
`, osIfaceName, osTypeName, osTypeName) + callers.output()

if !isMachine {
output += `
Expand Down
Loading

0 comments on commit 49ded66

Please sign in to comment.