From cfa4633c3d206aa2f9abdaac60d053162244ee6d Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Mon, 8 Feb 2021 18:03:29 -0800 Subject: [go-marshal] Add dynamic tag in go_marshal. This makes it easier to implement dynamically sized types in go-marshal. You really only need to implement MarshalBytes, UnmarshalBytes and SizeBytes to implement the entire interface. By using the `dynamic` tag, the autogenerator will generate the rest of the methods for us. This change also simplifies how KernelIPTGetEntries implements Marshallable using the newly added utility. PiperOrigin-RevId: 356397114 --- tools/go_marshal/test/BUILD | 6 +++++- tools/go_marshal/test/marshal_test.go | 19 +++++++++++++++++++ tools/go_marshal/test/test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) (limited to 'tools/go_marshal/test') diff --git a/tools/go_marshal/test/BUILD b/tools/go_marshal/test/BUILD index 4b27773c2..cb2d4e6e3 100644 --- a/tools/go_marshal/test/BUILD +++ b/tools/go_marshal/test/BUILD @@ -26,7 +26,10 @@ go_library( srcs = ["test.go"], marshal = True, visibility = ["//tools/go_marshal/test:__subpackages__"], - deps = ["//tools/go_marshal/test/external"], + deps = [ + "//pkg/marshal/primitive", + "//tools/go_marshal/test/external", + ], ) go_test( @@ -36,6 +39,7 @@ go_test( deps = [ ":test", "//pkg/marshal", + "//pkg/marshal/primitive", "//pkg/syserror", "//pkg/usermem", "//tools/go_marshal/analysis", diff --git a/tools/go_marshal/test/marshal_test.go b/tools/go_marshal/test/marshal_test.go index a00f9a684..b0091dc64 100644 --- a/tools/go_marshal/test/marshal_test.go +++ b/tools/go_marshal/test/marshal_test.go @@ -28,6 +28,7 @@ import ( "github.com/google/go-cmp/cmp" "gvisor.dev/gvisor/pkg/marshal" + "gvisor.dev/gvisor/pkg/marshal/primitive" "gvisor.dev/gvisor/pkg/syserror" "gvisor.dev/gvisor/pkg/usermem" "gvisor.dev/gvisor/tools/go_marshal/analysis" @@ -513,3 +514,21 @@ func TestLimitedSliceMarshalling(t *testing.T) { }) } } + +func TestDynamicType(t *testing.T) { + t12 := test.Type12Dynamic{ + X: 32, + Y: []primitive.Int64{5, 6, 7}, + } + + var m marshal.Marshallable + m = &t12 // Ensure that all methods were generated. + b := make([]byte, m.SizeBytes()) + m.MarshalBytes(b) + + var res test.Type12Dynamic + res.UnmarshalBytes(b) + if !reflect.DeepEqual(t12, res) { + t.Errorf("dynamic type is not same after marshalling and unmarshalling: before = %+v, after = %+v", t12, res) + } +} diff --git a/tools/go_marshal/test/test.go b/tools/go_marshal/test/test.go index e7e3ed74a..b8eb989d9 100644 --- a/tools/go_marshal/test/test.go +++ b/tools/go_marshal/test/test.go @@ -16,6 +16,8 @@ package test import ( + "gvisor.dev/gvisor/pkg/marshal/primitive" + // We're intentionally using a package name alias here even though it's not // necessary to test the code generator's ability to handle package aliases. ex "gvisor.dev/gvisor/tools/go_marshal/test/external" @@ -198,3 +200,36 @@ type Type11 struct { ex.External y int64 } + +// Type12Dynamic is a dynamically sized struct which depends on the autogenerator +// to generate some Marshallable methods for it. +// +// +marshal dynamic +type Type12Dynamic struct { + X primitive.Int64 + Y []primitive.Int64 +} + +// SizeBytes implements marshal.Marshallable.SizeBytes. +func (t *Type12Dynamic) SizeBytes() int { + return (len(t.Y) * 8) + t.X.SizeBytes() +} + +// MarshalBytes implements marshal.Marshallable.MarshalBytes. +func (t *Type12Dynamic) MarshalBytes(dst []byte) { + t.X.MarshalBytes(dst) + dst = dst[t.X.SizeBytes():] + for i, x := range t.Y { + x.MarshalBytes(dst[i*8 : (i+1)*8]) + } +} + +// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. +func (t *Type12Dynamic) UnmarshalBytes(src []byte) { + t.X.UnmarshalBytes(src) + for i := t.X.SizeBytes(); i < len(src); i += 8 { + var x primitive.Int64 + x.UnmarshalBytes(src[i:]) + t.Y = append(t.Y, x) + } +} -- cgit v1.2.3