github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/go/importer/import.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This implementation is loosely based on the algorithm described
     6  // in: "On the linearization of graphs and writing symbol files",
     7  // by R. Griesemer, Technical Report 156, ETH Zürich, 1991.
     8  
     9  // package importer implements an exporter and importer for Go export data.
    10  package importer // import "llvm.org/llgo/third_party/gotools/go/importer"
    11  
    12  import (
    13  	"encoding/binary"
    14  	"fmt"
    15  	"go/token"
    16  
    17  	"llvm.org/llgo/third_party/gotools/go/exact"
    18  	"llvm.org/llgo/third_party/gotools/go/types"
    19  )
    20  
    21  // ImportData imports a package from the serialized package data
    22  // and returns the number of bytes consumed and a reference to the package.
    23  // If data is obviously malformed, an error is returned but in
    24  // general it is not recommended to call ImportData on untrusted
    25  // data.
    26  func ImportData(imports map[string]*types.Package, data []byte) (int, *types.Package, error) {
    27  	datalen := len(data)
    28  
    29  	// check magic string
    30  	var s string
    31  	if len(data) >= len(magic) {
    32  		s = string(data[:len(magic)])
    33  		data = data[len(magic):]
    34  	}
    35  	if s != magic {
    36  		return 0, nil, fmt.Errorf("incorrect magic string: got %q; want %q", s, magic)
    37  	}
    38  
    39  	// check low-level encoding format
    40  	var m byte = 'm' // missing format
    41  	if len(data) > 0 {
    42  		m = data[0]
    43  		data = data[1:]
    44  	}
    45  	if m != format() {
    46  		return 0, nil, fmt.Errorf("incorrect low-level encoding format: got %c; want %c", m, format())
    47  	}
    48  
    49  	p := importer{
    50  		data:    data,
    51  		datalen: datalen,
    52  		imports: imports,
    53  	}
    54  
    55  	// populate typList with predeclared types
    56  	for _, t := range predeclared {
    57  		p.typList = append(p.typList, t)
    58  	}
    59  
    60  	if v := p.string(); v != version {
    61  		return 0, nil, fmt.Errorf("unknown version: got %s; want %s", v, version)
    62  	}
    63  
    64  	pkg := p.pkg()
    65  	if debug && p.pkgList[0] != pkg {
    66  		panic("imported packaged not found in pkgList[0]")
    67  	}
    68  
    69  	// read objects
    70  	n := p.int()
    71  	for i := 0; i < n; i++ {
    72  		p.obj(pkg)
    73  	}
    74  
    75  	// complete interfaces
    76  	for _, typ := range p.typList {
    77  		if it, ok := typ.(*types.Interface); ok {
    78  			it.Complete()
    79  		}
    80  	}
    81  
    82  	// package was imported completely and without errors
    83  	pkg.MarkComplete()
    84  
    85  	return p.consumed(), pkg, nil
    86  }
    87  
    88  type importer struct {
    89  	data    []byte
    90  	datalen int
    91  	imports map[string]*types.Package
    92  	pkgList []*types.Package
    93  	typList []types.Type
    94  }
    95  
    96  func (p *importer) pkg() *types.Package {
    97  	// if the package was seen before, i is its index (>= 0)
    98  	i := p.int()
    99  	if i >= 0 {
   100  		return p.pkgList[i]
   101  	}
   102  
   103  	// otherwise, i is the package tag (< 0)
   104  	if i != packageTag {
   105  		panic(fmt.Sprintf("unexpected package tag %d", i))
   106  	}
   107  
   108  	// read package data
   109  	name := p.string()
   110  	path := p.string()
   111  
   112  	// if the package was imported before, use that one; otherwise create a new one
   113  	pkg := p.imports[path]
   114  	if pkg == nil {
   115  		pkg = types.NewPackage(path, name)
   116  		p.imports[path] = pkg
   117  	}
   118  	p.pkgList = append(p.pkgList, pkg)
   119  
   120  	return pkg
   121  }
   122  
   123  func (p *importer) obj(pkg *types.Package) {
   124  	var obj types.Object
   125  	switch tag := p.int(); tag {
   126  	case constTag:
   127  		obj = types.NewConst(token.NoPos, pkg, p.string(), p.typ(), p.value())
   128  	case typeTag:
   129  		// type object is added to scope via respective named type
   130  		_ = p.typ().(*types.Named)
   131  		return
   132  	case varTag:
   133  		obj = types.NewVar(token.NoPos, pkg, p.string(), p.typ())
   134  	case funcTag:
   135  		obj = types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature))
   136  	default:
   137  		panic(fmt.Sprintf("unexpected object tag %d", tag))
   138  	}
   139  
   140  	if alt := pkg.Scope().Insert(obj); alt != nil {
   141  		panic(fmt.Sprintf("%s already declared", alt.Name()))
   142  	}
   143  }
   144  
   145  func (p *importer) value() exact.Value {
   146  	switch kind := exact.Kind(p.int()); kind {
   147  	case falseTag:
   148  		return exact.MakeBool(false)
   149  	case trueTag:
   150  		return exact.MakeBool(true)
   151  	case int64Tag:
   152  		return exact.MakeInt64(p.int64())
   153  	case floatTag:
   154  		return p.float()
   155  	case fractionTag:
   156  		return p.fraction()
   157  	case complexTag:
   158  		re := p.fraction()
   159  		im := p.fraction()
   160  		return exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
   161  	case stringTag:
   162  		return exact.MakeString(p.string())
   163  	default:
   164  		panic(fmt.Sprintf("unexpected value kind %d", kind))
   165  	}
   166  }
   167  
   168  func (p *importer) float() exact.Value {
   169  	sign := p.int()
   170  	if sign == 0 {
   171  		return exact.MakeInt64(0)
   172  	}
   173  
   174  	x := p.ufloat()
   175  	if sign < 0 {
   176  		x = exact.UnaryOp(token.SUB, x, 0)
   177  	}
   178  	return x
   179  }
   180  
   181  func (p *importer) fraction() exact.Value {
   182  	sign := p.int()
   183  	if sign == 0 {
   184  		return exact.MakeInt64(0)
   185  	}
   186  
   187  	x := exact.BinaryOp(p.ufloat(), token.QUO, p.ufloat())
   188  	if sign < 0 {
   189  		x = exact.UnaryOp(token.SUB, x, 0)
   190  	}
   191  	return x
   192  }
   193  
   194  func (p *importer) ufloat() exact.Value {
   195  	exp := p.int()
   196  	x := exact.MakeFromBytes(p.bytes())
   197  	switch {
   198  	case exp < 0:
   199  		d := exact.Shift(exact.MakeInt64(1), token.SHL, uint(-exp))
   200  		x = exact.BinaryOp(x, token.QUO, d)
   201  	case exp > 0:
   202  		x = exact.Shift(x, token.SHL, uint(exp))
   203  	}
   204  	return x
   205  }
   206  
   207  func (p *importer) record(t types.Type) {
   208  	p.typList = append(p.typList, t)
   209  }
   210  
   211  func (p *importer) typ() types.Type {
   212  	// if the type was seen before, i is its index (>= 0)
   213  	i := p.int()
   214  	if i >= 0 {
   215  		return p.typList[i]
   216  	}
   217  
   218  	// otherwise, i is the type tag (< 0)
   219  	switch i {
   220  	case arrayTag:
   221  		t := new(types.Array)
   222  		p.record(t)
   223  
   224  		n := p.int64()
   225  		*t = *types.NewArray(p.typ(), n)
   226  		return t
   227  
   228  	case sliceTag:
   229  		t := new(types.Slice)
   230  		p.record(t)
   231  
   232  		*t = *types.NewSlice(p.typ())
   233  		return t
   234  
   235  	case structTag:
   236  		t := new(types.Struct)
   237  		p.record(t)
   238  
   239  		n := p.int()
   240  		fields := make([]*types.Var, n)
   241  		tags := make([]string, n)
   242  		for i := range fields {
   243  			fields[i] = p.field()
   244  			tags[i] = p.string()
   245  		}
   246  		*t = *types.NewStruct(fields, tags)
   247  		return t
   248  
   249  	case pointerTag:
   250  		t := new(types.Pointer)
   251  		p.record(t)
   252  
   253  		*t = *types.NewPointer(p.typ())
   254  		return t
   255  
   256  	case signatureTag:
   257  		t := new(types.Signature)
   258  		p.record(t)
   259  
   260  		*t = *p.signature()
   261  		return t
   262  
   263  	case interfaceTag:
   264  		// Create a dummy entry in the type list. This is safe because we
   265  		// cannot expect the interface type to appear in a cycle, as any
   266  		// such cycle must contain a named type which would have been
   267  		// first defined earlier.
   268  		n := len(p.typList)
   269  		p.record(nil)
   270  
   271  		// read embedded interfaces
   272  		embeddeds := make([]*types.Named, p.int())
   273  		for i := range embeddeds {
   274  			embeddeds[i] = p.typ().(*types.Named)
   275  		}
   276  
   277  		// read methods
   278  		methods := make([]*types.Func, p.int())
   279  		for i := range methods {
   280  			pkg, name := p.qualifiedName()
   281  			methods[i] = types.NewFunc(token.NoPos, pkg, name, p.typ().(*types.Signature))
   282  		}
   283  
   284  		t := types.NewInterface(methods, embeddeds)
   285  		p.typList[n] = t
   286  		return t
   287  
   288  	case mapTag:
   289  		t := new(types.Map)
   290  		p.record(t)
   291  
   292  		*t = *types.NewMap(p.typ(), p.typ())
   293  		return t
   294  
   295  	case chanTag:
   296  		t := new(types.Chan)
   297  		p.record(t)
   298  
   299  		*t = *types.NewChan(types.ChanDir(p.int()), p.typ())
   300  		return t
   301  
   302  	case namedTag:
   303  		// read type object
   304  		name := p.string()
   305  		pkg := p.pkg()
   306  		scope := pkg.Scope()
   307  		obj := scope.Lookup(name)
   308  
   309  		// if the object doesn't exist yet, create and insert it
   310  		if obj == nil {
   311  			obj = types.NewTypeName(token.NoPos, pkg, name, nil)
   312  			scope.Insert(obj)
   313  		}
   314  
   315  		// associate new named type with obj if it doesn't exist yet
   316  		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
   317  
   318  		// but record the existing type, if any
   319  		t := obj.Type().(*types.Named)
   320  		p.record(t)
   321  
   322  		// read underlying type
   323  		t0.SetUnderlying(p.typ())
   324  
   325  		// read associated methods
   326  		for i, n := 0, p.int(); i < n; i++ {
   327  			t0.AddMethod(types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature)))
   328  		}
   329  
   330  		return t
   331  
   332  	default:
   333  		panic(fmt.Sprintf("unexpected type tag %d", i))
   334  	}
   335  }
   336  
   337  func deref(typ types.Type) types.Type {
   338  	if p, _ := typ.(*types.Pointer); p != nil {
   339  		return p.Elem()
   340  	}
   341  	return typ
   342  }
   343  
   344  func (p *importer) field() *types.Var {
   345  	pkg, name := p.qualifiedName()
   346  	typ := p.typ()
   347  
   348  	anonymous := false
   349  	if name == "" {
   350  		// anonymous field - typ must be T or *T and T must be a type name
   351  		switch typ := deref(typ).(type) {
   352  		case *types.Basic: // basic types are named types
   353  			pkg = nil
   354  			name = typ.Name()
   355  		case *types.Named:
   356  			obj := typ.Obj()
   357  			name = obj.Name()
   358  			// correct the field package for anonymous fields
   359  			if exported(name) {
   360  				pkg = p.pkgList[0]
   361  			}
   362  		default:
   363  			panic("anonymous field expected")
   364  		}
   365  		anonymous = true
   366  	}
   367  
   368  	return types.NewField(token.NoPos, pkg, name, typ, anonymous)
   369  }
   370  
   371  func (p *importer) qualifiedName() (*types.Package, string) {
   372  	name := p.string()
   373  	pkg := p.pkgList[0] // exported names assume current package
   374  	if !exported(name) {
   375  		pkg = p.pkg()
   376  	}
   377  	return pkg, name
   378  }
   379  
   380  func (p *importer) signature() *types.Signature {
   381  	var recv *types.Var
   382  	if p.int() != 0 {
   383  		recv = p.param()
   384  	}
   385  	return types.NewSignature(nil, recv, p.tuple(), p.tuple(), p.int() != 0)
   386  }
   387  
   388  func (p *importer) param() *types.Var {
   389  	return types.NewVar(token.NoPos, nil, p.string(), p.typ())
   390  }
   391  
   392  func (p *importer) tuple() *types.Tuple {
   393  	vars := make([]*types.Var, p.int())
   394  	for i := range vars {
   395  		vars[i] = p.param()
   396  	}
   397  	return types.NewTuple(vars...)
   398  }
   399  
   400  // ----------------------------------------------------------------------------
   401  // decoders
   402  
   403  func (p *importer) string() string {
   404  	return string(p.bytes())
   405  }
   406  
   407  func (p *importer) int() int {
   408  	return int(p.int64())
   409  }
   410  
   411  func (p *importer) int64() int64 {
   412  	if debug {
   413  		p.marker('i')
   414  	}
   415  
   416  	return p.rawInt64()
   417  }
   418  
   419  // Note: bytes() returns the respective byte slice w/o copy.
   420  func (p *importer) bytes() []byte {
   421  	if debug {
   422  		p.marker('b')
   423  	}
   424  
   425  	var b []byte
   426  	if n := int(p.rawInt64()); n > 0 {
   427  		b = p.data[:n]
   428  		p.data = p.data[n:]
   429  	}
   430  	return b
   431  }
   432  
   433  func (p *importer) marker(want byte) {
   434  	if debug {
   435  		if got := p.data[0]; got != want {
   436  			panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.consumed()))
   437  		}
   438  		p.data = p.data[1:]
   439  
   440  		pos := p.consumed()
   441  		if n := int(p.rawInt64()); n != pos {
   442  			panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
   443  		}
   444  	}
   445  }
   446  
   447  // rawInt64 should only be used by low-level decoders
   448  func (p *importer) rawInt64() int64 {
   449  	i, n := binary.Varint(p.data)
   450  	p.data = p.data[n:]
   451  	return i
   452  }
   453  
   454  func (p *importer) consumed() int {
   455  	return p.datalen - len(p.data)
   456  }