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 }