github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/iface.go (about)

     1  // Copyright 2014 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 runtime
     6  
     7  import (
     8  	"runtime/internal/atomic"
     9  	"runtime/internal/sys"
    10  	"unsafe"
    11  )
    12  
    13  const itabInitSize = 512
    14  
    15  var (
    16  	itabLock      mutex                               // lock for accessing itab table
    17  	itabTable     = &itabTableInit                    // pointer to current table
    18  	itabTableInit = itabTableType{size: itabInitSize} // starter table
    19  )
    20  
    21  //Note: change the formula in the mallocgc call in itabAdd if you change these fields.
    22  type itabTableType struct {
    23  	size    uintptr             // length of entries array. Always a power of 2.
    24  	count   uintptr             // current number of filled entries.
    25  	entries [itabInitSize]*itab // really [size] large
    26  }
    27  
    28  func itabHashFunc(inter *interfacetype, typ *_type) uintptr {
    29  	// compiler has provided some good hash codes for us.
    30  	return uintptr(inter.typ.hash ^ typ.hash)
    31  }
    32  
    33  func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
    34  	if len(inter.mhdr) == 0 {
    35  		throw("internal error - misuse of itab")
    36  	}
    37  
    38  	// easy case
    39  	if typ.tflag&tflagUncommon == 0 {
    40  		if canfail {
    41  			return nil
    42  		}
    43  		name := inter.typ.nameOff(inter.mhdr[0].name)
    44  		panic(&TypeAssertionError{"", typ.string(), inter.typ.string(), name.name()})
    45  	}
    46  
    47  	var m *itab
    48  
    49  	// First, look in the existing table to see if we can find the itab we need.
    50  	// This is by far the most common case, so do it without locks.
    51  	// Use atomic to ensure we see any previous writes done by the thread
    52  	// that updates the itabTable field (with atomic.Storep in itabAdd).
    53  	t := (*itabTableType)(atomic.Loadp(unsafe.Pointer(&itabTable)))
    54  	if m = t.find(inter, typ); m != nil {
    55  		goto finish
    56  	}
    57  
    58  	// Not found.  Grab the lock and try again.
    59  	lock(&itabLock)
    60  	if m = itabTable.find(inter, typ); m != nil {
    61  		unlock(&itabLock)
    62  		goto finish
    63  	}
    64  
    65  	// Entry doesn't exist yet. Make a new entry & add it.
    66  	m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
    67  	m.inter = inter
    68  	m._type = typ
    69  	m.init()
    70  	itabAdd(m)
    71  	unlock(&itabLock)
    72  finish:
    73  	if m.fun[0] != 0 {
    74  		return m
    75  	}
    76  	if canfail {
    77  		return nil
    78  	}
    79  	// this can only happen if the conversion
    80  	// was already done once using the , ok form
    81  	// and we have a cached negative result.
    82  	// The cached result doesn't record which
    83  	// interface function was missing, so initialize
    84  	// the itab again to get the missing function name.
    85  	panic(&TypeAssertionError{concreteString: typ.string(), assertedString: inter.typ.string(), missingMethod: m.init()})
    86  }
    87  
    88  // find finds the given interface/type pair in t.
    89  // Returns nil if the given interface/type pair isn't present.
    90  func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
    91  	// Implemented using quadratic probing.
    92  	// Probe sequence is h(i) = h0 + i*(i+1)/2 mod 2^k.
    93  	// We're guaranteed to hit all table entries using this probe sequence.
    94  	mask := t.size - 1
    95  	h := itabHashFunc(inter, typ) & mask
    96  	for i := uintptr(1); ; i++ {
    97  		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
    98  		// Use atomic read here so if we see m != nil, we also see
    99  		// the initializations of the fields of m.
   100  		// m := *p
   101  		m := (*itab)(atomic.Loadp(unsafe.Pointer(p)))
   102  		if m == nil {
   103  			return nil
   104  		}
   105  		if m.inter == inter && m._type == typ {
   106  			return m
   107  		}
   108  		h += i
   109  		h &= mask
   110  	}
   111  }
   112  
   113  // itabAdd adds the given itab to the itab hash table.
   114  // itabLock must be held.
   115  func itabAdd(m *itab) {
   116  	// Bugs can lead to calling this while mallocing is set,
   117  	// typically because this is called while panicing.
   118  	// Crash reliably, rather than only when we need to grow
   119  	// the hash table.
   120  	if getg().m.mallocing != 0 {
   121  		throw("malloc deadlock")
   122  	}
   123  
   124  	t := itabTable
   125  	if t.count >= 3*(t.size/4) { // 75% load factor
   126  		// Grow hash table.
   127  		// t2 = new(itabTableType) + some additional entries
   128  		// We lie and tell malloc we want pointer-free memory because
   129  		// all the pointed-to values are not in the heap.
   130  		t2 := (*itabTableType)(mallocgc((2+2*t.size)*sys.PtrSize, nil, true))
   131  		t2.size = t.size * 2
   132  
   133  		// Copy over entries.
   134  		// Note: while copying, other threads may look for an itab and
   135  		// fail to find it. That's ok, they will then try to get the itab lock
   136  		// and as a consequence wait until this copying is complete.
   137  		iterate_itabs(t2.add)
   138  		if t2.count != t.count {
   139  			throw("mismatched count during itab table copy")
   140  		}
   141  		// Publish new hash table. Use an atomic write: see comment in getitab.
   142  		atomicstorep(unsafe.Pointer(&itabTable), unsafe.Pointer(t2))
   143  		// Adopt the new table as our own.
   144  		t = itabTable
   145  		// Note: the old table can be GC'ed here.
   146  	}
   147  	t.add(m)
   148  }
   149  
   150  // add adds the given itab to itab table t.
   151  // itabLock must be held.
   152  func (t *itabTableType) add(m *itab) {
   153  	// See comment in find about the probe sequence.
   154  	// Insert new itab in the first empty spot in the probe sequence.
   155  	mask := t.size - 1
   156  	h := itabHashFunc(m.inter, m._type) & mask
   157  	for i := uintptr(1); ; i++ {
   158  		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
   159  		m2 := *p
   160  		if m2 == m {
   161  			// A given itab may be used in more than one module
   162  			// and thanks to the way global symbol resolution works, the
   163  			// pointed-to itab may already have been inserted into the
   164  			// global 'hash'.
   165  			return
   166  		}
   167  		if m2 == nil {
   168  			// Use atomic write here so if a reader sees m, it also
   169  			// sees the correctly initialized fields of m.
   170  			// NoWB is ok because m is not in heap memory.
   171  			// *p = m
   172  			atomic.StorepNoWB(unsafe.Pointer(p), unsafe.Pointer(m))
   173  			t.count++
   174  			return
   175  		}
   176  		h += i
   177  		h &= mask
   178  	}
   179  }
   180  
   181  // init fills in the m.fun array with all the code pointers for
   182  // the m.inter/m._type pair. If the type does not implement the interface,
   183  // it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
   184  // It is ok to call this multiple times on the same m, even concurrently.
   185  func (m *itab) init() string {
   186  	inter := m.inter
   187  	typ := m._type
   188  	x := typ.uncommon()
   189  
   190  	// both inter and typ have method sorted by name,
   191  	// and interface names are unique,
   192  	// so can iterate over both in lock step;
   193  	// the loop is O(ni+nt) not O(ni*nt).
   194  	ni := len(inter.mhdr)
   195  	nt := int(x.mcount)
   196  	xmhdr := (*[1 << 16]method)(add(unsafe.Pointer(x), uintptr(x.moff)))[:nt:nt]
   197  	j := 0
   198  imethods:
   199  	for k := 0; k < ni; k++ {
   200  		i := &inter.mhdr[k]
   201  		itype := inter.typ.typeOff(i.ityp)
   202  		name := inter.typ.nameOff(i.name)
   203  		iname := name.name()
   204  		ipkg := name.pkgPath()
   205  		if ipkg == "" {
   206  			ipkg = inter.pkgpath.name()
   207  		}
   208  		for ; j < nt; j++ {
   209  			t := &xmhdr[j]
   210  			tname := typ.nameOff(t.name)
   211  			if typ.typeOff(t.mtyp) == itype && tname.name() == iname {
   212  				pkgPath := tname.pkgPath()
   213  				if pkgPath == "" {
   214  					pkgPath = typ.nameOff(x.pkgpath).name()
   215  				}
   216  				if tname.isExported() || pkgPath == ipkg {
   217  					if m != nil {
   218  						ifn := typ.textOff(t.ifn)
   219  						*(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[0]), uintptr(k)*sys.PtrSize)) = ifn
   220  					}
   221  					continue imethods
   222  				}
   223  			}
   224  		}
   225  		// didn't find method
   226  		m.fun[0] = 0
   227  		return iname
   228  	}
   229  	m.hash = typ.hash
   230  	return ""
   231  }
   232  
   233  func itabsinit() {
   234  	lock(&itabLock)
   235  	for _, md := range activeModules() {
   236  		for _, i := range md.itablinks {
   237  			itabAdd(i)
   238  		}
   239  	}
   240  	unlock(&itabLock)
   241  }
   242  
   243  // panicdottypeE is called when doing an e.(T) conversion and the conversion fails.
   244  // have = the dynamic type we have.
   245  // want = the static type we're trying to convert to.
   246  // iface = the static type we're converting from.
   247  func panicdottypeE(have, want, iface *_type) {
   248  	haveString := ""
   249  	if have != nil {
   250  		haveString = have.string()
   251  	}
   252  	panic(&TypeAssertionError{iface.string(), haveString, want.string(), ""})
   253  }
   254  
   255  // panicdottypeI is called when doing an i.(T) conversion and the conversion fails.
   256  // Same args as panicdottypeE, but "have" is the dynamic itab we have.
   257  func panicdottypeI(have *itab, want, iface *_type) {
   258  	var t *_type
   259  	if have != nil {
   260  		t = have._type
   261  	}
   262  	panicdottypeE(t, want, iface)
   263  }
   264  
   265  // panicnildottype is called when doing a i.(T) conversion and the interface i is nil.
   266  // want = the static type we're trying to convert to.
   267  func panicnildottype(want *_type) {
   268  	panic(&TypeAssertionError{"", "", want.string(), ""})
   269  	// TODO: Add the static type we're converting from as well.
   270  	// It might generate a better error message.
   271  	// Just to match other nil conversion errors, we don't for now.
   272  }
   273  
   274  // The conv and assert functions below do very similar things.
   275  // The convXXX functions are guaranteed by the compiler to succeed.
   276  // The assertXXX functions may fail (either panicking or returning false,
   277  // depending on whether they are 1-result or 2-result).
   278  // The convXXX functions succeed on a nil input, whereas the assertXXX
   279  // functions fail on a nil input.
   280  
   281  func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
   282  	if raceenabled {
   283  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E))
   284  	}
   285  	if msanenabled {
   286  		msanread(elem, t.size)
   287  	}
   288  	x := mallocgc(t.size, t, true)
   289  	// TODO: We allocate a zeroed object only to overwrite it with actual data.
   290  	// Figure out how to avoid zeroing. Also below in convT2Eslice, convT2I, convT2Islice.
   291  	typedmemmove(t, x, elem)
   292  	e._type = t
   293  	e.data = x
   294  	return
   295  }
   296  
   297  func convT2E16(t *_type, elem unsafe.Pointer) (e eface) {
   298  	if raceenabled {
   299  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E16))
   300  	}
   301  	if msanenabled {
   302  		msanread(elem, t.size)
   303  	}
   304  	var x unsafe.Pointer
   305  	if *(*uint16)(elem) == 0 {
   306  		x = unsafe.Pointer(&zeroVal[0])
   307  	} else {
   308  		x = mallocgc(2, t, false)
   309  		*(*uint16)(x) = *(*uint16)(elem)
   310  	}
   311  	e._type = t
   312  	e.data = x
   313  	return
   314  }
   315  
   316  func convT2E32(t *_type, elem unsafe.Pointer) (e eface) {
   317  	if raceenabled {
   318  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E32))
   319  	}
   320  	if msanenabled {
   321  		msanread(elem, t.size)
   322  	}
   323  	var x unsafe.Pointer
   324  	if *(*uint32)(elem) == 0 {
   325  		x = unsafe.Pointer(&zeroVal[0])
   326  	} else {
   327  		x = mallocgc(4, t, false)
   328  		*(*uint32)(x) = *(*uint32)(elem)
   329  	}
   330  	e._type = t
   331  	e.data = x
   332  	return
   333  }
   334  
   335  func convT2E64(t *_type, elem unsafe.Pointer) (e eface) {
   336  	if raceenabled {
   337  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E64))
   338  	}
   339  	if msanenabled {
   340  		msanread(elem, t.size)
   341  	}
   342  	var x unsafe.Pointer
   343  	if *(*uint64)(elem) == 0 {
   344  		x = unsafe.Pointer(&zeroVal[0])
   345  	} else {
   346  		x = mallocgc(8, t, false)
   347  		*(*uint64)(x) = *(*uint64)(elem)
   348  	}
   349  	e._type = t
   350  	e.data = x
   351  	return
   352  }
   353  
   354  func convT2Estring(t *_type, elem unsafe.Pointer) (e eface) {
   355  	if raceenabled {
   356  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Estring))
   357  	}
   358  	if msanenabled {
   359  		msanread(elem, t.size)
   360  	}
   361  	var x unsafe.Pointer
   362  	if *(*string)(elem) == "" {
   363  		x = unsafe.Pointer(&zeroVal[0])
   364  	} else {
   365  		x = mallocgc(t.size, t, true)
   366  		*(*string)(x) = *(*string)(elem)
   367  	}
   368  	e._type = t
   369  	e.data = x
   370  	return
   371  }
   372  
   373  func convT2Eslice(t *_type, elem unsafe.Pointer) (e eface) {
   374  	if raceenabled {
   375  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Eslice))
   376  	}
   377  	if msanenabled {
   378  		msanread(elem, t.size)
   379  	}
   380  	var x unsafe.Pointer
   381  	if v := *(*slice)(elem); uintptr(v.array) == 0 {
   382  		x = unsafe.Pointer(&zeroVal[0])
   383  	} else {
   384  		x = mallocgc(t.size, t, true)
   385  		*(*slice)(x) = *(*slice)(elem)
   386  	}
   387  	e._type = t
   388  	e.data = x
   389  	return
   390  }
   391  
   392  func convT2Enoptr(t *_type, elem unsafe.Pointer) (e eface) {
   393  	if raceenabled {
   394  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Enoptr))
   395  	}
   396  	if msanenabled {
   397  		msanread(elem, t.size)
   398  	}
   399  	x := mallocgc(t.size, t, false)
   400  	memmove(x, elem, t.size)
   401  	e._type = t
   402  	e.data = x
   403  	return
   404  }
   405  
   406  func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
   407  	t := tab._type
   408  	if raceenabled {
   409  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I))
   410  	}
   411  	if msanenabled {
   412  		msanread(elem, t.size)
   413  	}
   414  	x := mallocgc(t.size, t, true)
   415  	typedmemmove(t, x, elem)
   416  	i.tab = tab
   417  	i.data = x
   418  	return
   419  }
   420  
   421  func convT2I16(tab *itab, elem unsafe.Pointer) (i iface) {
   422  	t := tab._type
   423  	if raceenabled {
   424  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I16))
   425  	}
   426  	if msanenabled {
   427  		msanread(elem, t.size)
   428  	}
   429  	var x unsafe.Pointer
   430  	if *(*uint16)(elem) == 0 {
   431  		x = unsafe.Pointer(&zeroVal[0])
   432  	} else {
   433  		x = mallocgc(2, t, false)
   434  		*(*uint16)(x) = *(*uint16)(elem)
   435  	}
   436  	i.tab = tab
   437  	i.data = x
   438  	return
   439  }
   440  
   441  func convT2I32(tab *itab, elem unsafe.Pointer) (i iface) {
   442  	t := tab._type
   443  	if raceenabled {
   444  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I32))
   445  	}
   446  	if msanenabled {
   447  		msanread(elem, t.size)
   448  	}
   449  	var x unsafe.Pointer
   450  	if *(*uint32)(elem) == 0 {
   451  		x = unsafe.Pointer(&zeroVal[0])
   452  	} else {
   453  		x = mallocgc(4, t, false)
   454  		*(*uint32)(x) = *(*uint32)(elem)
   455  	}
   456  	i.tab = tab
   457  	i.data = x
   458  	return
   459  }
   460  
   461  func convT2I64(tab *itab, elem unsafe.Pointer) (i iface) {
   462  	t := tab._type
   463  	if raceenabled {
   464  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I64))
   465  	}
   466  	if msanenabled {
   467  		msanread(elem, t.size)
   468  	}
   469  	var x unsafe.Pointer
   470  	if *(*uint64)(elem) == 0 {
   471  		x = unsafe.Pointer(&zeroVal[0])
   472  	} else {
   473  		x = mallocgc(8, t, false)
   474  		*(*uint64)(x) = *(*uint64)(elem)
   475  	}
   476  	i.tab = tab
   477  	i.data = x
   478  	return
   479  }
   480  
   481  func convT2Istring(tab *itab, elem unsafe.Pointer) (i iface) {
   482  	t := tab._type
   483  	if raceenabled {
   484  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Istring))
   485  	}
   486  	if msanenabled {
   487  		msanread(elem, t.size)
   488  	}
   489  	var x unsafe.Pointer
   490  	if *(*string)(elem) == "" {
   491  		x = unsafe.Pointer(&zeroVal[0])
   492  	} else {
   493  		x = mallocgc(t.size, t, true)
   494  		*(*string)(x) = *(*string)(elem)
   495  	}
   496  	i.tab = tab
   497  	i.data = x
   498  	return
   499  }
   500  
   501  func convT2Islice(tab *itab, elem unsafe.Pointer) (i iface) {
   502  	t := tab._type
   503  	if raceenabled {
   504  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Islice))
   505  	}
   506  	if msanenabled {
   507  		msanread(elem, t.size)
   508  	}
   509  	var x unsafe.Pointer
   510  	if v := *(*slice)(elem); uintptr(v.array) == 0 {
   511  		x = unsafe.Pointer(&zeroVal[0])
   512  	} else {
   513  		x = mallocgc(t.size, t, true)
   514  		*(*slice)(x) = *(*slice)(elem)
   515  	}
   516  	i.tab = tab
   517  	i.data = x
   518  	return
   519  }
   520  
   521  func convT2Inoptr(tab *itab, elem unsafe.Pointer) (i iface) {
   522  	t := tab._type
   523  	if raceenabled {
   524  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Inoptr))
   525  	}
   526  	if msanenabled {
   527  		msanread(elem, t.size)
   528  	}
   529  	x := mallocgc(t.size, t, false)
   530  	memmove(x, elem, t.size)
   531  	i.tab = tab
   532  	i.data = x
   533  	return
   534  }
   535  
   536  func convI2I(inter *interfacetype, i iface) (r iface) {
   537  	tab := i.tab
   538  	if tab == nil {
   539  		return
   540  	}
   541  	if tab.inter == inter {
   542  		r.tab = tab
   543  		r.data = i.data
   544  		return
   545  	}
   546  	r.tab = getitab(inter, tab._type, false)
   547  	r.data = i.data
   548  	return
   549  }
   550  
   551  func assertI2I(inter *interfacetype, i iface) (r iface) {
   552  	tab := i.tab
   553  	if tab == nil {
   554  		// explicit conversions require non-nil interface value.
   555  		panic(&TypeAssertionError{"", "", inter.typ.string(), ""})
   556  	}
   557  	if tab.inter == inter {
   558  		r.tab = tab
   559  		r.data = i.data
   560  		return
   561  	}
   562  	r.tab = getitab(inter, tab._type, false)
   563  	r.data = i.data
   564  	return
   565  }
   566  
   567  func assertI2I2(inter *interfacetype, i iface) (r iface, b bool) {
   568  	tab := i.tab
   569  	if tab == nil {
   570  		return
   571  	}
   572  	if tab.inter != inter {
   573  		tab = getitab(inter, tab._type, true)
   574  		if tab == nil {
   575  			return
   576  		}
   577  	}
   578  	r.tab = tab
   579  	r.data = i.data
   580  	b = true
   581  	return
   582  }
   583  
   584  func assertE2I(inter *interfacetype, e eface) (r iface) {
   585  	t := e._type
   586  	if t == nil {
   587  		// explicit conversions require non-nil interface value.
   588  		panic(&TypeAssertionError{"", "", inter.typ.string(), ""})
   589  	}
   590  	r.tab = getitab(inter, t, false)
   591  	r.data = e.data
   592  	return
   593  }
   594  
   595  func assertE2I2(inter *interfacetype, e eface) (r iface, b bool) {
   596  	t := e._type
   597  	if t == nil {
   598  		return
   599  	}
   600  	tab := getitab(inter, t, true)
   601  	if tab == nil {
   602  		return
   603  	}
   604  	r.tab = tab
   605  	r.data = e.data
   606  	b = true
   607  	return
   608  }
   609  
   610  //go:linkname reflect_ifaceE2I reflect.ifaceE2I
   611  func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
   612  	*dst = assertE2I(inter, e)
   613  }
   614  
   615  func iterate_itabs(fn func(*itab)) {
   616  	// Note: only runs during stop the world or with itabLock held,
   617  	// so no other locks/atomics needed.
   618  	t := itabTable
   619  	for i := uintptr(0); i < t.size; i++ {
   620  		m := *(**itab)(add(unsafe.Pointer(&t.entries), i*sys.PtrSize))
   621  		if m != nil {
   622  			fn(m)
   623  		}
   624  	}
   625  }
   626  
   627  // staticbytes is used to avoid convT2E for byte-sized values.
   628  var staticbytes = [...]byte{
   629  	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   630  	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   631  	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   632  	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   633  	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
   634  	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   635  	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   636  	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   637  	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   638  	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
   639  	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
   640  	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
   641  	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   642  	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
   643  	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   644  	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
   645  	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
   646  	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
   647  	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
   648  	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
   649  	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
   650  	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
   651  	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
   652  	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
   653  	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
   654  	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
   655  	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
   656  	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
   657  	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
   658  	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   659  	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   660  	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
   661  }