github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 // initialize okfor 204 for et := types.EType(0); et < NTYPE; et++ { 205 if isInt[et] || et == TIDEAL { 206 okforeq[et] = true 207 okforcmp[et] = true 208 okforarith[et] = true 209 okforadd[et] = true 210 okforand[et] = true 211 okforconst[et] = true 212 issimple[et] = true 213 minintval[et] = new(Mpint) 214 maxintval[et] = new(Mpint) 215 } 216 217 if isFloat[et] { 218 okforeq[et] = true 219 okforcmp[et] = true 220 okforadd[et] = true 221 okforarith[et] = true 222 okforconst[et] = true 223 issimple[et] = true 224 minfltval[et] = newMpflt() 225 maxfltval[et] = newMpflt() 226 } 227 228 if isComplex[et] { 229 okforeq[et] = true 230 okforadd[et] = true 231 okforarith[et] = true 232 okforconst[et] = true 233 issimple[et] = true 234 } 235 } 236 237 issimple[TBOOL] = true 238 239 okforadd[TSTRING] = true 240 241 okforbool[TBOOL] = true 242 243 okforcap[TARRAY] = true 244 okforcap[TCHAN] = true 245 okforcap[TSLICE] = true 246 247 okforconst[TBOOL] = true 248 okforconst[TSTRING] = true 249 250 okforlen[TARRAY] = true 251 okforlen[TCHAN] = true 252 okforlen[TMAP] = true 253 okforlen[TSLICE] = true 254 okforlen[TSTRING] = true 255 256 okforeq[TPTR] = true 257 okforeq[TUNSAFEPTR] = true 258 okforeq[TINTER] = true 259 okforeq[TCHAN] = true 260 okforeq[TSTRING] = true 261 okforeq[TBOOL] = true 262 okforeq[TMAP] = true // nil only; refined in typecheck 263 okforeq[TFUNC] = true // nil only; refined in typecheck 264 okforeq[TSLICE] = true // nil only; refined in typecheck 265 okforeq[TARRAY] = true // only if element type is comparable; refined in typecheck 266 okforeq[TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck 267 268 okforcmp[TSTRING] = true 269 270 var i int 271 for i = 0; i < len(okfor); i++ { 272 okfor[i] = okfornone[:] 273 } 274 275 // binary 276 okfor[OADD] = okforadd[:] 277 okfor[OAND] = okforand[:] 278 okfor[OANDAND] = okforbool[:] 279 okfor[OANDNOT] = okforand[:] 280 okfor[ODIV] = okforarith[:] 281 okfor[OEQ] = okforeq[:] 282 okfor[OGE] = okforcmp[:] 283 okfor[OGT] = okforcmp[:] 284 okfor[OLE] = okforcmp[:] 285 okfor[OLT] = okforcmp[:] 286 okfor[OMOD] = okforand[:] 287 okfor[OMUL] = okforarith[:] 288 okfor[ONE] = okforeq[:] 289 okfor[OOR] = okforand[:] 290 okfor[OOROR] = okforbool[:] 291 okfor[OSUB] = okforarith[:] 292 okfor[OXOR] = okforand[:] 293 okfor[OLSH] = okforand[:] 294 okfor[ORSH] = okforand[:] 295 296 // unary 297 okfor[OBITNOT] = okforand[:] 298 okfor[ONEG] = okforarith[:] 299 okfor[ONOT] = okforbool[:] 300 okfor[OPLUS] = okforarith[:] 301 302 // special 303 okfor[OCAP] = okforcap[:] 304 okfor[OLEN] = okforlen[:] 305 306 // comparison 307 iscmp[OLT] = true 308 iscmp[OGT] = true 309 iscmp[OGE] = true 310 iscmp[OLE] = true 311 iscmp[OEQ] = true 312 iscmp[ONE] = true 313 314 maxintval[TINT8].SetString("0x7f") 315 minintval[TINT8].SetString("-0x80") 316 maxintval[TINT16].SetString("0x7fff") 317 minintval[TINT16].SetString("-0x8000") 318 maxintval[TINT32].SetString("0x7fffffff") 319 minintval[TINT32].SetString("-0x80000000") 320 maxintval[TINT64].SetString("0x7fffffffffffffff") 321 minintval[TINT64].SetString("-0x8000000000000000") 322 323 maxintval[TUINT8].SetString("0xff") 324 maxintval[TUINT16].SetString("0xffff") 325 maxintval[TUINT32].SetString("0xffffffff") 326 maxintval[TUINT64].SetString("0xffffffffffffffff") 327 328 // f is valid float if min < f < max. (min and max are not themselves valid.) 329 maxfltval[TFLOAT32].SetString("33554431p103") // 2^24-1 p (127-23) + 1/2 ulp 330 minfltval[TFLOAT32].SetString("-33554431p103") 331 maxfltval[TFLOAT64].SetString("18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp 332 minfltval[TFLOAT64].SetString("-18014398509481983p970") 333 334 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32] 335 minfltval[TCOMPLEX64] = minfltval[TFLOAT32] 336 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64] 337 minfltval[TCOMPLEX128] = minfltval[TFLOAT64] 338 339 // for walk to use in error messages 340 types.Types[TFUNC] = functype(nil, nil, nil) 341 342 // types used in front end 343 // types.Types[TNIL] got set early in lexinit 344 types.Types[TIDEAL] = types.New(TIDEAL) 345 346 types.Types[TINTER] = types.New(TINTER) 347 348 // simple aliases 349 simtype[TMAP] = TPTR 350 simtype[TCHAN] = TPTR 351 simtype[TFUNC] = TPTR 352 simtype[TUNSAFEPTR] = TPTR 353 354 array_array = int(Rnd(0, int64(Widthptr))) 355 array_nel = int(Rnd(int64(array_array)+int64(Widthptr), int64(Widthptr))) 356 array_cap = int(Rnd(int64(array_nel)+int64(Widthptr), int64(Widthptr))) 357 sizeof_Array = int(Rnd(int64(array_cap)+int64(Widthptr), int64(Widthptr))) 358 359 // string is same as slice wo the cap 360 sizeof_String = int(Rnd(int64(array_nel)+int64(Widthptr), int64(Widthptr))) 361 362 dowidth(types.Types[TSTRING]) 363 dowidth(types.Idealstring) 364 365 itable = types.NewPtr(types.Types[TUINT8]) 366 } 367 368 func makeErrorInterface() *types.Type { 369 field := types.NewField() 370 field.Type = types.Types[TSTRING] 371 f := functypefield(fakeRecvField(), nil, []*types.Field{field}) 372 373 field = types.NewField() 374 field.Sym = lookup("Error") 375 field.Type = f 376 377 t := types.New(TINTER) 378 t.SetInterface([]*types.Field{field}) 379 return t 380 } 381 382 func lexinit1() { 383 // error type 384 s := builtinpkg.Lookup("error") 385 types.Errortype = makeErrorInterface() 386 types.Errortype.Sym = s 387 types.Errortype.Orig = makeErrorInterface() 388 s.Def = asTypesNode(typenod(types.Errortype)) 389 dowidth(types.Errortype) 390 391 // We create separate byte and rune types for better error messages 392 // rather than just creating type alias *types.Sym's for the uint8 and 393 // int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false. 394 // TODO(gri) Should we get rid of this special case (at the cost 395 // of less informative error messages involving bytes and runes)? 396 // (Alternatively, we could introduce an OTALIAS node representing 397 // type aliases, albeit at the cost of having to deal with it everywhere). 398 399 // byte alias 400 s = builtinpkg.Lookup("byte") 401 types.Bytetype = types.New(TUINT8) 402 types.Bytetype.Sym = s 403 s.Def = asTypesNode(typenod(types.Bytetype)) 404 asNode(s.Def).Name = new(Name) 405 dowidth(types.Bytetype) 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 dowidth(types.Runetype) 414 415 // backend-dependent builtin types (e.g. int). 416 for _, s := range typedefs { 417 s1 := builtinpkg.Lookup(s.name) 418 419 sameas := s.sameas32 420 if Widthptr == 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 := types.New(s.etype) 431 t.Sym = s1 432 types.Types[s.etype] = t 433 s1.Def = asTypesNode(typenod(t)) 434 asNode(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 = newname(lookup(".fp")) 461 nodfp.Type = types.Types[TINT32] 462 nodfp.SetClass(PPARAM) 463 nodfp.Name.SetUsed(true) 464 }