Documentation ¶
Overview ¶
Package ir implements intermediate representation of compiled programs. (Work In Progress)
See: https://en.wikipedia.org/wiki/Intermediate_representation
Concepts ¶
From the POV of this package, an IR is a slice of Objects. Object is either a DataDefinition or a FunctionDefinition. All objects are defined by Linkage, NameID and TypeID fields.
DataDefintions reserve global, static data storage and have an optional Value. If Value is nil the DataDefintion defines a zero value of its type.
FunctionDefinitions have a Body which is a slice of Operation. Operations are, for example, Add, Return, etc. The operation execution model is a zero register stack machine.
Verifying and linking ¶
After generating a slice of Objects, its every item should be verified using Verify. One or more generated IRs can be turned into complete IRs using LinkMain or LinkLib. These functions will check and resolve external definitions by filling the respective Index fields of certain operations, for example Global. A properly linked IR should be suitable for back-end code generation of a program or a library.
Executing IR programs ¶
cznic/virtual is an IR code generator for a virtual CPU and can also run the resulting binary. The virtual CPU is not very fast, it's best use is probably just to verify a particular IR generator or to provide an interpreter for scripts loaded/entered at run time. A "standard" back-end should normally produce machine code,
Index ¶
- Variables
- func PrettyString(v interface{}) string
- type Add
- type AddressValue
- type AllocResult
- type And
- type Argument
- type Arguments
- type ArrayType
- type BeginScope
- type Bool
- type Call
- type CallFP
- type Complex128Value
- type Complex64Value
- type CompositeValue
- type Const
- type Const32
- type Const64
- type ConstC128
- type Convert
- type Copy
- type Cpl
- type DataDefinition
- type DesignatedValue
- type Div
- type Drop
- type Dup
- type Element
- type EndScope
- type Eq
- type Field
- type FieldProperties
- type FieldValue
- type Float32Value
- type Float64Value
- type FunctionDefinition
- type FunctionType
- type Geq
- type Global
- type Gt
- type Int32Value
- type Int64Value
- type Jmp
- type JmpP
- type Jnz
- type Jz
- type Label
- type Leq
- type Linkage
- type Load
- type Lsh
- type Lt
- type MemoryModel
- type MemoryModelItem
- type Mul
- type NameID
- type Neg
- type Neq
- type Nil
- type Not
- type Object
- type ObjectBase
- type Objects
- type Operation
- type Or
- type Panic
- type PointerType
- type PostIncrement
- type PreIncrement
- type PtrDiff
- type Rem
- type Result
- type Return
- type Rsh
- type Store
- type StringConst
- type StringID
- type StringValue
- type StructOrUnionType
- type Sub
- type Switch
- type Type
- type TypeBase
- type TypeCache
- type TypeID
- type TypeKind
- type Value
- type Variable
- type VariableDeclaration
- type WideStringValue
- type Xor
Constants ¶
This section is empty.
Variables ¶
var ( // Testing amends things for tests. Testing bool )
Functions ¶
func PrettyString ¶
func PrettyString(v interface{}) string
PrettyString turns certain things, produced by this package, into neatly format text.
Types ¶
type Add ¶
Add operation adds the top stack item (b) and the previous one (a) and replaces both operands with a + b.
type AddressValue ¶
type AddressValue struct { // A negative value or object index as resolved by the linker. Index int Label NameID Linkage NameID NameID Offset uintptr // contains filtered or unexported fields }
AddressValue is a declaration initializer constant of type address. Its final value is determined by the linker/loader.
func (*AddressValue) String ¶
func (v *AddressValue) String() string
type AllocResult ¶
AllocResult operation reserves evaluation stack space for a result of type TypeID.
func (*AllocResult) String ¶
func (o *AllocResult) String() string
type Arguments ¶
type Arguments struct { token.Position FunctionPointer bool // TOS contains a function pointer for a subsequent CallFP. Determined by linker. }
Arguments operation annotates that function results, if any, are allocated and a function pointer is at TOS. Evaluation of any function arguments follows.
type BeginScope ¶
type BeginScope struct { // Evaluation stack may be non-empty on entering the scope. See // https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Value bool token.Position }
BeginScope operation annotates entering a block scope.
func (*BeginScope) String ¶
func (o *BeginScope) String() string
type Bool ¶
Bool operation converts TOS to a bool (ie. an int32) such that the result reflects if the operand was non zero.
type Call ¶
type Call struct { Arguments int // Actual number of arguments passed to function. Comma bool // The call operation is produced by the C comma operator for a void function. Index int // A negative value or an function object index as resolved by the linker. TypeID TypeID // Type of the function. token.Position }
Call operation performs a static function call. The evaluation stack contains the space reseved for function results, if any, and any function arguments. On return all arguments are removed from the stack.
type CallFP ¶
type CallFP struct { Arguments int // Actual number of arguments passed to function. Comma bool // The call FP operation is produced by the C comma operator for a void function. TypeID TypeID // Type of the function pointer. token.Position }
CallFP operation performs a function pointer call. The evaluation stack contains the space reseved for function results, if any, the function pointer and any function arguments. On return all arguments and the function pointer are removed from the stack.
type Complex128Value ¶
type Complex128Value struct { Value complex128 // contains filtered or unexported fields }
Complex128Value is a declaration initializer constant of type complex128.
func (*Complex128Value) String ¶
func (v *Complex128Value) String() string
type Complex64Value ¶
type Complex64Value struct { Value complex64 // contains filtered or unexported fields }
Complex64Value is a declaration initializer constant of type complex64.
func (*Complex64Value) String ¶
func (v *Complex64Value) String() string
type CompositeValue ¶
type CompositeValue struct { Values []Value // contains filtered or unexported fields }
CompositeValue represents a constant array/struct initializer.
func (*CompositeValue) String ¶
func (v *CompositeValue) String() string
type Const32 ¶
type Const32 struct { LOp bool // This operation is an artifact of || or &&. TypeID TypeID Value int32 token.Position }
Const32 operation pushes a 32 bit value on the evaluation stack.
type ConstC128 ¶
type ConstC128 struct { TypeID TypeID Value complex128 token.Position }
ConstC128 operation pushes a complex128 value on the evaluation stack.
type Convert ¶
type Convert struct { Result TypeID // Conversion type. TypeID TypeID // Operand type. token.Position }
Convert operation converts TOS to the result type.
type Copy ¶
Copy assigns source, which address is at TOS, to dest, which address is the previous stack item. The source address is removed from the stack.
type DataDefinition ¶
type DataDefinition struct { ObjectBase Value }
DataDefinition represents a variable definition and an optional initializer value.
func NewDataDefinition ¶
func NewDataDefinition(p token.Position, name, typeName NameID, typ TypeID, l Linkage, initializer Value) *DataDefinition
NewDataDefinition returns a newly created DataDefinition.
type DesignatedValue ¶
DesignatedValue represents the value of a particular array element or a particular struct field.
func (*DesignatedValue) String ¶
func (v *DesignatedValue) String() string
type Div ¶
Div operation subtracts the top stack item (b) and the previous one (a) and replaces both operands with a / b. The operation panics if operands are integers and b == 0.
type Drop ¶
type Drop struct { Comma bool // The drop operation is produced by the C comma operator. LOp bool // This operation is an artifact of || or &&. TypeID TypeID token.Position }
Drop operation removes one item from the evaluation stack.
type Element ¶
type Element struct { Address bool IndexType TypeID Neg bool // Negate the index expression. TypeID TypeID // The indexed type. token.Position }
Element replaces a pointer and index with the indexed element or its address.
type EndScope ¶
type EndScope struct { // Leaving the scope may leave values on the evaluation stack. See // https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Value bool token.Position }
EndScope operation annotates leaving a block scope.
type Eq ¶
Eq operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a == b or zero otherwise.
type Field ¶
type Field struct { Address bool Index int TypeID TypeID // Pointer to a struct/union. token.Position }
Field replaces a struct/union pointer at TOS with its field by index, or its address.
type FieldProperties ¶
type FieldProperties struct { Offset int64 // Relative to start of the struct/union. Size int64 // Field size for copying. Padding int // Adjustment to enforce proper alignment. }
FieldProperties describe a struct/union field.
func (*FieldProperties) Sizeof ¶
func (f *FieldProperties) Sizeof() int64
Sizeof returns the sum of f.Size and f.Padding.
type FieldValue ¶
FieldValue replaces a struct/union at TOS with its field by index.
func (*FieldValue) String ¶
func (o *FieldValue) String() string
type Float32Value ¶
type Float32Value struct { Value float32 // contains filtered or unexported fields }
Float32Value is a declaration initializer constant of type float32.
func (*Float32Value) String ¶
func (v *Float32Value) String() string
type Float64Value ¶
type Float64Value struct { Value float64 // contains filtered or unexported fields }
Float64Value is a declaration initializer constant of type float64.
func (*Float64Value) String ¶
func (v *Float64Value) String() string
type FunctionDefinition ¶
type FunctionDefinition struct { Arguments []NameID // May be nil. Body []Operation ObjectBase Results []NameID // May be nil. }
FunctionDefinition represents a function definition.
func NewFunctionDefinition ¶
func NewFunctionDefinition(p token.Position, name, typeName NameID, typ TypeID, l Linkage, argumnents, results []NameID) *FunctionDefinition
NewFunctionDefinition returns a newly created FunctionDefinition.
func (*FunctionDefinition) Verify ¶
func (f *FunctionDefinition) Verify() (err error)
Verify implements Object.
type FunctionType ¶
FunctionType represents a function, its possibly variadic, optional arguments and results.
type Geq ¶
Geq operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a >= b or zero otherwise.
type Global ¶
type Global struct { Address bool Index int // A negative value or an object index as resolved by the linker. Linkage NameID NameID TypeID TypeID TypeName NameID token.Position }
Global operation pushes a global variable, or its address, to the evaluation stack.
type Gt ¶
Gt operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a > b or zero otherwise.
type Int32Value ¶
type Int32Value struct { Value int32 // contains filtered or unexported fields }
Int32Value is a declaration initializer constant of type int32.
func (*Int32Value) String ¶
func (v *Int32Value) String() string
type Int64Value ¶
type Int64Value struct { Value int64 // contains filtered or unexported fields }
Int64Value is a declaration initializer constant of type int64.
func (*Int64Value) String ¶
func (v *Int64Value) String() string
type Jmp ¶
type Jmp struct { Cond bool // This operation is an artifact of the conditional operator. NameID NameID Number int token.Position }
Jmp operation performs a branch to a named or numbered label.
type Jnz ¶
type Jnz struct { LOp bool // This operation is an artifact of || or &&. NameID NameID Number int token.Position }
Jnz operation performs a branch to a named or numbered label if the top of the stack is non zero. The TOS type must be int32 and the operation removes TOS.
type Jz ¶
type Jz struct { LOp bool // This operation is an artifact of || or && or the conditional operator. NameID NameID Number int token.Position }
Jz operation performs a branch to a named or numbered label if the top of the stack is zero. The TOS type must be int32 and the operation removes TOS.
type Label ¶
type Label struct { Cond bool // This operation is an artifact of the conditional operator. LAnd bool // This operation is an artifact of &&. LOr bool // This operation is an artifact of ||. NameID NameID Nop bool // This operation is an artifact of the conditional operator. Number int token.Position }
Label operation declares a named or numbered branch target. A valid Label must have a non zero NameID or non negative Number.
type Leq ¶
Leq operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a <= b or zero otherwise.
type Linkage ¶
type Linkage int
Linkage represents a linkage type.
const ( ExternalLinkage Linkage InternalLinkage )
Linkage values.
type Lsh ¶
Lsh operation uses the top stack item (b), which must be an int32, and the previous one (a), which must be an integral type and replaces both operands with a << b.
type Lt ¶
Lt operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a < b or zero otherwise.
type MemoryModel ¶
type MemoryModel map[TypeKind]MemoryModelItem
MemoryModel defines properties of types. A valid memory model must provide model items for all type kinds except Array, Struct and Union. Methods of invalid models may panic. Memory model instances are not modified by this package and safe for concurrent use by multiple goroutines as long as any of them does not modify them either.
func NewMemoryModel ¶
func NewMemoryModel() (MemoryModel, error)
NewMemoryModel returns a new MemoryModel for the current architecture and platform or an error, if any.
func (MemoryModel) Alignof ¶
func (m MemoryModel) Alignof(t Type) int
Alignof computes the memory alignment requirements of t. Zero is returned for a struct/union type with no fields.
func (MemoryModel) Layout ¶
func (m MemoryModel) Layout(t *StructOrUnionType) []FieldProperties
Layout computes the memory layout of t.
func (MemoryModel) Sizeof ¶
func (m MemoryModel) Sizeof(t Type) int64
Sizeof computes the memory size of t.
func (MemoryModel) StructAlignof ¶
func (m MemoryModel) StructAlignof(t Type) int
StructAlignof computes the memory alignment requirements of t when its instance is a struct field. Zero is returned for a struct/union type with no fields.
type MemoryModelItem ¶
MemoryModelItem describes memory properties of a particular type kind.
type Mul ¶
Mul operation subtracts the top stack item (b) and the previous one (a) and replaces both operands with a * b.
type NameID ¶
type NameID int
NameID is a numeric identifier of an identifier as registered in a global dictionary[0].
[0]: https://godoc.org/github.com/cznic/xc#pkg-variables
type Neq ¶
Neq operation compares the top stack item (b) and the previous one (a) and replaces both operands with a non zero int32 value if a != b or zero otherwise.
type Object ¶
type Object interface { // Verify checks if the object is well-formed. Verify may mutate the // object. For example, Verify may remove provably unreachable code of // a FunctionDefinition.Body. Verify() error Base() *ObjectBase }
Object represents a declarations or definitions of static data and functions.
func LinkLib ¶
LinkLib returns all objects with external linkage defined in translationUnits. Linking may mutate passed objects. It's the caller responsibility to ensure all translationUnits were produced for the same architecture and platform.
LinkLib panics when passed no data.
type ObjectBase ¶
type ObjectBase struct { Comment NameID Linkage NameID NameID Package NameID TypeID TypeID TypeName NameID token.Position }
ObjectBase collects fields common to all objects.
type Objects ¶
type Objects [][]Object
Objects represent []Object implementing io.ReaderFrom and io.WriterTo.
type PointerType ¶
PointerType represents a pointer to an element, an instance of another type.
type PostIncrement ¶
type PostIncrement struct { BitFieldType TypeID BitOffset int Bits int Delta int TypeID TypeID // Operand type. token.Position }
PostIncrement operation adds Delta to the value pointed to by address at TOS and replaces TOS by the value pointee had before the increment. If Bits is non zero then the effective operand type is BitFieldType and the bit field starts at bit BitOffset.
func (*PostIncrement) String ¶
func (o *PostIncrement) String() string
type PreIncrement ¶
type PreIncrement struct { BitFieldType TypeID BitOffset int Bits int Delta int TypeID TypeID // Operand type. token.Position }
PreIncrement operation adds Delta to the value pointed to by address at TOS and replaces TOS by the new value of the pointee. If Bits is non zero then the effective operand type is BitFieldType and the bit field starts at bit BitOffset.
func (*PreIncrement) String ¶
func (o *PreIncrement) String() string
type PtrDiff ¶
PtrDiff operation subtracts the top stack item (b) and the previous one (a) and replaces both operands with a - b of type TypeID.
type Rem ¶
Rem operation divides the top stack item (b) and the previous one (a) and replaces both operands with a % b. The operation panics if b == 0.
type Return ¶
Return operation removes all function call arguments from the evaluation stack as well as the function pointer used in the call, if any.
type Rsh ¶
Rsh operation uses the top stack item (b), which must be an int32, and the previous one (a), which must be an integral type and replaces both operands with a >> b.
type Store ¶
Store operation stores a TOS value at address in the preceding stack position. The address is removed from the evaluation stack. If Bits is non zero then the destination is a bit field starting at bit BitOffset.
type StringConst ¶
type StringConst struct { Value StringID TypeID TypeID // Type of the pointer to the string value. token.Position }
StringConst operation pushes a string value on the evaluation stack.
func (*StringConst) String ¶
func (o *StringConst) String() string
type StringID ¶
type StringID int
StringID is a numeric identifier of a string literal as registered in a global dictionary[0].
[0]: https://godoc.org/github.com/cznic/xc#pkg-variables
type StringValue ¶
type StringValue struct { Offset uintptr StringID StringID // contains filtered or unexported fields }
StringValue is a declaration initializer constant of type string.
func (*StringValue) String ¶
func (v *StringValue) String() string
type StructOrUnionType ¶
StructOrUnionType represents a collection of fields that can be selected by name.
func (*StructOrUnionType) Pointer ¶
func (t *StructOrUnionType) Pointer() Type
Pointer implements Type.
type Sub ¶
Sub operation subtracts the top stack item (b) and the previous one (a) and replaces both operands with a - b.
type Switch ¶
type Switch struct { Default Label Labels []Label TypeID TypeID // Operand type. Values []Value token.Position }
Switch jumps to a label according to a value at TOS or to a default label. The value at TOS is removed from the evaluation stack.
type Type ¶
Type represents an IR type.
The type specifier syntax is defined using Extended Backus-Naur Form (EBNF[0]):
Type = ArrayType | FunctionType | PointerType | StructType | TypeName | UnionType . ArrayType = "[" "0"..."9" { "0"..."9" } "]" Type . FunctionType = "func" "(" [ TypeList ] [ "..." ] ")" [ Type | "(" TypeList ")" ] . PointerType = "*" Type . StructType = "struct" "{" [ FieldList ] "}" . Fieldist = name " " Type { "," name " " Type } . TypeList = Type { "," Type } . TypeName = "uint8" | "uint16" | "uint32" | "uint64" | "int8" | "int16" | "int32" | "int64" | "float32" | "float64" | "float128" | "complex64" | "complex128" | complex256 | "uint0" | "uint8" | "uint16" | "uint32" | "uint64" . UnionType = "union" "{" [ FieldList ] "}" .
No whitespace is allowed in type specifiers except as the name Type separator.
[0]: https://golang.org/ref/spec#Notation
Type identity ¶
Two types are identical if their type specifiers are equivalent.
type TypeCache ¶
TypeCache maps TypeIDs to Types. Use TypeCache{} to create a ready to use TypeCache value.
type TypeID ¶
type TypeID int
TypeID is a numeric identifier of a type specifier as registered in a global dictionary[0].
[0]: https://godoc.org/github.com/cznic/xc#pkg-variables
type TypeKind ¶
type TypeKind int
TypeKind represents a particular type kind.
const ( Int8 TypeKind Int16 Int32 Int64 Uint8 Uint16 Uint32 Uint64 Float32 Float64 Float128 Complex64 Complex128 Complex256 Array Union Struct Pointer Function )
TypeKind values.
type Value ¶
type Value interface {
// contains filtered or unexported methods
}
Value represents a constant expression used for initializing static data or function variables.
type Variable ¶
Variable pushes a function local variable by index, or its address, to the evaluation stack.
type VariableDeclaration ¶
type VariableDeclaration struct { Index int // 0-based index within a function. NameID NameID TypeID TypeID TypeName NameID Value token.Position }
VariableDeclaration operation declares a function local variable. NameID, TypeName and Value are all optional.
func (*VariableDeclaration) Pos ¶
func (o *VariableDeclaration) Pos() token.Position
Pos implements Operation.
func (*VariableDeclaration) String ¶
func (o *VariableDeclaration) String() string
type WideStringValue ¶
type WideStringValue struct { Value []rune // contains filtered or unexported fields }
WideStringValue is a declaration initializer constant of type wide string.
func (*WideStringValue) String ¶
func (v *WideStringValue) String() string