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