aboutsummaryrefslogtreecommitdiffstats
path: root/sys/decl.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-08-28 15:59:22 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-09-02 13:06:53 +0200
commita7206b24cac96c08aecf2f3b4cc3c2e555eec708 (patch)
tree80c678141148ce2eafaab5617f168bd840b8c8a6 /sys/decl.go
parentaa51461a34f998908d10f551615ad242bdff8fe9 (diff)
pkg/compiler: check and generate types
Move most of the logic from sysgen to pkg/compiler. Update #217
Diffstat (limited to 'sys/decl.go')
-rw-r--r--sys/decl.go106
1 files changed, 41 insertions, 65 deletions
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)
}