Home | History | Annotate | Download | only in gc
      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 }
    466