golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/go/ssa/interp/value.go (about)

     1  // Copyright 2013 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 interp
     6  
     7  // Values
     8  //
     9  // All interpreter values are "boxed" in the empty interface, value.
    10  // The range of possible dynamic types within value are:
    11  //
    12  // - bool
    13  // - numbers (all built-in int/float/complex types are distinguished)
    14  // - string
    15  // - map[value]value --- maps for which  usesBuiltinMap(keyType)
    16  //   *hashmap        --- maps for which !usesBuiltinMap(keyType)
    17  // - chan value
    18  // - []value --- slices
    19  // - iface --- interfaces.
    20  // - structure --- structs.  Fields are ordered and accessed by numeric indices.
    21  // - array --- arrays.
    22  // - *value --- pointers.  Careful: *value is a distinct type from *array etc.
    23  // - *ssa.Function \
    24  //   *ssa.Builtin   } --- functions.  A nil 'func' is always of type *ssa.Function.
    25  //   *closure      /
    26  // - tuple --- as returned by Return, Next, "value,ok" modes, etc.
    27  // - iter --- iterators from 'range' over map or string.
    28  // - bad --- a poison pill for locals that have gone out of scope.
    29  // - rtype -- the interpreter's concrete implementation of reflect.Type
    30  // - **deferred -- the address of a frame's defer stack for a Defer._Stack.
    31  //
    32  // Note that nil is not on this list.
    33  //
    34  // Pay close attention to whether or not the dynamic type is a pointer.
    35  // The compiler cannot help you since value is an empty interface.
    36  
    37  import (
    38  	"bytes"
    39  	"fmt"
    40  	"go/types"
    41  	"io"
    42  	"reflect"
    43  	"strings"
    44  	"sync"
    45  	"unsafe"
    46  
    47  	"golang.org/x/tools/go/ssa"
    48  	"golang.org/x/tools/go/types/typeutil"
    49  	"golang.org/x/tools/internal/aliases"
    50  )
    51  
    52  type value interface{}
    53  
    54  type tuple []value
    55  
    56  type array []value
    57  
    58  type iface struct {
    59  	t types.Type // never an "untyped" type
    60  	v value
    61  }
    62  
    63  type structure []value
    64  
    65  // For map, array, *array, slice, string or channel.
    66  type iter interface {
    67  	// next returns a Tuple (key, value, ok).
    68  	// key and value are unaliased, e.g. copies of the sequence element.
    69  	next() tuple
    70  }
    71  
    72  type closure struct {
    73  	Fn  *ssa.Function
    74  	Env []value
    75  }
    76  
    77  type bad struct{}
    78  
    79  type rtype struct {
    80  	t types.Type
    81  }
    82  
    83  // Hash functions and equivalence relation:
    84  
    85  // hashString computes the FNV hash of s.
    86  func hashString(s string) int {
    87  	var h uint32
    88  	for i := 0; i < len(s); i++ {
    89  		h ^= uint32(s[i])
    90  		h *= 16777619
    91  	}
    92  	return int(h)
    93  }
    94  
    95  var (
    96  	mu     sync.Mutex
    97  	hasher = typeutil.MakeHasher()
    98  )
    99  
   100  // hashType returns a hash for t such that
   101  // types.Identical(x, y) => hashType(x) == hashType(y).
   102  func hashType(t types.Type) int {
   103  	mu.Lock()
   104  	h := int(hasher.Hash(t))
   105  	mu.Unlock()
   106  	return h
   107  }
   108  
   109  // usesBuiltinMap returns true if the built-in hash function and
   110  // equivalence relation for type t are consistent with those of the
   111  // interpreter's representation of type t.  Such types are: all basic
   112  // types (bool, numbers, string), pointers and channels.
   113  //
   114  // usesBuiltinMap returns false for types that require a custom map
   115  // implementation: interfaces, arrays and structs.
   116  //
   117  // Panic ensues if t is an invalid map key type: function, map or slice.
   118  func usesBuiltinMap(t types.Type) bool {
   119  	switch t := t.(type) {
   120  	case *types.Basic, *types.Chan, *types.Pointer:
   121  		return true
   122  	case *types.Named, *aliases.Alias:
   123  		return usesBuiltinMap(t.Underlying())
   124  	case *types.Interface, *types.Array, *types.Struct:
   125  		return false
   126  	}
   127  	panic(fmt.Sprintf("invalid map key type: %T", t))
   128  }
   129  
   130  func (x array) eq(t types.Type, _y interface{}) bool {
   131  	y := _y.(array)
   132  	tElt := t.Underlying().(*types.Array).Elem()
   133  	for i, xi := range x {
   134  		if !equals(tElt, xi, y[i]) {
   135  			return false
   136  		}
   137  	}
   138  	return true
   139  }
   140  
   141  func (x array) hash(t types.Type) int {
   142  	h := 0
   143  	tElt := t.Underlying().(*types.Array).Elem()
   144  	for _, xi := range x {
   145  		h += hash(tElt, xi)
   146  	}
   147  	return h
   148  }
   149  
   150  func (x structure) eq(t types.Type, _y interface{}) bool {
   151  	y := _y.(structure)
   152  	tStruct := t.Underlying().(*types.Struct)
   153  	for i, n := 0, tStruct.NumFields(); i < n; i++ {
   154  		if f := tStruct.Field(i); !f.Anonymous() {
   155  			if !equals(f.Type(), x[i], y[i]) {
   156  				return false
   157  			}
   158  		}
   159  	}
   160  	return true
   161  }
   162  
   163  func (x structure) hash(t types.Type) int {
   164  	tStruct := t.Underlying().(*types.Struct)
   165  	h := 0
   166  	for i, n := 0, tStruct.NumFields(); i < n; i++ {
   167  		if f := tStruct.Field(i); !f.Anonymous() {
   168  			h += hash(f.Type(), x[i])
   169  		}
   170  	}
   171  	return h
   172  }
   173  
   174  // nil-tolerant variant of types.Identical.
   175  func sameType(x, y types.Type) bool {
   176  	if x == nil {
   177  		return y == nil
   178  	}
   179  	return y != nil && types.Identical(x, y)
   180  }
   181  
   182  func (x iface) eq(t types.Type, _y interface{}) bool {
   183  	y := _y.(iface)
   184  	return sameType(x.t, y.t) && (x.t == nil || equals(x.t, x.v, y.v))
   185  }
   186  
   187  func (x iface) hash(_ types.Type) int {
   188  	return hashType(x.t)*8581 + hash(x.t, x.v)
   189  }
   190  
   191  func (x rtype) hash(_ types.Type) int {
   192  	return hashType(x.t)
   193  }
   194  
   195  func (x rtype) eq(_ types.Type, y interface{}) bool {
   196  	return types.Identical(x.t, y.(rtype).t)
   197  }
   198  
   199  // equals returns true iff x and y are equal according to Go's
   200  // linguistic equivalence relation for type t.
   201  // In a well-typed program, the dynamic types of x and y are
   202  // guaranteed equal.
   203  func equals(t types.Type, x, y value) bool {
   204  	switch x := x.(type) {
   205  	case bool:
   206  		return x == y.(bool)
   207  	case int:
   208  		return x == y.(int)
   209  	case int8:
   210  		return x == y.(int8)
   211  	case int16:
   212  		return x == y.(int16)
   213  	case int32:
   214  		return x == y.(int32)
   215  	case int64:
   216  		return x == y.(int64)
   217  	case uint:
   218  		return x == y.(uint)
   219  	case uint8:
   220  		return x == y.(uint8)
   221  	case uint16:
   222  		return x == y.(uint16)
   223  	case uint32:
   224  		return x == y.(uint32)
   225  	case uint64:
   226  		return x == y.(uint64)
   227  	case uintptr:
   228  		return x == y.(uintptr)
   229  	case float32:
   230  		return x == y.(float32)
   231  	case float64:
   232  		return x == y.(float64)
   233  	case complex64:
   234  		return x == y.(complex64)
   235  	case complex128:
   236  		return x == y.(complex128)
   237  	case string:
   238  		return x == y.(string)
   239  	case *value:
   240  		return x == y.(*value)
   241  	case chan value:
   242  		return x == y.(chan value)
   243  	case structure:
   244  		return x.eq(t, y)
   245  	case array:
   246  		return x.eq(t, y)
   247  	case iface:
   248  		return x.eq(t, y)
   249  	case rtype:
   250  		return x.eq(t, y)
   251  	}
   252  
   253  	// Since map, func and slice don't support comparison, this
   254  	// case is only reachable if one of x or y is literally nil
   255  	// (handled in eqnil) or via interface{} values.
   256  	panic(fmt.Sprintf("comparing uncomparable type %s", t))
   257  }
   258  
   259  // Returns an integer hash of x such that equals(x, y) => hash(x) == hash(y).
   260  func hash(t types.Type, x value) int {
   261  	switch x := x.(type) {
   262  	case bool:
   263  		if x {
   264  			return 1
   265  		}
   266  		return 0
   267  	case int:
   268  		return x
   269  	case int8:
   270  		return int(x)
   271  	case int16:
   272  		return int(x)
   273  	case int32:
   274  		return int(x)
   275  	case int64:
   276  		return int(x)
   277  	case uint:
   278  		return int(x)
   279  	case uint8:
   280  		return int(x)
   281  	case uint16:
   282  		return int(x)
   283  	case uint32:
   284  		return int(x)
   285  	case uint64:
   286  		return int(x)
   287  	case uintptr:
   288  		return int(x)
   289  	case float32:
   290  		return int(x)
   291  	case float64:
   292  		return int(x)
   293  	case complex64:
   294  		return int(real(x))
   295  	case complex128:
   296  		return int(real(x))
   297  	case string:
   298  		return hashString(x)
   299  	case *value:
   300  		return int(uintptr(unsafe.Pointer(x)))
   301  	case chan value:
   302  		return int(uintptr(reflect.ValueOf(x).Pointer()))
   303  	case structure:
   304  		return x.hash(t)
   305  	case array:
   306  		return x.hash(t)
   307  	case iface:
   308  		return x.hash(t)
   309  	case rtype:
   310  		return x.hash(t)
   311  	}
   312  	panic(fmt.Sprintf("%T is unhashable", x))
   313  }
   314  
   315  // reflect.Value struct values don't have a fixed shape, since the
   316  // payload can be a scalar or an aggregate depending on the instance.
   317  // So store (and load) can't simply use recursion over the shape of the
   318  // rhs value, or the lhs, to copy the value; we need the static type
   319  // information.  (We can't make reflect.Value a new basic data type
   320  // because its "structness" is exposed to Go programs.)
   321  
   322  // load returns the value of type T in *addr.
   323  func load(T types.Type, addr *value) value {
   324  	switch T := T.Underlying().(type) {
   325  	case *types.Struct:
   326  		v := (*addr).(structure)
   327  		a := make(structure, len(v))
   328  		for i := range a {
   329  			a[i] = load(T.Field(i).Type(), &v[i])
   330  		}
   331  		return a
   332  	case *types.Array:
   333  		v := (*addr).(array)
   334  		a := make(array, len(v))
   335  		for i := range a {
   336  			a[i] = load(T.Elem(), &v[i])
   337  		}
   338  		return a
   339  	default:
   340  		return *addr
   341  	}
   342  }
   343  
   344  // store stores value v of type T into *addr.
   345  func store(T types.Type, addr *value, v value) {
   346  	switch T := T.Underlying().(type) {
   347  	case *types.Struct:
   348  		lhs := (*addr).(structure)
   349  		rhs := v.(structure)
   350  		for i := range lhs {
   351  			store(T.Field(i).Type(), &lhs[i], rhs[i])
   352  		}
   353  	case *types.Array:
   354  		lhs := (*addr).(array)
   355  		rhs := v.(array)
   356  		for i := range lhs {
   357  			store(T.Elem(), &lhs[i], rhs[i])
   358  		}
   359  	default:
   360  		*addr = v
   361  	}
   362  }
   363  
   364  // Prints in the style of built-in println.
   365  // (More or less; in gc println is actually a compiler intrinsic and
   366  // can distinguish println(1) from println(interface{}(1)).)
   367  func writeValue(buf *bytes.Buffer, v value) {
   368  	switch v := v.(type) {
   369  	case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, complex64, complex128, string:
   370  		fmt.Fprintf(buf, "%v", v)
   371  
   372  	case map[value]value:
   373  		buf.WriteString("map[")
   374  		sep := ""
   375  		for k, e := range v {
   376  			buf.WriteString(sep)
   377  			sep = " "
   378  			writeValue(buf, k)
   379  			buf.WriteString(":")
   380  			writeValue(buf, e)
   381  		}
   382  		buf.WriteString("]")
   383  
   384  	case *hashmap:
   385  		buf.WriteString("map[")
   386  		sep := " "
   387  		for _, e := range v.entries() {
   388  			for e != nil {
   389  				buf.WriteString(sep)
   390  				sep = " "
   391  				writeValue(buf, e.key)
   392  				buf.WriteString(":")
   393  				writeValue(buf, e.value)
   394  				e = e.next
   395  			}
   396  		}
   397  		buf.WriteString("]")
   398  
   399  	case chan value:
   400  		fmt.Fprintf(buf, "%v", v) // (an address)
   401  
   402  	case *value:
   403  		if v == nil {
   404  			buf.WriteString("<nil>")
   405  		} else {
   406  			fmt.Fprintf(buf, "%p", v)
   407  		}
   408  
   409  	case iface:
   410  		fmt.Fprintf(buf, "(%s, ", v.t)
   411  		writeValue(buf, v.v)
   412  		buf.WriteString(")")
   413  
   414  	case structure:
   415  		buf.WriteString("{")
   416  		for i, e := range v {
   417  			if i > 0 {
   418  				buf.WriteString(" ")
   419  			}
   420  			writeValue(buf, e)
   421  		}
   422  		buf.WriteString("}")
   423  
   424  	case array:
   425  		buf.WriteString("[")
   426  		for i, e := range v {
   427  			if i > 0 {
   428  				buf.WriteString(" ")
   429  			}
   430  			writeValue(buf, e)
   431  		}
   432  		buf.WriteString("]")
   433  
   434  	case []value:
   435  		buf.WriteString("[")
   436  		for i, e := range v {
   437  			if i > 0 {
   438  				buf.WriteString(" ")
   439  			}
   440  			writeValue(buf, e)
   441  		}
   442  		buf.WriteString("]")
   443  
   444  	case *ssa.Function, *ssa.Builtin, *closure:
   445  		fmt.Fprintf(buf, "%p", v) // (an address)
   446  
   447  	case rtype:
   448  		buf.WriteString(v.t.String())
   449  
   450  	case tuple:
   451  		// Unreachable in well-formed Go programs
   452  		buf.WriteString("(")
   453  		for i, e := range v {
   454  			if i > 0 {
   455  				buf.WriteString(", ")
   456  			}
   457  			writeValue(buf, e)
   458  		}
   459  		buf.WriteString(")")
   460  
   461  	default:
   462  		fmt.Fprintf(buf, "<%T>", v)
   463  	}
   464  }
   465  
   466  // Implements printing of Go values in the style of built-in println.
   467  func toString(v value) string {
   468  	var b bytes.Buffer
   469  	writeValue(&b, v)
   470  	return b.String()
   471  }
   472  
   473  // ------------------------------------------------------------------------
   474  // Iterators
   475  
   476  type stringIter struct {
   477  	*strings.Reader
   478  	i int
   479  }
   480  
   481  func (it *stringIter) next() tuple {
   482  	okv := make(tuple, 3)
   483  	ch, n, err := it.ReadRune()
   484  	ok := err != io.EOF
   485  	okv[0] = ok
   486  	if ok {
   487  		okv[1] = it.i
   488  		okv[2] = ch
   489  	}
   490  	it.i += n
   491  	return okv
   492  }
   493  
   494  type mapIter struct {
   495  	iter *reflect.MapIter
   496  	ok   bool
   497  }
   498  
   499  func (it *mapIter) next() tuple {
   500  	it.ok = it.iter.Next()
   501  	if !it.ok {
   502  		return []value{false, nil, nil}
   503  	}
   504  	k, v := it.iter.Key().Interface(), it.iter.Value().Interface()
   505  	return []value{true, k, v}
   506  }
   507  
   508  type hashmapIter struct {
   509  	iter *reflect.MapIter
   510  	ok   bool
   511  	cur  *entry
   512  }
   513  
   514  func (it *hashmapIter) next() tuple {
   515  	for {
   516  		if it.cur != nil {
   517  			k, v := it.cur.key, it.cur.value
   518  			it.cur = it.cur.next
   519  			return []value{true, k, v}
   520  		}
   521  		it.ok = it.iter.Next()
   522  		if !it.ok {
   523  			return []value{false, nil, nil}
   524  		}
   525  		it.cur = it.iter.Value().Interface().(*entry)
   526  	}
   527  }