From a7206b24cac96c08aecf2f3b4cc3c2e555eec708 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 28 Aug 2017 15:59:22 +0200 Subject: pkg/compiler: check and generate types Move most of the logic from sysgen to pkg/compiler. Update #217 --- sys/decl.go | 106 +++++++++++++++++++++++------------------------------------- 1 file changed, 41 insertions(+), 65 deletions(-) (limited to 'sys/decl.go') diff --git a/sys/decl.go b/sys/decl.go index 7a7c95dbd..7a4fe3fff 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -11,10 +11,9 @@ const ptrSize = 8 type Call struct { ID int - NR int // kernel syscall number + NR uint64 // kernel syscall number Name string CallName string - Native bool // real of fake syscall Args []Type Ret Type } @@ -301,6 +300,9 @@ type ArrayType struct { } func (t *ArrayType) Varlen() bool { + if t.Type.Varlen() { + return true + } switch t.Kind { case ArrayRandLen: return true @@ -434,81 +436,45 @@ func (t *UnionType) Align() uint64 { var ( CallMap = make(map[string]*Call) structs map[string]Type - keyedStructs map[structKey]Type + keyedStructs map[StructKey]Type Resources map[string]*ResourceDesc ctors = make(map[string][]*Call) ) -type structKey struct { - name string - field string - dir Dir +type StructKey struct { + Name string + Dir Dir } -func getStruct(key structKey) Type { - if structs == nil { - structs = make(map[string]Type) - keyedStructs = make(map[structKey]Type) - for _, str := range structArray { - structs[str.Name()] = str - } - } - str := keyedStructs[key] - if str == nil { - proto := structs[key.name] - if proto == nil { - panic(fmt.Sprintf("missing struct prototype for %v", key.name)) - } - switch typed := proto.(type) { - case *StructType: - newStr := new(StructType) - *newStr = *typed - newStr.FldName = key.field - newStr.ArgDir = key.dir - str = newStr - case *UnionType: - newStr := new(UnionType) - *newStr = *typed - newStr.FldName = key.field - newStr.ArgDir = key.dir - str = newStr - default: - panic(fmt.Sprintf("unexpected type of struct prototype for %v: %+v", key.name, proto)) - } - keyedStructs[key] = str - } - return str +type StructFields struct { + Key StructKey + Fields []Type } func initStructFields() { - missed := 0 + keyedStructs := make(map[StructKey][]Type) for _, f := range structFields { - untyped := keyedStructs[f.key] - if untyped == nil { - missed++ - continue - } - switch str := untyped.(type) { - case *StructType: - str.Fields = f.fields - case *UnionType: - str.Options = f.fields - default: - panic(fmt.Sprintf("unexpected type of struct prototype for %v: %+v", f.key.name, untyped)) - } + keyedStructs[f.Key] = f.Fields } -} -func resource(name string) *ResourceDesc { - if Resources == nil { - // This is first called during init of sys package, so does not need to be thread-safe. - // resourceArray is in sys_GOARCH.go (generated by sysgen). - Resources = make(map[string]*ResourceDesc) - for _, res := range resourceArray { - Resources[res.Name] = res - } + for _, c := range Calls { + ForeachType(c, func(t Type) { + switch s := t.(type) { + case *StructType: + key := StructKey{s.TypeName, s.ArgDir} + if keyedStructs[key] == nil { + panic("no fields") + } + s.Fields = keyedStructs[key] + case *UnionType: + key := StructKey{s.TypeName, s.ArgDir} + if keyedStructs[key] == nil { + panic("no fields") + } + s.Options = keyedStructs[key] + } + }) } - return Resources[name] } // ResourceConstructors returns a list of calls that can create a resource of the given kind. @@ -517,7 +483,17 @@ func ResourceConstructors(name string) []*Call { } func initResources() { - resource("") // init resources, if it's not done yet + Resources = make(map[string]*ResourceDesc) + for _, res := range resourceArray { + Resources[res.Name] = res + } + for _, c := range Calls { + ForeachType(c, func(t Type) { + if r, ok := t.(*ResourceType); ok { + r.Desc = Resources[r.TypeName] + } + }) + } for _, res := range resourceArray { ctors[res.Name] = resourceCtors(res.Kind, false) } -- cgit mrf-deployment