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