diff --git a/rpc/compiler.go b/rpc/compiler.go index 6d223f3..0435b16 100644 --- a/rpc/compiler.go +++ b/rpc/compiler.go @@ -90,39 +90,44 @@ func genRcvr(name string) *ast.FieldList { func genFieldWrite(field *types.Var) ast.Stmt { name := field.Name() - var call *ast.CallExpr - basic := field.Type().(*types.Basic) - switch basic.Kind() { - case types.Uint64: - call = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ + var fun *ast.SelectorExpr + switch fTy := field.Type().(type) { + case *types.Slice: + basic := fTy.Elem().(*types.Basic) + if basic.Kind() != types.Byte { + log.Fatal("unsupported slice elem ty: ", basic.Name()) + } + fun = &ast.SelectorExpr{ + X: &ast.Ident{Name: "marshalutil"}, + Sel: &ast.Ident{Name: "WriteSlice1D"}, + } + case *types.Basic: + switch fTy.Kind() { + case types.Uint64: + fun = &ast.SelectorExpr{ X: &ast.Ident{Name: "marshal"}, Sel: &ast.Ident{Name: "WriteInt"}, - }, - Args: []ast.Expr{ - &ast.Ident{Name: "b"}, - &ast.SelectorExpr{ - X: &ast.Ident{Name: "o"}, - Sel: &ast.Ident{Name: name}, - }, - }, - } - case types.Bool: - call = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ + } + case types.Bool: + fun = &ast.SelectorExpr{ X: &ast.Ident{Name: "marshalutil"}, Sel: &ast.Ident{Name: "WriteBool"}, - }, - Args: []ast.Expr{ - &ast.Ident{Name: "b"}, - &ast.SelectorExpr{ - X: &ast.Ident{Name: "o"}, - Sel: &ast.Ident{Name: name}, - }, - }, + } + default: + log.Fatal("unsupported type: ", fTy.Name()) } default: - log.Fatal("unsupported type: ", basic.Name()) + log.Fatal("unsupported type: ", fTy) + } + call := &ast.CallExpr{ + Fun: fun, + Args: []ast.Expr{ + &ast.Ident{Name: "b"}, + &ast.SelectorExpr{ + X: &ast.Ident{Name: "o"}, + Sel: &ast.Ident{Name: name}, + }, + }, } return &ast.AssignStmt{ Lhs: []ast.Expr{&ast.Ident{Name: "b"}}, @@ -186,26 +191,42 @@ func genEncode(o types.Object) *ast.FuncDecl { func genFieldRead(field *types.Var) []ast.Stmt { name := field.Name() var call *ast.CallExpr - basic := field.Type().(*types.Basic) - switch basic.Kind() { - case types.Uint64: - call = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: &ast.Ident{Name: "marshalutil"}, - Sel: &ast.Ident{Name: "SafeReadInt"}, - }, - Args: []ast.Expr{&ast.Ident{Name: "b"}}, + switch fTy := field.Type().(type) { + case *types.Slice: + basic := fTy.Elem().(*types.Basic) + if basic.Kind() != types.Byte { + log.Fatal("unsupported slice elem ty: ", basic.Name()) } - case types.Bool: call = &ast.CallExpr{ Fun: &ast.SelectorExpr{ X: &ast.Ident{Name: "marshalutil"}, - Sel: &ast.Ident{Name: "ReadBool"}, + Sel: &ast.Ident{Name: "ReadSlice1D"}, }, Args: []ast.Expr{&ast.Ident{Name: "b"}}, } + case *types.Basic: + switch fTy.Kind() { + case types.Uint64: + call = &ast.CallExpr{ + Fun: &ast.SelectorExpr{ + X: &ast.Ident{Name: "marshalutil"}, + Sel: &ast.Ident{Name: "SafeReadInt"}, + }, + Args: []ast.Expr{&ast.Ident{Name: "b"}}, + } + case types.Bool: + call = &ast.CallExpr{ + Fun: &ast.SelectorExpr{ + X: &ast.Ident{Name: "marshalutil"}, + Sel: &ast.Ident{Name: "ReadBool"}, + }, + Args: []ast.Expr{&ast.Ident{Name: "b"}}, + } + default: + log.Fatal("unsupported type: ", fTy.Name()) + } default: - log.Fatal("unsupported type: ", basic.Name()) + log.Fatal("unsupported type: ", fTy) } assign := &ast.AssignStmt{ Lhs: []ast.Expr{ diff --git a/rpc/compiler_test.go b/rpc/compiler_test.go index fd77873..15fdbcc 100644 --- a/rpc/compiler_test.go +++ b/rpc/compiler_test.go @@ -22,11 +22,12 @@ type entry struct { } var data = []entry{ - {"ints/ints.go", "ints/ints.golden", 1}, - {"alias/alias.go", "alias/alias.golden", 1}, - {"mult/mult.go", "mult/mult.golden", 3}, - {"otherpkg/otherpkg.go", "otherpkg/otherpkg.golden", 1}, - {"bool/bool.go", "bool/bool.golden", 1}, + //{"ints/ints.go", "ints/ints.golden", 1}, + //{"alias/alias.go", "alias/alias.golden", 1}, + //{"mult/mult.go", "mult/mult.golden", 3}, + //{"otherpkg/otherpkg.go", "otherpkg/otherpkg.golden", 1}, + //{"bool/bool.go", "bool/bool.golden", 1}, + {"slice/slice.go", "slice/slice.golden", 1}, } // tmpWrite writes data to a tmp file and returns the tmp file name. diff --git a/rpc/testdata/slice/slice.go b/rpc/testdata/slice/slice.go new file mode 100644 index 0000000..67ad091 --- /dev/null +++ b/rpc/testdata/slice/slice.go @@ -0,0 +1,5 @@ +package rpc + +type arg struct { + x []byte +} diff --git a/rpc/testdata/slice/slice.golden b/rpc/testdata/slice/slice.golden new file mode 100644 index 0000000..a886817 --- /dev/null +++ b/rpc/testdata/slice/slice.golden @@ -0,0 +1,30 @@ +// Auto-generated from spec "github.com/mit-pdos/pav/rpc/testdata/slice/slice.go" +// using compiler "github.com/mit-pdos/pav/rpc". +package rpc + +import ( + "github.com/mit-pdos/pav/marshalutil" + "github.com/tchajed/marshal" +) + +type errorTy = bool + +const ( + errNone errorTy = false + errSome errorTy = true +) + +func (o *arg) encode() []byte { + var b = make([]byte, 0) + b = marshalutil.WriteSlice1D(b, o.x) + return b +} +func (o *arg) decode(b0 []byte) ([]byte, errorTy) { + var b = b0 + x, b, err := marshalutil.ReadSlice1D(b) + if err { + return nil, err + } + o.x = x + return b, errNone +} diff --git a/rpc/todo.md b/rpc/todo.md index 51de15c..24aa1a8 100644 --- a/rpc/todo.md +++ b/rpc/todo.md @@ -6,17 +6,10 @@ [ ] add fixed size []byte support. [ ] add merkle.Id support. unalias that to []byte. [x] generate same pkg name as src. -[ ] how does grpc differentiate fixed vs dynamic size byte sl? +[x] how does grpc differentiate fixed vs dynamic size byte sl? [x] 1. add epochTy support. unalias to uint64. -[ ] add bool support. +[x] add bool support. --- ## Planning - -How hard would it be to get alias's to work? -File imports some pkg. -pkg.Id is actually an alias to uint64. -How to know that? -Currently we just parse and typecheck a single file. -I think we'd need to parse/typecheck the imports to make this work?