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