wire.go raw

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