github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/universe.go (about) 1 // Copyright 2009 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 package gc 6 7 // builtinpkg is a fake package that declares the universe block. 8 var builtinpkg *Pkg 9 10 var itable *Type // distinguished *byte 11 12 var basicTypes = [...]struct { 13 name string 14 etype EType 15 }{ 16 {"int8", TINT8}, 17 {"int16", TINT16}, 18 {"int32", TINT32}, 19 {"int64", TINT64}, 20 {"uint8", TUINT8}, 21 {"uint16", TUINT16}, 22 {"uint32", TUINT32}, 23 {"uint64", TUINT64}, 24 {"float32", TFLOAT32}, 25 {"float64", TFLOAT64}, 26 {"complex64", TCOMPLEX64}, 27 {"complex128", TCOMPLEX128}, 28 {"bool", TBOOL}, 29 {"string", TSTRING}, 30 } 31 32 var typedefs = [...]struct { 33 name string 34 etype EType 35 width *int 36 sameas32 EType 37 sameas64 EType 38 }{ 39 {"int", TINT, &Widthint, TINT32, TINT64}, 40 {"uint", TUINT, &Widthint, TUINT32, TUINT64}, 41 {"uintptr", TUINTPTR, &Widthptr, TUINT32, TUINT64}, 42 } 43 44 var builtinFuncs = [...]struct { 45 name string 46 op Op 47 }{ 48 {"append", OAPPEND}, 49 {"cap", OCAP}, 50 {"close", OCLOSE}, 51 {"complex", OCOMPLEX}, 52 {"copy", OCOPY}, 53 {"delete", ODELETE}, 54 {"imag", OIMAG}, 55 {"len", OLEN}, 56 {"make", OMAKE}, 57 {"new", ONEW}, 58 {"panic", OPANIC}, 59 {"print", OPRINT}, 60 {"println", OPRINTN}, 61 {"real", OREAL}, 62 {"recover", ORECOVER}, 63 } 64 65 var unsafeFuncs = [...]struct { 66 name string 67 op Op 68 }{ 69 {"Alignof", OALIGNOF}, 70 {"Offsetof", OOFFSETOF}, 71 {"Sizeof", OSIZEOF}, 72 } 73 74 // initUniverse initializes the universe block. 75 func initUniverse() { 76 lexinit() 77 typeinit() 78 lexinit1() 79 } 80 81 // lexinit initializes known symbols and the basic types. 82 func lexinit() { 83 for _, s := range basicTypes { 84 etype := s.etype 85 if int(etype) >= len(Types) { 86 Fatalf("lexinit: %s bad etype", s.name) 87 } 88 s2 := Pkglookup(s.name, builtinpkg) 89 t := Types[etype] 90 if t == nil { 91 t = typ(etype) 92 t.Sym = s2 93 if etype != TANY && etype != TSTRING { 94 dowidth(t) 95 } 96 Types[etype] = t 97 } 98 s2.Def = typenod(t) 99 s2.Def.Name = new(Name) 100 } 101 102 for _, s := range builtinFuncs { 103 // TODO(marvin): Fix Node.EType type union. 104 s2 := Pkglookup(s.name, builtinpkg) 105 s2.Def = nod(ONAME, nil, nil) 106 s2.Def.Sym = s2 107 s2.Def.Etype = EType(s.op) 108 } 109 110 for _, s := range unsafeFuncs { 111 s2 := Pkglookup(s.name, unsafepkg) 112 s2.Def = nod(ONAME, nil, nil) 113 s2.Def.Sym = s2 114 s2.Def.Etype = EType(s.op) 115 } 116 117 idealstring = typ(TSTRING) 118 idealbool = typ(TBOOL) 119 Types[TANY] = typ(TANY) 120 121 s := Pkglookup("true", builtinpkg) 122 s.Def = nodbool(true) 123 s.Def.Sym = lookup("true") 124 s.Def.Name = new(Name) 125 s.Def.Type = idealbool 126 127 s = Pkglookup("false", builtinpkg) 128 s.Def = nodbool(false) 129 s.Def.Sym = lookup("false") 130 s.Def.Name = new(Name) 131 s.Def.Type = idealbool 132 133 s = lookup("_") 134 s.Block = -100 135 s.Def = nod(ONAME, nil, nil) 136 s.Def.Sym = s 137 Types[TBLANK] = typ(TBLANK) 138 s.Def.Type = Types[TBLANK] 139 nblank = s.Def 140 141 s = Pkglookup("_", builtinpkg) 142 s.Block = -100 143 s.Def = nod(ONAME, nil, nil) 144 s.Def.Sym = s 145 Types[TBLANK] = typ(TBLANK) 146 s.Def.Type = Types[TBLANK] 147 148 Types[TNIL] = typ(TNIL) 149 s = Pkglookup("nil", builtinpkg) 150 var v Val 151 v.U = new(NilVal) 152 s.Def = nodlit(v) 153 s.Def.Sym = s 154 s.Def.Name = new(Name) 155 156 s = Pkglookup("iota", builtinpkg) 157 s.Def = nod(OIOTA, nil, nil) 158 s.Def.Sym = s 159 s.Def.Name = new(Name) 160 } 161 162 func typeinit() { 163 if Widthptr == 0 { 164 Fatalf("typeinit before betypeinit") 165 } 166 167 for et := EType(0); et < NTYPE; et++ { 168 simtype[et] = et 169 } 170 171 Types[TPTR32] = typ(TPTR32) 172 dowidth(Types[TPTR32]) 173 174 Types[TPTR64] = typ(TPTR64) 175 dowidth(Types[TPTR64]) 176 177 t := typ(TUNSAFEPTR) 178 Types[TUNSAFEPTR] = t 179 t.Sym = Pkglookup("Pointer", unsafepkg) 180 t.Sym.Def = typenod(t) 181 t.Sym.Def.Name = new(Name) 182 dowidth(Types[TUNSAFEPTR]) 183 184 Tptr = TPTR32 185 if Widthptr == 8 { 186 Tptr = TPTR64 187 } 188 189 for et := TINT8; et <= TUINT64; et++ { 190 isInt[et] = true 191 } 192 isInt[TINT] = true 193 isInt[TUINT] = true 194 isInt[TUINTPTR] = true 195 196 isFloat[TFLOAT32] = true 197 isFloat[TFLOAT64] = true 198 199 isComplex[TCOMPLEX64] = true 200 isComplex[TCOMPLEX128] = true 201 202 isforw[TFORW] = true 203 204 // initialize okfor 205 for et := EType(0); et < NTYPE; et++ { 206 if isInt[et] || et == TIDEAL { 207 okforeq[et] = true 208 okforcmp[et] = true 209 okforarith[et] = true 210 okforadd[et] = true 211 okforand[et] = true 212 okforconst[et] = true 213 issimple[et] = true 214 minintval[et] = new(Mpint) 215 maxintval[et] = new(Mpint) 216 } 217 218 if isFloat[et] { 219 okforeq[et] = true 220 okforcmp[et] = true 221 okforadd[et] = true 222 okforarith[et] = true 223 okforconst[et] = true 224 issimple[et] = true 225 minfltval[et] = newMpflt() 226 maxfltval[et] = newMpflt() 227 } 228 229 if isComplex[et] { 230 okforeq[et] = true 231 okforadd[et] = true 232 okforarith[et] = true 233 okforconst[et] = true 234 issimple[et] = true 235 } 236 } 237 238 issimple[TBOOL] = true 239 240 okforadd[TSTRING] = true 241 242 okforbool[TBOOL] = true 243 244 okforcap[TARRAY] = true 245 okforcap[TCHAN] = true 246 okforcap[TSLICE] = true 247 248 okforconst[TBOOL] = true 249 okforconst[TSTRING] = true 250 251 okforlen[TARRAY] = true 252 okforlen[TCHAN] = true 253 okforlen[TMAP] = true 254 okforlen[TSLICE] = true 255 okforlen[TSTRING] = true 256 257 okforeq[TPTR32] = true 258 okforeq[TPTR64] = true 259 okforeq[TUNSAFEPTR] = true 260 okforeq[TINTER] = true 261 okforeq[TCHAN] = true 262 okforeq[TSTRING] = true 263 okforeq[TBOOL] = true 264 okforeq[TMAP] = true // nil only; refined in typecheck 265 okforeq[TFUNC] = true // nil only; refined in typecheck 266 okforeq[TSLICE] = true // nil only; refined in typecheck 267 okforeq[TARRAY] = true // only if element type is comparable; refined in typecheck 268 okforeq[TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck 269 270 okforcmp[TSTRING] = true 271 272 var i int 273 for i = 0; i < len(okfor); i++ { 274 okfor[i] = okfornone[:] 275 } 276 277 // binary 278 okfor[OADD] = okforadd[:] 279 280 okfor[OAND] = okforand[:] 281 okfor[OANDAND] = okforbool[:] 282 okfor[OANDNOT] = okforand[:] 283 okfor[ODIV] = okforarith[:] 284 okfor[OEQ] = okforeq[:] 285 okfor[OGE] = okforcmp[:] 286 okfor[OGT] = okforcmp[:] 287 okfor[OLE] = okforcmp[:] 288 okfor[OLT] = okforcmp[:] 289 okfor[OMOD] = okforand[:] 290 okfor[OHMUL] = okforarith[:] 291 okfor[OMUL] = okforarith[:] 292 okfor[ONE] = okforeq[:] 293 okfor[OOR] = okforand[:] 294 okfor[OOROR] = okforbool[:] 295 okfor[OSUB] = okforarith[:] 296 okfor[OXOR] = okforand[:] 297 okfor[OLSH] = okforand[:] 298 okfor[ORSH] = okforand[:] 299 300 // unary 301 okfor[OCOM] = okforand[:] 302 303 okfor[OMINUS] = okforarith[:] 304 okfor[ONOT] = okforbool[:] 305 okfor[OPLUS] = okforarith[:] 306 307 // special 308 okfor[OCAP] = okforcap[:] 309 310 okfor[OLEN] = okforlen[:] 311 312 // comparison 313 iscmp[OLT] = true 314 315 iscmp[OGT] = true 316 iscmp[OGE] = true 317 iscmp[OLE] = true 318 iscmp[OEQ] = true 319 iscmp[ONE] = true 320 321 maxintval[TINT8].SetString("0x7f") 322 minintval[TINT8].SetString("-0x80") 323 maxintval[TINT16].SetString("0x7fff") 324 minintval[TINT16].SetString("-0x8000") 325 maxintval[TINT32].SetString("0x7fffffff") 326 minintval[TINT32].SetString("-0x80000000") 327 maxintval[TINT64].SetString("0x7fffffffffffffff") 328 minintval[TINT64].SetString("-0x8000000000000000") 329 330 maxintval[TUINT8].SetString("0xff") 331 maxintval[TUINT16].SetString("0xffff") 332 maxintval[TUINT32].SetString("0xffffffff") 333 maxintval[TUINT64].SetString("0xffffffffffffffff") 334 335 // f is valid float if min < f < max. (min and max are not themselves valid.) 336 maxfltval[TFLOAT32].SetString("33554431p103") // 2^24-1 p (127-23) + 1/2 ulp 337 minfltval[TFLOAT32].SetString("-33554431p103") 338 maxfltval[TFLOAT64].SetString("18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp 339 minfltval[TFLOAT64].SetString("-18014398509481983p970") 340 341 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32] 342 minfltval[TCOMPLEX64] = minfltval[TFLOAT32] 343 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64] 344 minfltval[TCOMPLEX128] = minfltval[TFLOAT64] 345 346 // for walk to use in error messages 347 Types[TFUNC] = functype(nil, nil, nil) 348 349 // types used in front end 350 // types[TNIL] got set early in lexinit 351 Types[TIDEAL] = typ(TIDEAL) 352 353 Types[TINTER] = typ(TINTER) 354 355 // simple aliases 356 simtype[TMAP] = Tptr 357 358 simtype[TCHAN] = Tptr 359 simtype[TFUNC] = Tptr 360 simtype[TUNSAFEPTR] = Tptr 361 362 array_array = int(Rnd(0, int64(Widthptr))) 363 array_nel = int(Rnd(int64(array_array)+int64(Widthptr), int64(Widthint))) 364 array_cap = int(Rnd(int64(array_nel)+int64(Widthint), int64(Widthint))) 365 sizeof_Array = int(Rnd(int64(array_cap)+int64(Widthint), int64(Widthptr))) 366 367 // string is same as slice wo the cap 368 sizeof_String = int(Rnd(int64(array_nel)+int64(Widthint), int64(Widthptr))) 369 370 dowidth(Types[TSTRING]) 371 dowidth(idealstring) 372 373 itable = typPtr(Types[TUINT8]) 374 } 375 376 func makeErrorInterface() *Type { 377 field := newField() 378 field.Type = Types[TSTRING] 379 f := functypefield(fakethisfield(), nil, []*Field{field}) 380 381 field = newField() 382 field.Sym = lookup("Error") 383 field.Type = f 384 385 t := typ(TINTER) 386 t.SetFields([]*Field{field}) 387 return t 388 } 389 390 func lexinit1() { 391 // error type 392 s := Pkglookup("error", builtinpkg) 393 errortype = makeErrorInterface() 394 errortype.Sym = s 395 // TODO: If we can prove that it's safe to set errortype.Orig here 396 // than we don't need the special errortype/errorInterface case in 397 // bexport.go. See also issue #15920. 398 // errortype.Orig = makeErrorInterface() 399 s.Def = typenod(errortype) 400 401 // byte alias 402 s = Pkglookup("byte", builtinpkg) 403 bytetype = typ(TUINT8) 404 bytetype.Sym = s 405 s.Def = typenod(bytetype) 406 s.Def.Name = new(Name) 407 408 // rune alias 409 s = Pkglookup("rune", builtinpkg) 410 runetype = typ(TINT32) 411 runetype.Sym = s 412 s.Def = typenod(runetype) 413 s.Def.Name = new(Name) 414 415 // backend-dependent builtin types (e.g. int). 416 for _, s := range typedefs { 417 s1 := Pkglookup(s.name, builtinpkg) 418 419 sameas := s.sameas32 420 if *s.width == 8 { 421 sameas = s.sameas64 422 } 423 424 simtype[s.etype] = sameas 425 minfltval[s.etype] = minfltval[sameas] 426 maxfltval[s.etype] = maxfltval[sameas] 427 minintval[s.etype] = minintval[sameas] 428 maxintval[s.etype] = maxintval[sameas] 429 430 t := typ(s.etype) 431 t.Sym = s1 432 Types[s.etype] = t 433 s1.Def = typenod(t) 434 s1.Def.Name = new(Name) 435 s1.Origpkg = builtinpkg 436 437 dowidth(t) 438 } 439 } 440 441 // finishUniverse makes the universe block visible within the current package. 442 func finishUniverse() { 443 // Operationally, this is similar to a dot import of builtinpkg, except 444 // that we silently skip symbols that are already declared in the 445 // package block rather than emitting a redeclared symbol error. 446 447 for _, s := range builtinpkg.Syms { 448 if s.Def == nil { 449 continue 450 } 451 s1 := lookup(s.Name) 452 if s1.Def != nil { 453 continue 454 } 455 456 s1.Def = s.Def 457 s1.Block = s.Block 458 } 459 460 nodfp = nod(ONAME, nil, nil) 461 nodfp.Type = Types[TINT32] 462 nodfp.Xoffset = 0 463 nodfp.Class = PPARAM 464 nodfp.Sym = lookup(".fp") 465 }