diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-10-19 14:41:46 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-11-11 14:27:54 -0800 |
| commit | d3a93e8370682fa5231bc94faf11ed3681b2ac99 (patch) | |
| tree | a3f5827fe456cb7cc5f47e870c6069c0497ca3e5 /sysgen | |
| parent | 959ec07095ff4ec4423a1365e0f0f94844a77507 (diff) | |
sys: attach Dir to all types
Dir is a static info, so we don't need to compute, propagate and
attach it in prog whenever we generate/change programs.
Attach Dir to all types.
Diffstat (limited to 'sysgen')
| -rw-r--r-- | sysgen/sysgen.go | 89 |
1 files changed, 51 insertions, 38 deletions
diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index cdc79794c..c66f2af7a 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -162,7 +162,7 @@ func generate(arch string, desc *Description, consts map[string]uint64, out io.W fmt.Fprintf(out, "func() { Calls = append(Calls, &Call{Name: \"%v\", CallName: \"%v\"", s.Name, s.CallName) if len(s.Ret) != 0 { fmt.Fprintf(out, ", Ret: ") - generateArg("", "ret", s.Ret[0], s.Ret[1:], desc, consts, true, false, out) + generateArg("", "ret", s.Ret[0], "out", s.Ret[1:], desc, consts, true, false, out) } fmt.Fprintf(out, ", Args: []Type{") for i, a := range s.Args { @@ -170,7 +170,7 @@ func generate(arch string, desc *Description, consts map[string]uint64, out io.W fmt.Fprintf(out, ", ") } logf(5, " generate description for arg %v", i) - generateArg("", a[0], a[1], a[2:], desc, consts, true, false, out) + generateArg("", a[0], a[1], "in", a[2:], desc, consts, true, false, out) } if skipCurrentSyscall != "" { logf(0, "unsupported syscall: %v due to %v", s.Name, skipCurrentSyscall) @@ -230,7 +230,7 @@ func generateResources(desc *Description, consts map[string]uint64, out io.Write } } fmt.Fprintf(out, "\"%v\": &ResourceDesc{Name: \"%v\", Type: ", name, name) - generateArg("", "resource-type", underlying, nil, desc, consts, true, true, out) + generateArg("", "resource-type", underlying, "inout", nil, desc, consts, true, true, out) fmt.Fprintf(out, ", Kind: []string{") for i, k := range kind { if i != 0 { @@ -253,11 +253,21 @@ func generateResources(desc *Description, consts map[string]uint64, out io.Write fmt.Fprintf(out, "}\n") } -func generateStructEntry(str Struct, key string, name string, out io.Writer) { +type structKey struct { + name string + field string + dir string +} + +func generateStructEntry(str Struct, key structKey, out io.Writer) { typ := "StructType" if str.IsUnion { typ = "UnionType" } + name := key.field + if name == "" { + name = key.name + } packed := "" if str.Packed { packed = ", packed: true" @@ -270,11 +280,11 @@ func generateStructEntry(str Struct, key string, name string, out io.Writer) { if str.Align != 0 { align = fmt.Sprintf(", align: %v", str.Align) } - fmt.Fprintf(out, "\"%v\": &%v{TypeCommon: TypeCommon{TypeName: \"%v\", IsOptional: %v} %v %v %v},\n", - key, typ, name, false, packed, align, varlen) + fmt.Fprintf(out, "\"%v\": &%v{TypeCommon: TypeCommon{TypeName: \"%v\", ArgDir: %v, IsOptional: %v} %v %v %v},\n", + key, typ, name, fmtDir(key.dir), false, packed, align, varlen) } -func generateStructFields(str Struct, key string, desc *Description, consts map[string]uint64, out io.Writer) { +func generateStructFields(str Struct, key structKey, desc *Description, consts map[string]uint64, out io.Writer) { typ := "StructType" fields := "Fields" if str.IsUnion { @@ -284,7 +294,7 @@ func generateStructFields(str Struct, key string, desc *Description, consts map[ fmt.Fprintf(out, "{ s := Structs[\"%v\"].(*%v)\n", key, typ) for _, a := range str.Flds { fmt.Fprintf(out, "s.%v = append(s.%v, ", fields, fields) - generateArg(str.Name, a[0], a[1], a[2:], desc, consts, false, true, out) + generateArg(str.Name, a[0], a[1], key.dir, a[2:], desc, consts, false, true, out) fmt.Fprintf(out, ")\n") } fmt.Fprintf(out, "}\n") @@ -301,24 +311,23 @@ func generateStructs(desc *Description, consts map[string]uint64, out io.Writer) // for each field indexed by the name of the parent struct and the // field name. - structMap := make(map[string]Struct) + structMap := make(map[structKey]Struct) for _, str := range desc.Structs { - if _, ok := structMap[str.Name]; ok { - failf("two structs with the same name '%v'", str.Name) + for _, dir := range []string{"in", "out", "inout"} { + structMap[structKey{str.Name, "", dir}] = str } - structMap[str.Name] = str for _, a := range str.Flds { if innerStr, ok := desc.Structs[a[1]]; ok { - structMap[fmt.Sprintf("%v-%v", str.Name, a[0])] = innerStr + for _, dir := range []string{"in", "out", "inout"} { + structMap[structKey{a[1], a[0], dir}] = innerStr + } } } } fmt.Fprintf(out, "var Structs = map[string]Type{\n") for key, str := range structMap { - keyParts := strings.Split(key, "-") - name := keyParts[len(keyParts)-1] - generateStructEntry(str, key, name, out) + generateStructEntry(str, key, out) } fmt.Fprintf(out, "}\n") @@ -351,7 +360,7 @@ func parseRange(buffer string, consts map[string]uint64) (string, string) { } func generateArg( - parent, name, typ string, + parent, name, typ, dir string, a []string, desc *Description, consts map[string]uint64, @@ -369,7 +378,7 @@ func generateArg( } } common := func() string { - return fmt.Sprintf("TypeCommon: TypeCommon{TypeName: %v, IsOptional: %v}", name, opt) + return fmt.Sprintf("TypeCommon: TypeCommon{TypeName: %v, ArgDir: %v, IsOptional: %v}", name, fmtDir(dir), opt) } canBeArg := false switch typ { @@ -393,25 +402,28 @@ func generateArg( if want := 1; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - commonHdr := common() + ptrCommonHdr := common() + dir = a[0] opt = false - fmt.Fprintf(out, "&PtrType{%v, Dir: %v, Type: &BufferType{%v, Kind: BufferBlobRand}}", commonHdr, fmtDir(a[0]), common()) + fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferBlobRand}}", ptrCommonHdr, common()) case "string": canBeArg = true if want := 0; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - commonHdr := common() + ptrCommonHdr := common() + dir = "in" opt = false - fmt.Fprintf(out, "&PtrType{%v, Dir: %v, Type: &BufferType{%v, Kind: BufferString}}", commonHdr, fmtDir("in"), common()) + fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferString}}", ptrCommonHdr, common()) case "filesystem": canBeArg = true if want := 0; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - commonHdr := common() + ptrCommonHdr := common() + dir = "in" opt = false - fmt.Fprintf(out, "&PtrType{%v, Dir: %v, Type: &BufferType{%v, Kind: BufferFilesystem}}", commonHdr, fmtDir("in"), common()) + fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferFilesystem}}", ptrCommonHdr, common()) case "sockaddr": if want := 0; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) @@ -500,7 +512,10 @@ func generateArg( if want := 1; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - fmt.Fprintf(out, "&PtrType{%v, Dir: %v, Type: &StrConstType{%v, Val: \"%v\"}}", common(), fmtDir("in"), common(), a[0]+"\\x00") + ptrCommonHdr := common() + dir = "in" + opt = false + fmt.Fprintf(out, "&PtrType{%v, Type: &StrConstType{%v, Val: \"%v\"}}", ptrCommonHdr, common(), a[0]+"\\x00") case "int8", "int16", "int32", "int64", "intptr", "int16be", "int32be", "int64be", "intptrbe": canBeArg = true size, bigEndian := decodeIntType(typ) @@ -534,9 +549,10 @@ func generateArg( if want := 0; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - commonHdr := common() + ptrCommonHdr := common() + dir = "in" opt = false - fmt.Fprintf(out, "&PtrType{%v, Dir: DirIn, Type: &FilenameType{%v}}", commonHdr, common()) + fmt.Fprintf(out, "&PtrType{%v, Type: &FilenameType{%v}}", ptrCommonHdr, common()) case "array": if len(a) != 1 && len(a) != 2 { failf("wrong number of arguments for %v arg %v, want 1 or 2, got %v", typ, name, len(a)) @@ -545,14 +561,14 @@ func generateArg( if a[0] == "int8" { fmt.Fprintf(out, "&BufferType{%v, Kind: BufferBlobRand}", common()) } else { - fmt.Fprintf(out, "&ArrayType{%v, Type: %v, Kind: ArrayRandLen}", common(), generateType(a[0], desc, consts)) + fmt.Fprintf(out, "&ArrayType{%v, Type: %v, Kind: ArrayRandLen}", common(), generateType(a[0], dir, desc, consts)) } } else { begin, end := parseRange(a[1], consts) if a[0] == "int8" { fmt.Fprintf(out, "&BufferType{%v, Kind: BufferBlobRange, RangeBegin: %v, RangeEnd: %v}", common(), begin, end) } else { - fmt.Fprintf(out, "&ArrayType{%v, Type: %v, Kind: ArrayRangeLen, RangeBegin: %v, RangeEnd: %v}", common(), generateType(a[0], desc, consts), begin, end) + fmt.Fprintf(out, "&ArrayType{%v, Type: %v, Kind: ArrayRangeLen, RangeBegin: %v, RangeEnd: %v}", common(), generateType(a[0], dir, desc, consts), begin, end) } } case "ptr": @@ -560,11 +576,12 @@ func generateArg( if want := 2; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } - fmt.Fprintf(out, "&PtrType{%v, Type: %v, Dir: %v}", common(), generateType(a[1], desc, consts), fmtDir(a[0])) + dir = "in" + fmt.Fprintf(out, "&PtrType{%v, Type: %v}", common(), generateType(a[1], a[0], desc, consts)) default: if strings.HasPrefix(typ, "unnamed") { if inner, ok := desc.Unnamed[typ]; ok { - generateArg("", "", inner[0], inner[1:], desc, consts, false, isField, out) + generateArg("", "", inner[0], dir, inner[1:], desc, consts, false, isField, out) } else { failf("unknown unnamed type '%v'", typ) } @@ -572,11 +589,7 @@ func generateArg( if len(a) != 0 { failf("struct '%v' has args", typ) } - if parent == "" { - fmt.Fprintf(out, "Structs[\"%v\"]", typ) - } else { - fmt.Fprintf(out, "Structs[\"%v-%v\"]", parent, origName) - } + fmt.Fprintf(out, "Structs[\"%v\"]", structKey{typ, origName, dir}) } else if _, ok := desc.Resources[typ]; ok { if len(a) != 0 { failf("resource '%v' has args", typ) @@ -592,9 +605,9 @@ func generateArg( } } -func generateType(typ string, desc *Description, consts map[string]uint64) string { +func generateType(typ, dir string, desc *Description, consts map[string]uint64) string { buf := new(bytes.Buffer) - generateArg("", "", typ, nil, desc, consts, false, true, buf) + generateArg("", "", typ, dir, nil, desc, consts, false, true, buf) return buf.String() } |
