github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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  }
    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  	// We create separate byte and rune types for better error messages
   402  	// rather than just creating type alias *Sym's for the uint8 and
   403  	// int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false.
   404  	// TODO(gri) Should we get rid of this special case (at the cost
   405  	// of less informative error messages involving bytes and runes)?
   406  	// (Alternatively, we could introduce an OTALIAS node representing
   407  	// type aliases, albeit at the cost of having to deal with it everywhere).
   408  
   409  	// byte alias
   410  	s = Pkglookup("byte", builtinpkg)
   411  	bytetype = typ(TUINT8)
   412  	bytetype.Sym = s
   413  	s.Def = typenod(bytetype)
   414  	s.Def.Name = new(Name)
   415  
   416  	// rune alias
   417  	s = Pkglookup("rune", builtinpkg)
   418  	runetype = typ(TINT32)
   419  	runetype.Sym = s
   420  	s.Def = typenod(runetype)
   421  	s.Def.Name = new(Name)
   422  
   423  	// backend-dependent builtin types (e.g. int).
   424  	for _, s := range typedefs {
   425  		s1 := Pkglookup(s.name, builtinpkg)
   426  
   427  		sameas := s.sameas32
   428  		if *s.width == 8 {
   429  			sameas = s.sameas64
   430  		}
   431  
   432  		simtype[s.etype] = sameas
   433  		minfltval[s.etype] = minfltval[sameas]
   434  		maxfltval[s.etype] = maxfltval[sameas]
   435  		minintval[s.etype] = minintval[sameas]
   436  		maxintval[s.etype] = maxintval[sameas]
   437  
   438  		t := typ(s.etype)
   439  		t.Sym = s1
   440  		Types[s.etype] = t
   441  		s1.Def = typenod(t)
   442  		s1.Def.Name = new(Name)
   443  		s1.Origpkg = builtinpkg
   444  
   445  		dowidth(t)
   446  	}
   447  }
   448  
   449  // finishUniverse makes the universe block visible within the current package.
   450  func finishUniverse() {
   451  	// Operationally, this is similar to a dot import of builtinpkg, except
   452  	// that we silently skip symbols that are already declared in the
   453  	// package block rather than emitting a redeclared symbol error.
   454  
   455  	for _, s := range builtinpkg.Syms {
   456  		if s.Def == nil {
   457  			continue
   458  		}
   459  		s1 := lookup(s.Name)
   460  		if s1.Def != nil {
   461  			continue
   462  		}
   463  
   464  		s1.Def = s.Def
   465  		s1.Block = s.Block
   466  	}
   467  
   468  	nodfp = nod(ONAME, nil, nil)
   469  	nodfp.Type = Types[TINT32]
   470  	nodfp.Xoffset = 0
   471  	nodfp.Class = PPARAM
   472  	nodfp.Sym = lookup(".fp")
   473  }