github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/engine/wazevo/ssa/vs.go (about) 1 package ssa 2 3 import ( 4 "fmt" 5 "math" 6 7 "github.com/bananabytelabs/wazero/internal/engine/wazevo/wazevoapi" 8 ) 9 10 // Variable is a unique identifier for a source program's variable and will correspond to 11 // multiple ssa Value(s). 12 // 13 // For example, `Local 1` is a Variable in WebAssembly, and Value(s) will be created for it 14 // whenever it executes `local.set 1`. 15 // 16 // Variable is useful to track the SSA Values of a variable in the source program, and 17 // can be used to find the corresponding latest SSA Value via Builder.FindValue. 18 type Variable uint32 19 20 // String implements fmt.Stringer. 21 func (v Variable) String() string { 22 return fmt.Sprintf("var%d", v) 23 } 24 25 // Value represents an SSA value with a type information. The relationship with Variable is 1: N (including 0), 26 // that means there might be multiple Variable(s) for a Value. 27 // 28 // Higher 32-bit is used to store Type for this value. 29 type Value uint64 30 31 // ValueID is the lower 32bit of Value, which is the pure identifier of Value without type info. 32 type ValueID uint32 33 34 const ( 35 valueIDInvalid ValueID = math.MaxUint32 36 ValueInvalid Value = Value(valueIDInvalid) 37 ) 38 39 // Format creates a debug string for this Value using the data stored in Builder. 40 func (v Value) Format(b Builder) string { 41 if annotation, ok := b.(*builder).valueAnnotations[v.ID()]; ok { 42 return annotation 43 } 44 return fmt.Sprintf("v%d", v.ID()) 45 } 46 47 func (v Value) formatWithType(b Builder) (ret string) { 48 if annotation, ok := b.(*builder).valueAnnotations[v.ID()]; ok { 49 ret = annotation + ":" + v.Type().String() 50 } else { 51 ret = fmt.Sprintf("v%d:%s", v.ID(), v.Type()) 52 } 53 54 if wazevoapi.SSALoggingEnabled { // This is useful to check live value analysis bugs. 55 if bd := b.(*builder); bd.donePasses { 56 id := v.ID() 57 ret += fmt.Sprintf("(ref=%d)", bd.valueRefCounts[id]) 58 } 59 } 60 return ret 61 } 62 63 // Valid returns true if this value is valid. 64 func (v Value) Valid() bool { 65 return v.ID() != valueIDInvalid 66 } 67 68 // Type returns the Type of this value. 69 func (v Value) Type() Type { 70 return Type(v >> 32) 71 } 72 73 // ID returns the valueID of this value. 74 func (v Value) ID() ValueID { 75 return ValueID(v) 76 } 77 78 // setType sets a type to this Value and returns the updated Value. 79 func (v Value) setType(typ Type) Value { 80 return v | Value(typ)<<32 81 }