github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/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 232 okforconst[TBOOL] = true 233 okforconst[TSTRING] = true 234 235 okforlen[TARRAY] = true 236 okforlen[TCHAN] = true 237 okforlen[TMAP] = true 238 okforlen[TSTRING] = true 239 240 okforeq[TPTR32] = true 241 okforeq[TPTR64] = true 242 okforeq[TUNSAFEPTR] = true 243 okforeq[TINTER] = true 244 okforeq[TCHAN] = true 245 okforeq[TSTRING] = true 246 okforeq[TBOOL] = true 247 okforeq[TMAP] = true // nil only; refined in typecheck 248 okforeq[TFUNC] = true // nil only; refined in typecheck 249 okforeq[TARRAY] = true // nil slice only; refined in typecheck 250 okforeq[TSTRUCT] = true // it's complicated; refined in typecheck 251 252 okforcmp[TSTRING] = true 253 254 var i int 255 for i = 0; i < len(okfor); i++ { 256 okfor[i] = okfornone[:] 257 } 258 259 // binary 260 okfor[OADD] = okforadd[:] 261 262 okfor[OAND] = okforand[:] 263 okfor[OANDAND] = okforbool[:] 264 okfor[OANDNOT] = okforand[:] 265 okfor[ODIV] = okforarith[:] 266 okfor[OEQ] = okforeq[:] 267 okfor[OGE] = okforcmp[:] 268 okfor[OGT] = okforcmp[:] 269 okfor[OLE] = okforcmp[:] 270 okfor[OLT] = okforcmp[:] 271 okfor[OMOD] = okforand[:] 272 okfor[OHMUL] = okforarith[:] 273 okfor[OMUL] = okforarith[:] 274 okfor[ONE] = okforeq[:] 275 okfor[OOR] = okforand[:] 276 okfor[OOROR] = okforbool[:] 277 okfor[OSUB] = okforarith[:] 278 okfor[OXOR] = okforand[:] 279 okfor[OLSH] = okforand[:] 280 okfor[ORSH] = okforand[:] 281 282 // unary 283 okfor[OCOM] = okforand[:] 284 285 okfor[OMINUS] = okforarith[:] 286 okfor[ONOT] = okforbool[:] 287 okfor[OPLUS] = okforarith[:] 288 289 // special 290 okfor[OCAP] = okforcap[:] 291 292 okfor[OLEN] = okforlen[:] 293 294 // comparison 295 iscmp[OLT] = true 296 297 iscmp[OGT] = true 298 iscmp[OGE] = true 299 iscmp[OLE] = true 300 iscmp[OEQ] = true 301 iscmp[ONE] = true 302 303 Maxintval[TINT8].SetString("0x7f") 304 Minintval[TINT8].SetString("-0x80") 305 Maxintval[TINT16].SetString("0x7fff") 306 Minintval[TINT16].SetString("-0x8000") 307 Maxintval[TINT32].SetString("0x7fffffff") 308 Minintval[TINT32].SetString("-0x80000000") 309 Maxintval[TINT64].SetString("0x7fffffffffffffff") 310 Minintval[TINT64].SetString("-0x8000000000000000") 311 312 Maxintval[TUINT8].SetString("0xff") 313 Maxintval[TUINT16].SetString("0xffff") 314 Maxintval[TUINT32].SetString("0xffffffff") 315 Maxintval[TUINT64].SetString("0xffffffffffffffff") 316 317 // f is valid float if min < f < max. (min and max are not themselves valid.) 318 maxfltval[TFLOAT32].SetString("33554431p103") // 2^24-1 p (127-23) + 1/2 ulp 319 minfltval[TFLOAT32].SetString("-33554431p103") 320 maxfltval[TFLOAT64].SetString("18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp 321 minfltval[TFLOAT64].SetString("-18014398509481983p970") 322 323 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32] 324 minfltval[TCOMPLEX64] = minfltval[TFLOAT32] 325 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64] 326 minfltval[TCOMPLEX128] = minfltval[TFLOAT64] 327 328 // for walk to use in error messages 329 Types[TFUNC] = functype(nil, nil, nil) 330 331 // types used in front end 332 // types[TNIL] got set early in lexinit 333 Types[TIDEAL] = typ(TIDEAL) 334 335 Types[TINTER] = typ(TINTER) 336 337 // simple aliases 338 Simtype[TMAP] = Tptr 339 340 Simtype[TCHAN] = Tptr 341 Simtype[TFUNC] = Tptr 342 Simtype[TUNSAFEPTR] = Tptr 343 344 Array_array = int(Rnd(0, int64(Widthptr))) 345 Array_nel = int(Rnd(int64(Array_array)+int64(Widthptr), int64(Widthint))) 346 Array_cap = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthint))) 347 sizeof_Array = int(Rnd(int64(Array_cap)+int64(Widthint), int64(Widthptr))) 348 349 // string is same as slice wo the cap 350 sizeof_String = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthptr))) 351 352 dowidth(Types[TSTRING]) 353 dowidth(idealstring) 354 355 itable = typPtr(Types[TUINT8]) 356 } 357 358 func lexinit1() { 359 // t = interface { Error() string } 360 361 rcvr := typ(TSTRUCT) 362 rcvr.Funarg = true 363 field := newField() 364 field.Type = Ptrto(typ(TSTRUCT)) 365 rcvr.SetFields([]*Field{field}) 366 367 in := typ(TSTRUCT) 368 in.Funarg = true 369 370 out := typ(TSTRUCT) 371 out.Funarg = true 372 field = newField() 373 field.Type = Types[TSTRING] 374 out.SetFields([]*Field{field}) 375 376 f := typ(TFUNC) 377 *f.RecvsP() = rcvr 378 *f.ResultsP() = out 379 *f.ParamsP() = in 380 381 t := typ(TINTER) 382 field = newField() 383 field.Sym = Lookup("Error") 384 field.Type = f 385 t.SetFields([]*Field{field}) 386 387 // error type 388 s := Pkglookup("error", builtinpkg) 389 errortype = t 390 errortype.Sym = s 391 s.Def = typenod(errortype) 392 393 // byte alias 394 s = Pkglookup("byte", builtinpkg) 395 bytetype = typ(TUINT8) 396 bytetype.Sym = s 397 s.Def = typenod(bytetype) 398 s.Def.Name = new(Name) 399 400 // rune alias 401 s = Pkglookup("rune", builtinpkg) 402 runetype = typ(TINT32) 403 runetype.Sym = s 404 s.Def = typenod(runetype) 405 s.Def.Name = new(Name) 406 407 // backend-dependent builtin types (e.g. int). 408 for _, s := range typedefs { 409 s1 := Pkglookup(s.name, builtinpkg) 410 411 sameas := s.sameas32 412 if *s.width == 8 { 413 sameas = s.sameas64 414 } 415 416 Simtype[s.etype] = sameas 417 minfltval[s.etype] = minfltval[sameas] 418 maxfltval[s.etype] = maxfltval[sameas] 419 Minintval[s.etype] = Minintval[sameas] 420 Maxintval[s.etype] = Maxintval[sameas] 421 422 t := typ(s.etype) 423 t.Sym = s1 424 Types[s.etype] = t 425 s1.Def = typenod(t) 426 s1.Def.Name = new(Name) 427 s1.Origpkg = builtinpkg 428 429 dowidth(t) 430 } 431 } 432 433 // finishUniverse makes the universe block visible within the current package. 434 func finishUniverse() { 435 // Operationally, this is similar to a dot import of builtinpkg, except 436 // that we silently skip symbols that are already declared in the 437 // package block rather than emitting a redeclared symbol error. 438 439 for _, s := range builtinpkg.Syms { 440 if s.Def == nil || (s.Name == "any" && Debug['A'] == 0) { 441 continue 442 } 443 s1 := Lookup(s.Name) 444 if s1.Def != nil { 445 continue 446 } 447 448 s1.Def = s.Def 449 s1.Block = s.Block 450 } 451 452 nodfp = Nod(ONAME, nil, nil) 453 nodfp.Type = Types[TINT32] 454 nodfp.Xoffset = 0 455 nodfp.Class = PPARAM 456 nodfp.Sym = Lookup(".fp") 457 }