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  }