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