github.com/noisysockets/netstack@v0.6.0/pkg/state/wire/wire.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package wire contains a few basic types that can be composed to serialize
    16  // graph information for the state package. This package defines the wire
    17  // protocol.
    18  //
    19  // Note that these types are careful about how they implement the relevant
    20  // interfaces (either value receiver or pointer receiver), so that native-sized
    21  // types, such as integers and simple pointers, can fit inside the interface
    22  // object.
    23  //
    24  // This package also uses panic as control flow, so called should be careful to
    25  // wrap calls in appropriate handlers.
    26  //
    27  // Testing for this package is driven by the state test package.
    28  package wire
    29  
    30  import (
    31  	"fmt"
    32  	"io"
    33  	"math"
    34  
    35  	"github.com/noisysockets/netstack/pkg/gohacks"
    36  	"github.com/noisysockets/netstack/pkg/sync"
    37  )
    38  
    39  var oneByteArrayPool = sync.Pool{
    40  	New: func() any { return &[1]byte{} },
    41  }
    42  
    43  // readFull is a utility. The equivalent is not needed for Write, but the API
    44  // contract dictates that it must always complete all bytes given or return an
    45  // error.
    46  func readFull(r io.Reader, p []byte) {
    47  	for done := 0; done < len(p); {
    48  		n, err := r.Read(p[done:])
    49  		done += n
    50  		if n == 0 && err != nil {
    51  			panic(err)
    52  		}
    53  	}
    54  }
    55  
    56  // Object is a generic object.
    57  type Object interface {
    58  	// save saves the given object.
    59  	//
    60  	// Panic is used for error control flow.
    61  	save(io.Writer)
    62  
    63  	// load loads a new object of the given type.
    64  	//
    65  	// Panic is used for error control flow.
    66  	load(io.Reader) Object
    67  }
    68  
    69  // Bool is a boolean.
    70  type Bool bool
    71  
    72  // loadBool loads an object of type Bool.
    73  func loadBool(r io.Reader) Bool {
    74  	b := loadUint(r)
    75  	return Bool(b == 1)
    76  }
    77  
    78  // save implements Object.save.
    79  func (b Bool) save(w io.Writer) {
    80  	var v Uint
    81  	if b {
    82  		v = 1
    83  	} else {
    84  		v = 0
    85  	}
    86  	v.save(w)
    87  }
    88  
    89  // load implements Object.load.
    90  func (Bool) load(r io.Reader) Object { return loadBool(r) }
    91  
    92  // Int is a signed integer.
    93  //
    94  // This uses varint encoding.
    95  type Int int64
    96  
    97  // loadInt loads an object of type Int.
    98  func loadInt(r io.Reader) Int {
    99  	u := loadUint(r)
   100  	x := Int(u >> 1)
   101  	if u&1 != 0 {
   102  		x = ^x
   103  	}
   104  	return x
   105  }
   106  
   107  // save implements Object.save.
   108  func (i Int) save(w io.Writer) {
   109  	u := Uint(i) << 1
   110  	if i < 0 {
   111  		u = ^u
   112  	}
   113  	u.save(w)
   114  }
   115  
   116  // load implements Object.load.
   117  func (Int) load(r io.Reader) Object { return loadInt(r) }
   118  
   119  // Uint is an unsigned integer.
   120  type Uint uint64
   121  
   122  func readByte(r io.Reader) byte {
   123  	p := oneByteArrayPool.Get().(*[1]byte)
   124  	defer oneByteArrayPool.Put(p)
   125  	n, err := r.Read(p[:])
   126  	if n != 1 {
   127  		panic(err)
   128  	}
   129  	return p[0]
   130  }
   131  
   132  // loadUint loads an object of type Uint.
   133  func loadUint(r io.Reader) Uint {
   134  	var (
   135  		u Uint
   136  		s uint
   137  	)
   138  	for i := 0; i <= 9; i++ {
   139  		b := readByte(r)
   140  		if b < 0x80 {
   141  			if i == 9 && b > 1 {
   142  				panic("overflow")
   143  			}
   144  			u |= Uint(b) << s
   145  			return u
   146  		}
   147  		u |= Uint(b&0x7f) << s
   148  		s += 7
   149  	}
   150  	panic("unreachable")
   151  }
   152  
   153  func writeByte(w io.Writer, b byte) {
   154  	p := oneByteArrayPool.Get().(*[1]byte)
   155  	defer oneByteArrayPool.Put(p)
   156  	p[0] = b
   157  	n, err := w.Write(p[:])
   158  	if n != 1 {
   159  		panic(err)
   160  	}
   161  }
   162  
   163  // save implements Object.save.
   164  func (u Uint) save(w io.Writer) {
   165  	for u >= 0x80 {
   166  		writeByte(w, byte(u)|0x80)
   167  		u >>= 7
   168  	}
   169  	writeByte(w, byte(u))
   170  }
   171  
   172  // load implements Object.load.
   173  func (Uint) load(r io.Reader) Object { return loadUint(r) }
   174  
   175  // Float32 is a 32-bit floating point number.
   176  type Float32 float32
   177  
   178  // loadFloat32 loads an object of type Float32.
   179  func loadFloat32(r io.Reader) Float32 {
   180  	n := loadUint(r)
   181  	return Float32(math.Float32frombits(uint32(n)))
   182  }
   183  
   184  // save implements Object.save.
   185  func (f Float32) save(w io.Writer) {
   186  	n := Uint(math.Float32bits(float32(f)))
   187  	n.save(w)
   188  }
   189  
   190  // load implements Object.load.
   191  func (Float32) load(r io.Reader) Object { return loadFloat32(r) }
   192  
   193  // Float64 is a 64-bit floating point number.
   194  type Float64 float64
   195  
   196  // loadFloat64 loads an object of type Float64.
   197  func loadFloat64(r io.Reader) Float64 {
   198  	n := loadUint(r)
   199  	return Float64(math.Float64frombits(uint64(n)))
   200  }
   201  
   202  // save implements Object.save.
   203  func (f Float64) save(w io.Writer) {
   204  	n := Uint(math.Float64bits(float64(f)))
   205  	n.save(w)
   206  }
   207  
   208  // load implements Object.load.
   209  func (Float64) load(r io.Reader) Object { return loadFloat64(r) }
   210  
   211  // Complex64 is a 64-bit complex number.
   212  type Complex64 complex128
   213  
   214  // loadComplex64 loads an object of type Complex64.
   215  func loadComplex64(r io.Reader) Complex64 {
   216  	re := loadFloat32(r)
   217  	im := loadFloat32(r)
   218  	return Complex64(complex(float32(re), float32(im)))
   219  }
   220  
   221  // save implements Object.save.
   222  func (c *Complex64) save(w io.Writer) {
   223  	re := Float32(real(*c))
   224  	im := Float32(imag(*c))
   225  	re.save(w)
   226  	im.save(w)
   227  }
   228  
   229  // load implements Object.load.
   230  func (*Complex64) load(r io.Reader) Object {
   231  	c := loadComplex64(r)
   232  	return &c
   233  }
   234  
   235  // Complex128 is a 128-bit complex number.
   236  type Complex128 complex128
   237  
   238  // loadComplex128 loads an object of type Complex128.
   239  func loadComplex128(r io.Reader) Complex128 {
   240  	re := loadFloat64(r)
   241  	im := loadFloat64(r)
   242  	return Complex128(complex(float64(re), float64(im)))
   243  }
   244  
   245  // save implements Object.save.
   246  func (c *Complex128) save(w io.Writer) {
   247  	re := Float64(real(*c))
   248  	im := Float64(imag(*c))
   249  	re.save(w)
   250  	im.save(w)
   251  }
   252  
   253  // load implements Object.load.
   254  func (*Complex128) load(r io.Reader) Object {
   255  	c := loadComplex128(r)
   256  	return &c
   257  }
   258  
   259  // String is a string.
   260  type String string
   261  
   262  // loadString loads an object of type String.
   263  func loadString(r io.Reader) String {
   264  	l := loadUint(r)
   265  	p := make([]byte, l)
   266  	readFull(r, p)
   267  	return String(gohacks.StringFromImmutableBytes(p))
   268  }
   269  
   270  // save implements Object.save.
   271  func (s *String) save(w io.Writer) {
   272  	l := Uint(len(*s))
   273  	l.save(w)
   274  	p := gohacks.ImmutableBytesFromString(string(*s))
   275  	_, err := w.Write(p) // Must write all bytes.
   276  	if err != nil {
   277  		panic(err)
   278  	}
   279  }
   280  
   281  // load implements Object.load.
   282  func (*String) load(r io.Reader) Object {
   283  	s := loadString(r)
   284  	return &s
   285  }
   286  
   287  // Dot is a kind of reference: one of Index and FieldName.
   288  type Dot interface {
   289  	isDot()
   290  }
   291  
   292  // Index is a reference resolution.
   293  type Index uint32
   294  
   295  func (Index) isDot() {}
   296  
   297  // FieldName is a reference resolution.
   298  type FieldName string
   299  
   300  func (*FieldName) isDot() {}
   301  
   302  // Ref is a reference to an object.
   303  type Ref struct {
   304  	// Root is the root object.
   305  	Root Uint
   306  
   307  	// Dots is the set of traversals required from the Root object above.
   308  	// Note that this will be stored in reverse order for efficiency.
   309  	Dots []Dot
   310  
   311  	// Type is the base type for the root object. This is non-nil iff Dots
   312  	// is non-zero length (that is, this is a complex reference). This is
   313  	// not *strictly* necessary, but can be used to simplify decoding.
   314  	Type TypeSpec
   315  }
   316  
   317  // loadRef loads an object of type Ref (abstract).
   318  func loadRef(r io.Reader) Ref {
   319  	ref := Ref{
   320  		Root: loadUint(r),
   321  	}
   322  	l := loadUint(r)
   323  	ref.Dots = make([]Dot, l)
   324  	for i := 0; i < int(l); i++ {
   325  		// Disambiguate between an Index (non-negative) and a field
   326  		// name (negative). This does some space and avoids a dedicate
   327  		// loadDot function. See Ref.save for the other side.
   328  		d := loadInt(r)
   329  		if d >= 0 {
   330  			ref.Dots[i] = Index(d)
   331  			continue
   332  		}
   333  		p := make([]byte, -d)
   334  		readFull(r, p)
   335  		fieldName := FieldName(gohacks.StringFromImmutableBytes(p))
   336  		ref.Dots[i] = &fieldName
   337  	}
   338  	if l != 0 {
   339  		// Only if dots is non-zero.
   340  		ref.Type = loadTypeSpec(r)
   341  	}
   342  	return ref
   343  }
   344  
   345  // save implements Object.save.
   346  func (r *Ref) save(w io.Writer) {
   347  	r.Root.save(w)
   348  	l := Uint(len(r.Dots))
   349  	l.save(w)
   350  	for _, d := range r.Dots {
   351  		// See LoadRef. We use non-negative numbers to encode Index
   352  		// objects and negative numbers to encode field lengths.
   353  		switch x := d.(type) {
   354  		case Index:
   355  			i := Int(x)
   356  			i.save(w)
   357  		case *FieldName:
   358  			d := Int(-len(*x))
   359  			d.save(w)
   360  			p := gohacks.ImmutableBytesFromString(string(*x))
   361  			if _, err := w.Write(p); err != nil {
   362  				panic(err)
   363  			}
   364  		default:
   365  			panic("unknown dot implementation")
   366  		}
   367  	}
   368  	if l != 0 {
   369  		// See above.
   370  		saveTypeSpec(w, r.Type)
   371  	}
   372  }
   373  
   374  // load implements Object.load.
   375  func (*Ref) load(r io.Reader) Object {
   376  	ref := loadRef(r)
   377  	return &ref
   378  }
   379  
   380  // Nil is a primitive zero value of any type.
   381  type Nil struct{}
   382  
   383  // loadNil loads an object of type Nil.
   384  func loadNil(r io.Reader) Nil {
   385  	return Nil{}
   386  }
   387  
   388  // save implements Object.save.
   389  func (Nil) save(w io.Writer) {}
   390  
   391  // load implements Object.load.
   392  func (Nil) load(r io.Reader) Object { return loadNil(r) }
   393  
   394  // Slice is a slice value.
   395  type Slice struct {
   396  	Length   Uint
   397  	Capacity Uint
   398  	Ref      Ref
   399  }
   400  
   401  // loadSlice loads an object of type Slice.
   402  func loadSlice(r io.Reader) Slice {
   403  	return Slice{
   404  		Length:   loadUint(r),
   405  		Capacity: loadUint(r),
   406  		Ref:      loadRef(r),
   407  	}
   408  }
   409  
   410  // save implements Object.save.
   411  func (s *Slice) save(w io.Writer) {
   412  	s.Length.save(w)
   413  	s.Capacity.save(w)
   414  	s.Ref.save(w)
   415  }
   416  
   417  // load implements Object.load.
   418  func (*Slice) load(r io.Reader) Object {
   419  	s := loadSlice(r)
   420  	return &s
   421  }
   422  
   423  // Array is an array value.
   424  type Array struct {
   425  	Contents []Object
   426  }
   427  
   428  // loadArray loads an object of type Array.
   429  func loadArray(r io.Reader) Array {
   430  	l := loadUint(r)
   431  	if l == 0 {
   432  		// Note that there isn't a single object available to encode
   433  		// the type of, so we need this additional branch.
   434  		return Array{}
   435  	}
   436  	// All the objects here have the same type, so use dynamic dispatch
   437  	// only once. All other objects will automatically take the same type
   438  	// as the first object.
   439  	contents := make([]Object, l)
   440  	v := Load(r)
   441  	contents[0] = v
   442  	for i := 1; i < int(l); i++ {
   443  		contents[i] = v.load(r)
   444  	}
   445  	return Array{
   446  		Contents: contents,
   447  	}
   448  }
   449  
   450  // save implements Object.save.
   451  func (a *Array) save(w io.Writer) {
   452  	l := Uint(len(a.Contents))
   453  	l.save(w)
   454  	if l == 0 {
   455  		// See LoadArray.
   456  		return
   457  	}
   458  	// See above.
   459  	Save(w, a.Contents[0])
   460  	for i := 1; i < int(l); i++ {
   461  		a.Contents[i].save(w)
   462  	}
   463  }
   464  
   465  // load implements Object.load.
   466  func (*Array) load(r io.Reader) Object {
   467  	a := loadArray(r)
   468  	return &a
   469  }
   470  
   471  // Map is a map value.
   472  type Map struct {
   473  	Keys   []Object
   474  	Values []Object
   475  }
   476  
   477  // loadMap loads an object of type Map.
   478  func loadMap(r io.Reader) Map {
   479  	l := loadUint(r)
   480  	if l == 0 {
   481  		// See LoadArray.
   482  		return Map{}
   483  	}
   484  	// See type dispatch notes in Array.
   485  	keys := make([]Object, l)
   486  	values := make([]Object, l)
   487  	k := Load(r)
   488  	v := Load(r)
   489  	keys[0] = k
   490  	values[0] = v
   491  	for i := 1; i < int(l); i++ {
   492  		keys[i] = k.load(r)
   493  		values[i] = v.load(r)
   494  	}
   495  	return Map{
   496  		Keys:   keys,
   497  		Values: values,
   498  	}
   499  }
   500  
   501  // save implements Object.save.
   502  func (m *Map) save(w io.Writer) {
   503  	l := Uint(len(m.Keys))
   504  	if int(l) != len(m.Values) {
   505  		panic(fmt.Sprintf("mismatched keys (%d) Aand values (%d)", len(m.Keys), len(m.Values)))
   506  	}
   507  	l.save(w)
   508  	if l == 0 {
   509  		// See LoadArray.
   510  		return
   511  	}
   512  	// See above.
   513  	Save(w, m.Keys[0])
   514  	Save(w, m.Values[0])
   515  	for i := 1; i < int(l); i++ {
   516  		m.Keys[i].save(w)
   517  		m.Values[i].save(w)
   518  	}
   519  }
   520  
   521  // load implements Object.load.
   522  func (*Map) load(r io.Reader) Object {
   523  	m := loadMap(r)
   524  	return &m
   525  }
   526  
   527  // TypeSpec is a type dereference.
   528  type TypeSpec interface {
   529  	isTypeSpec()
   530  }
   531  
   532  // TypeID is a concrete type ID.
   533  type TypeID Uint
   534  
   535  func (TypeID) isTypeSpec() {}
   536  
   537  // TypeSpecPointer is a pointer type.
   538  type TypeSpecPointer struct {
   539  	Type TypeSpec
   540  }
   541  
   542  func (*TypeSpecPointer) isTypeSpec() {}
   543  
   544  // TypeSpecArray is an array type.
   545  type TypeSpecArray struct {
   546  	Count Uint
   547  	Type  TypeSpec
   548  }
   549  
   550  func (*TypeSpecArray) isTypeSpec() {}
   551  
   552  // TypeSpecSlice is a slice type.
   553  type TypeSpecSlice struct {
   554  	Type TypeSpec
   555  }
   556  
   557  func (*TypeSpecSlice) isTypeSpec() {}
   558  
   559  // TypeSpecMap is a map type.
   560  type TypeSpecMap struct {
   561  	Key   TypeSpec
   562  	Value TypeSpec
   563  }
   564  
   565  func (*TypeSpecMap) isTypeSpec() {}
   566  
   567  // TypeSpecNil is an empty type.
   568  type TypeSpecNil struct{}
   569  
   570  func (TypeSpecNil) isTypeSpec() {}
   571  
   572  // TypeSpec types.
   573  //
   574  // These use a distinct encoding on the wire, as they are used only in the
   575  // interface object. They are decoded through the dedicated loadTypeSpec and
   576  // saveTypeSpec functions.
   577  const (
   578  	typeSpecTypeID Uint = iota
   579  	typeSpecPointer
   580  	typeSpecArray
   581  	typeSpecSlice
   582  	typeSpecMap
   583  	typeSpecNil
   584  )
   585  
   586  // loadTypeSpec loads TypeSpec values.
   587  func loadTypeSpec(r io.Reader) TypeSpec {
   588  	switch hdr := loadUint(r); hdr {
   589  	case typeSpecTypeID:
   590  		return TypeID(loadUint(r))
   591  	case typeSpecPointer:
   592  		return &TypeSpecPointer{
   593  			Type: loadTypeSpec(r),
   594  		}
   595  	case typeSpecArray:
   596  		return &TypeSpecArray{
   597  			Count: loadUint(r),
   598  			Type:  loadTypeSpec(r),
   599  		}
   600  	case typeSpecSlice:
   601  		return &TypeSpecSlice{
   602  			Type: loadTypeSpec(r),
   603  		}
   604  	case typeSpecMap:
   605  		return &TypeSpecMap{
   606  			Key:   loadTypeSpec(r),
   607  			Value: loadTypeSpec(r),
   608  		}
   609  	case typeSpecNil:
   610  		return TypeSpecNil{}
   611  	default:
   612  		// This is not a valid stream?
   613  		panic(fmt.Errorf("unknown header: %d", hdr))
   614  	}
   615  }
   616  
   617  // saveTypeSpec saves TypeSpec values.
   618  func saveTypeSpec(w io.Writer, t TypeSpec) {
   619  	switch x := t.(type) {
   620  	case TypeID:
   621  		typeSpecTypeID.save(w)
   622  		Uint(x).save(w)
   623  	case *TypeSpecPointer:
   624  		typeSpecPointer.save(w)
   625  		saveTypeSpec(w, x.Type)
   626  	case *TypeSpecArray:
   627  		typeSpecArray.save(w)
   628  		x.Count.save(w)
   629  		saveTypeSpec(w, x.Type)
   630  	case *TypeSpecSlice:
   631  		typeSpecSlice.save(w)
   632  		saveTypeSpec(w, x.Type)
   633  	case *TypeSpecMap:
   634  		typeSpecMap.save(w)
   635  		saveTypeSpec(w, x.Key)
   636  		saveTypeSpec(w, x.Value)
   637  	case TypeSpecNil:
   638  		typeSpecNil.save(w)
   639  	default:
   640  		// This should not happen?
   641  		panic(fmt.Errorf("unknown type %T", t))
   642  	}
   643  }
   644  
   645  // Interface is an interface value.
   646  type Interface struct {
   647  	Type  TypeSpec
   648  	Value Object
   649  }
   650  
   651  // loadInterface loads an object of type Interface.
   652  func loadInterface(r io.Reader) Interface {
   653  	return Interface{
   654  		Type:  loadTypeSpec(r),
   655  		Value: Load(r),
   656  	}
   657  }
   658  
   659  // save implements Object.save.
   660  func (i *Interface) save(w io.Writer) {
   661  	saveTypeSpec(w, i.Type)
   662  	Save(w, i.Value)
   663  }
   664  
   665  // load implements Object.load.
   666  func (*Interface) load(r io.Reader) Object {
   667  	i := loadInterface(r)
   668  	return &i
   669  }
   670  
   671  // Type is type information.
   672  type Type struct {
   673  	Name   string
   674  	Fields []string
   675  }
   676  
   677  // loadType loads an object of type Type.
   678  func loadType(r io.Reader) Type {
   679  	name := string(loadString(r))
   680  	l := loadUint(r)
   681  	fields := make([]string, l)
   682  	for i := 0; i < int(l); i++ {
   683  		fields[i] = string(loadString(r))
   684  	}
   685  	return Type{
   686  		Name:   name,
   687  		Fields: fields,
   688  	}
   689  }
   690  
   691  // save implements Object.save.
   692  func (t *Type) save(w io.Writer) {
   693  	s := String(t.Name)
   694  	s.save(w)
   695  	l := Uint(len(t.Fields))
   696  	l.save(w)
   697  	for i := 0; i < int(l); i++ {
   698  		s := String(t.Fields[i])
   699  		s.save(w)
   700  	}
   701  }
   702  
   703  // load implements Object.load.
   704  func (*Type) load(r io.Reader) Object {
   705  	t := loadType(r)
   706  	return &t
   707  }
   708  
   709  // multipleObjects is a special type for serializing multiple objects.
   710  type multipleObjects []Object
   711  
   712  // loadMultipleObjects loads a series of objects.
   713  func loadMultipleObjects(r io.Reader) multipleObjects {
   714  	l := loadUint(r)
   715  	m := make(multipleObjects, l)
   716  	for i := 0; i < int(l); i++ {
   717  		m[i] = Load(r)
   718  	}
   719  	return m
   720  }
   721  
   722  // save implements Object.save.
   723  func (m *multipleObjects) save(w io.Writer) {
   724  	l := Uint(len(*m))
   725  	l.save(w)
   726  	for i := 0; i < int(l); i++ {
   727  		Save(w, (*m)[i])
   728  	}
   729  }
   730  
   731  // load implements Object.load.
   732  func (*multipleObjects) load(r io.Reader) Object {
   733  	m := loadMultipleObjects(r)
   734  	return &m
   735  }
   736  
   737  // noObjects represents no objects.
   738  type noObjects struct{}
   739  
   740  // loadNoObjects loads a sentinel.
   741  func loadNoObjects(r io.Reader) noObjects { return noObjects{} }
   742  
   743  // save implements Object.save.
   744  func (noObjects) save(w io.Writer) {}
   745  
   746  // load implements Object.load.
   747  func (noObjects) load(r io.Reader) Object { return loadNoObjects(r) }
   748  
   749  // Struct is a basic composite value.
   750  type Struct struct {
   751  	TypeID TypeID
   752  	fields Object // Optionally noObjects or *multipleObjects.
   753  }
   754  
   755  // Field returns a pointer to the given field slot.
   756  //
   757  // This must be called after Alloc.
   758  func (s *Struct) Field(i int) *Object {
   759  	if fields, ok := s.fields.(*multipleObjects); ok {
   760  		return &((*fields)[i])
   761  	}
   762  	if _, ok := s.fields.(noObjects); ok {
   763  		// Alloc may be optionally called; can't call twice.
   764  		panic("Field called inappropriately, wrong Alloc?")
   765  	}
   766  	return &s.fields
   767  }
   768  
   769  // Alloc allocates the given number of fields.
   770  //
   771  // This must be called before Add and Save.
   772  //
   773  // Precondition: slots must be positive.
   774  func (s *Struct) Alloc(slots int) {
   775  	switch {
   776  	case slots == 0:
   777  		s.fields = noObjects{}
   778  	case slots == 1:
   779  		// Leave it alone.
   780  	case slots > 1:
   781  		fields := make(multipleObjects, slots)
   782  		s.fields = &fields
   783  	default:
   784  		// Violates precondition.
   785  		panic(fmt.Sprintf("Alloc called with negative slots %d?", slots))
   786  	}
   787  }
   788  
   789  // Fields returns the number of fields.
   790  func (s *Struct) Fields() int {
   791  	switch x := s.fields.(type) {
   792  	case *multipleObjects:
   793  		return len(*x)
   794  	case noObjects:
   795  		return 0
   796  	default:
   797  		return 1
   798  	}
   799  }
   800  
   801  // loadStruct loads an object of type Struct.
   802  func loadStruct(r io.Reader) Struct {
   803  	return Struct{
   804  		TypeID: TypeID(loadUint(r)),
   805  		fields: Load(r),
   806  	}
   807  }
   808  
   809  // save implements Object.save.
   810  //
   811  // Precondition: Alloc must have been called, and the fields all filled in
   812  // appropriately. See Alloc and Add for more details.
   813  func (s *Struct) save(w io.Writer) {
   814  	Uint(s.TypeID).save(w)
   815  	Save(w, s.fields)
   816  }
   817  
   818  // load implements Object.load.
   819  func (*Struct) load(r io.Reader) Object {
   820  	s := loadStruct(r)
   821  	return &s
   822  }
   823  
   824  // Object types.
   825  //
   826  // N.B. Be careful about changing the order or introducing new elements in the
   827  // middle here. This is part of the wire format and shouldn't change.
   828  const (
   829  	typeBool Uint = iota
   830  	typeInt
   831  	typeUint
   832  	typeFloat32
   833  	typeFloat64
   834  	typeNil
   835  	typeRef
   836  	typeString
   837  	typeSlice
   838  	typeArray
   839  	typeMap
   840  	typeStruct
   841  	typeNoObjects
   842  	typeMultipleObjects
   843  	typeInterface
   844  	typeComplex64
   845  	typeComplex128
   846  	typeType
   847  )
   848  
   849  // Save saves the given object.
   850  //
   851  // +checkescape all
   852  //
   853  // N.B. This function will panic on error.
   854  func Save(w io.Writer, obj Object) {
   855  	switch x := obj.(type) {
   856  	case Bool:
   857  		typeBool.save(w)
   858  		x.save(w)
   859  	case Int:
   860  		typeInt.save(w)
   861  		x.save(w)
   862  	case Uint:
   863  		typeUint.save(w)
   864  		x.save(w)
   865  	case Float32:
   866  		typeFloat32.save(w)
   867  		x.save(w)
   868  	case Float64:
   869  		typeFloat64.save(w)
   870  		x.save(w)
   871  	case Nil:
   872  		typeNil.save(w)
   873  		x.save(w)
   874  	case *Ref:
   875  		typeRef.save(w)
   876  		x.save(w)
   877  	case *String:
   878  		typeString.save(w)
   879  		x.save(w)
   880  	case *Slice:
   881  		typeSlice.save(w)
   882  		x.save(w)
   883  	case *Array:
   884  		typeArray.save(w)
   885  		x.save(w)
   886  	case *Map:
   887  		typeMap.save(w)
   888  		x.save(w)
   889  	case *Struct:
   890  		typeStruct.save(w)
   891  		x.save(w)
   892  	case noObjects:
   893  		typeNoObjects.save(w)
   894  		x.save(w)
   895  	case *multipleObjects:
   896  		typeMultipleObjects.save(w)
   897  		x.save(w)
   898  	case *Interface:
   899  		typeInterface.save(w)
   900  		x.save(w)
   901  	case *Type:
   902  		typeType.save(w)
   903  		x.save(w)
   904  	case *Complex64:
   905  		typeComplex64.save(w)
   906  		x.save(w)
   907  	case *Complex128:
   908  		typeComplex128.save(w)
   909  		x.save(w)
   910  	default:
   911  		panic(fmt.Errorf("unknown type: %#v", obj))
   912  	}
   913  }
   914  
   915  // Load loads a new object.
   916  //
   917  // +checkescape all
   918  //
   919  // N.B. This function will panic on error.
   920  func Load(r io.Reader) Object {
   921  	switch hdr := loadUint(r); hdr {
   922  	case typeBool:
   923  		return loadBool(r)
   924  	case typeInt:
   925  		return loadInt(r)
   926  	case typeUint:
   927  		return loadUint(r)
   928  	case typeFloat32:
   929  		return loadFloat32(r)
   930  	case typeFloat64:
   931  		return loadFloat64(r)
   932  	case typeNil:
   933  		return loadNil(r)
   934  	case typeRef:
   935  		return ((*Ref)(nil)).load(r) // Escapes.
   936  	case typeString:
   937  		return ((*String)(nil)).load(r) // Escapes.
   938  	case typeSlice:
   939  		return ((*Slice)(nil)).load(r) // Escapes.
   940  	case typeArray:
   941  		return ((*Array)(nil)).load(r) // Escapes.
   942  	case typeMap:
   943  		return ((*Map)(nil)).load(r) // Escapes.
   944  	case typeStruct:
   945  		return ((*Struct)(nil)).load(r) // Escapes.
   946  	case typeNoObjects: // Special for struct.
   947  		return loadNoObjects(r)
   948  	case typeMultipleObjects: // Special for struct.
   949  		return ((*multipleObjects)(nil)).load(r) // Escapes.
   950  	case typeInterface:
   951  		return ((*Interface)(nil)).load(r) // Escapes.
   952  	case typeComplex64:
   953  		return ((*Complex64)(nil)).load(r) // Escapes.
   954  	case typeComplex128:
   955  		return ((*Complex128)(nil)).load(r) // Escapes.
   956  	case typeType:
   957  		return ((*Type)(nil)).load(r) // Escapes.
   958  	default:
   959  		// This is not a valid stream?
   960  		panic(fmt.Errorf("unknown header: %d", hdr))
   961  	}
   962  }
   963  
   964  // LoadUint loads a single unsigned integer.
   965  //
   966  // N.B. This function will panic on error.
   967  func LoadUint(r io.Reader) uint64 {
   968  	return uint64(loadUint(r))
   969  }
   970  
   971  // SaveUint saves a single unsigned integer.
   972  //
   973  // N.B. This function will panic on error.
   974  func SaveUint(w io.Writer, v uint64) {
   975  	Uint(v).save(w)
   976  }