1
0
mirror of https://github.com/fumiama/gozel.git synced 2026-06-23 12:00:31 +08:00

feat(gen): impl. all specs except union

This commit is contained in:
源文雨
2026-03-24 00:49:26 +08:00
parent d42d758aeb
commit 1111b0ecc1
159 changed files with 9994 additions and 423 deletions

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"os"
"path"
"strings"
"unicode"
)
@@ -42,42 +41,52 @@ var (
"int": "int32",
"unsigned int": "uint32",
"float": "float32",
"double": "float64",
"float": "float32",
"double": "float64",
"float*": "*float32",
"double*": "*float64",
}
unsafeExcludeRegions = map[string]struct{}{
"bfloat16conversions": {},
"globaloffset": {},
"linkonceodr": {},
"subgroups": {},
"core_bfloat16conversions": {},
"core_globaloffset": {},
"core_linkonceodr": {},
"core_subgroups": {},
}
zecallExcludeRegions = map[string]struct{}{
"bandwidth": {},
"bfloat16conversions": {},
"CacheLineSize": {},
"callbacks": {},
"common": {},
"counterbasedeventpool": {},
"deviceipversion": {},
"deviceLUID": {},
"deviceusablememproperties": {},
"driverDDIHandles": {},
"EUCount": {},
"externalMemMap": {},
"floatAtomics": {},
"imageFormatSupport": {},
"imageviewplanar": {},
"kernelMaxGroupSizeProperties": {},
"linkonceodr": {},
"memoryCompressionHints": {},
"memoryProperties": {},
"powersavinghint": {},
"program": {},
"raytracing": {},
"relaxedAllocLimits": {},
"SRGB": {},
"subAllocationsProperties": {},
"subgroups": {},
"core_bandwidth": {},
"core_bfloat16conversions": {},
"core_CacheLineSize": {},
"core_callbacks": {},
"core_common": {},
"core_counterbasedeventpool": {},
"core_deviceipversion": {},
"core_deviceLUID": {},
"core_deviceusablememproperties": {},
"core_driverDDIHandles": {},
"core_EUCount": {},
"core_externalMemMap": {},
"core_floatAtomics": {},
"core_imageFormatSupport": {},
"core_imageviewplanar": {},
"core_kernelMaxGroupSizeProperties": {},
"core_linkonceodr": {},
"core_memoryCompressionHints": {},
"core_memoryProperties": {},
"core_powersavinghint": {},
"core_program": {},
"core_raytracing": {},
"core_relaxedAllocLimits": {},
"core_SRGB": {},
"core_subAllocationsProperties": {},
"core_subgroups": {},
"sysm_common": {},
"sysm_eccState": {},
"sysm_memoryBwCounterValidBits": {},
"sysm_memPageOfflineState": {},
"sysm_powerDomainProperties": {},
"tols_common": {},
}
)
@@ -95,18 +104,8 @@ func infh(name string) string {
func scanHeader(name string, scan *bufio.Scanner) {
ln := 0
var regionfile *os.File
symtab := symbolTable{
"ZE_APICALL": &symbol{symbolTypeConst, symbolSubTypeDefine, "ZE_APICALL", []string{""}},
"ZE_APIEXPORT": &symbol{symbolTypeConst, symbolSubTypeDefine, "ZE_APIEXPORT", []string{""}},
"ZE_DLLEXPORT": &symbol{symbolTypeConst, symbolSubTypeDefine, "ZE_DLLEXPORT", []string{""}},
}
fileheadersb := strings.Builder{}
region := ""
_ = os.RemoveAll(name)
err := os.MkdirAll(name, 0755)
if err != nil {
panic(fmt.Sprintf("%s L%d: cannot create region folder %s, err: %v", name, ln, region, err))
}
for scan.Scan() {
ln++
t := scan.Text()
@@ -122,24 +121,23 @@ func scanHeader(name string, scan *bufio.Scanner) {
panic(fmt.Sprintf("%s L%d: unexpected empty region", name, ln))
}
fmt.Println(infh(name), "scanning region", region)
f, err := os.Create(path.Join(name, region+".go"))
k := fmt.Sprint(name, "_", region)
f, err := os.Create(fmt.Sprint(k, ".go"))
if err != nil {
panic(fmt.Sprintf("%s L%d: cannot create region %s, err: %v", name, ln, region, err))
}
f.WriteString("// Code generated by cmd/gen. DO NOT EDIT.\n\n")
f.WriteString(fileheadersb.String())
f.WriteString("\n")
f.WriteString("package ")
f.WriteString(name)
f.WriteString("\n\n")
f.WriteString("package gozel\n\n")
noimport := true
sb := strings.Builder{}
sb.WriteString("import (")
if _, ok := unsafeExcludeRegions[region]; !ok {
if _, ok := unsafeExcludeRegions[k]; !ok {
sb.WriteString("\n\t\"unsafe\"\n")
noimport = false
}
if _, ok := zecallExcludeRegions[region]; !ok {
if _, ok := zecallExcludeRegions[k]; !ok {
sb.WriteString("\n\t\"github.com/fumiama/gozel/internal/zecall\"\n")
noimport = false
}
@@ -151,7 +149,7 @@ func scanHeader(name string, scan *bufio.Scanner) {
// block barrier
case strings.HasPrefix(t, "///////////////////////////////////////////////////////////////////////////////"):
fmt.Println(" [scan] enter", region, "block")
ln = scanBlocks(name, scan, regionfile, ln, symtab)
ln = scanBlocks(name, scan, regionfile, ln)
fmt.Println(" [scan] leave", region, "block")
// pragma end
case strings.HasPrefix(t, "#pragma endregion"):
@@ -170,7 +168,7 @@ func scanHeader(name string, scan *bufio.Scanner) {
}
func checkSymbolName(
symtab symbolTable, ln int, name, sname, goname string,
ln int, name, sname, goname string,
sb *strings.Builder, f *os.File, eq func() *symbol) bool {
if _, ok := symtab[sname]; ok {
panic(fmt.Sprintf("%s L%d: func #define %s has been defined", name, ln, sname))
@@ -195,7 +193,7 @@ func checkSymbolName(
func scanBlocks(
name string, scan *bufio.Scanner, f *os.File,
ln int, symtab symbolTable,
ln int,
) int {
sb := strings.Builder{}
ppskip2nextblk := false
@@ -253,7 +251,7 @@ func scanBlocks(
if !strings.Contains(argn, "(") { // is const define
sname := strings.TrimSpace(argn)
val := symtab.apply(strings.TrimSpace(argv))
checkSymbolName(symtab, ln, name, sname, sname, &sb, f, func() *symbol {
checkSymbolName(ln, name, sname, sname, &sb, f, func() *symbol {
return newSymbolConst(sname, val, symbolSubTypeDefine)
})
f.WriteString("const ")
@@ -274,7 +272,7 @@ func scanBlocks(
sname = strings.TrimSpace(sname)
args = strings.TrimSpace(args)
eval := strings.TrimSpace(argseval[n+1:])
checkSymbolName(symtab, ln, name, sname, sname, &sb, f, func() *symbol {
checkSymbolName(ln, name, sname, sname, &sb, f, func() *symbol {
return newSymbolFunc(sname, args, eval, symbolSubTypeDefine)
})
f.WriteString("func ")
@@ -287,12 +285,45 @@ func scanBlocks(
f.WriteString(eval)
f.WriteString("\n}\n\n")
case strings.HasPrefix(t, "typedef "):
ln = scanTypedef(name, scan, f, ln, symtab, t, &sb)
ln = scanTypedef(name, scan, f, ln, t, &sb)
case strings.HasPrefix(t, "ZE_APIEXPORT "):
if !strings.HasSuffix(t, " ZE_APICALL") {
panic(fmt.Sprintf("%s L%d: unexpected func line %s", name, ln, t))
}
ln = scanFunc(name, scan, f, ln, symtab, t, &sb)
ln = scanFunc(name, scan, f, ln, t, &sb)
case strings.HasPrefix(t, "static const ") && strings.HasSuffix(t, "= {"):
t = strings.TrimSpace(t[13 : len(t)-3])
i := strings.LastIndex(t, " ")
if i <= 0 {
panic(fmt.Sprintf("%s L%d: unexpected short var %s", name, ln, t))
}
typ := symtab.apply(strings.TrimSpace(t[:i]))
rnam := []rune(strings.TrimSpace(t[i+1:]))
rnam[0] = unicode.ToUpper(rnam[0])
nam := string(rnam)
f.WriteString(strings.Replace(sb.String(), "/ @brief", " "+nam, 1))
sb.Reset()
f.WriteString("var ")
f.WriteString(nam)
f.WriteString(" = ")
f.WriteString(typ)
f.WriteString("{")
for {
f.WriteString("\n")
s, isfin := scanln(name, scan, &ln)
if isfin {
break
}
s = strings.TrimSpace(s)
f.WriteString("\t")
if strings.HasPrefix(s, "0,") && strings.Contains(s, "///< p") {
f.WriteString("nil,")
f.WriteString(s[2:])
} else {
f.WriteString(s)
}
}
f.WriteString("}\n\n")
default:
panic(fmt.Sprintf("%s L%d: unexpected line %s", name, ln, t))
}
@@ -302,7 +333,7 @@ func scanBlocks(
func scanTypedef(
name string, scan *bufio.Scanner, f *os.File,
ln int, symtab symbolTable, firstln string, sb *strings.Builder,
ln int, firstln string, sb *strings.Builder,
) int {
s, newln := get1sentence(firstln, scan, ln)
if newln < 0 {
@@ -326,7 +357,7 @@ func scanTypedef(
}
goname := us2camel(fnname)
fnname += "_t"
checkSymbolName(symtab, ln, name, fnname, goname, sb, f, func() *symbol {
checkSymbolName(ln, name, fnname, goname, sb, f, func() *symbol {
return newSymbolConst(fnname, goname, symbolSubTypeFuncPtr)
})
f.WriteString("// gozel warn: please use C function pointer loaded from C library!\n")
@@ -510,7 +541,7 @@ func scanTypedef(
}
sname := strings.TrimSuffix(strings.TrimSpace(lines[0][1:]), ";")
val := us2camel(strings.TrimSuffix(sname, "_t"))
checkSymbolName(symtab, ln, name, sname, val, sb, f, func() *symbol {
checkSymbolName(ln, name, sname, val, sb, f, func() *symbol {
return newSymbolConst(sname, val, symbolSubTypeLargeStruct)
})
f.WriteString("type ")
@@ -563,7 +594,7 @@ func scanTypedef(
}
sname := strings.TrimSuffix(strings.TrimSpace(lines[0][1:]), ";")
val := us2camel(strings.TrimSuffix(sname, "_t"))
redirect := checkSymbolName(symtab, ln, name, sname, val, sb, f, func() *symbol {
redirect := checkSymbolName(ln, name, sname, val, sb, f, func() *symbol {
return newSymbolConst(sname, val, symbolSubTypeEnum)
})
replaces := ""
@@ -611,7 +642,7 @@ func scanTypedef(
sname := strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(typs[1]), ";"))
val := us2camel(strings.TrimSuffix(sname, "_t"))
origtyp := strings.TrimSuffix(symtab.apply(strings.TrimSpace(typs[0])), "_t")
checkSymbolName(symtab, ln, name, sname, val, sb, f, func() *symbol {
checkSymbolName(ln, name, sname, val, sb, f, func() *symbol {
return newSymbolConst(sname, val, symbolSubTypeEmptyStruct)
})
f.WriteString("type ")
@@ -624,11 +655,11 @@ func scanTypedef(
func scanFunc(
name string, scan *bufio.Scanner, f *os.File,
ln int, symtab symbolTable, firstln string, sb *strings.Builder,
ln int, firstln string, sb *strings.Builder,
) int {
//TODO: register func
rettyp := strings.TrimSpace(firstln[13 : len(firstln)-11])
rettyp = symtab.apply(strings.TrimSpace(rettyp))
rettyp = strings.TrimSuffix(symtab.apply(strings.TrimSpace(rettyp)), "_t")
fnname, isfin := scanln(name, scan, &ln)
if isfin {
panic(fmt.Sprintf("%s L%d: unexpected early end func name line %s", name, ln, fnname))
@@ -661,6 +692,9 @@ func scanFunc(
f.WriteString(argln[4:])
continue
}
if argln == "void" {
continue
}
argtypnam, argcomment, ok := strings.Cut(argln, "//")
if !ok {
panic(fmt.Sprintf("%s L%d: unexpected non-comment func arg line %s", name, ln, argln))
@@ -675,13 +709,17 @@ func scanFunc(
argsb.WriteString(", uintptr(")
argtyp := strings.TrimSpace(strings.ReplaceAll(argtypnam[:i], "const ", ""))
isp := strings.HasSuffix(argtyp, "*") // is pointer
pmark := "*"
if strings.HasSuffix(argtyp, "**") { // is pointer's pointer
pmark = "**"
}
convtyp, ok := typemap[argtyp]
if ok {
argtyp = convtyp
}
if isp {
if !ok {
argtyp = "*" + argtyp[:len(argtyp)-1]
argtyp = pmark + argtyp[:len(argtyp)-len(pmark)]
}
argsb.WriteString("unsafe.Pointer(")
} else {
@@ -689,7 +727,7 @@ func scanFunc(
if ok && sym.sstype == symbolSubTypeLargeStruct &&
!strings.HasPrefix(argnam, "p") {
isp = true
argtyp = "*" + argtyp
argtyp = pmark + argtyp
argcomment += " (gozel hack: converted to a hidden pointer from a struct value)"
argsb.WriteString("unsafe.Pointer(")
}
@@ -716,5 +754,6 @@ func scanFunc(
f.WriteString("\"")
f.WriteString(argsb.String())
f.WriteString(")\n}\n\n")
addAPI(origfnname)
return ln
}