code

package
v0.0.0-...-e0b5347 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2023 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package code provides functions and datastructures to encode / decode bytecode instructions.

Bytecode

Constants

Constants are blah di blah.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BinOp

type BinOp uint8

BinOp is the type of binary operator available int Type1 opcodes.

const (
	OpAdd BinOp = iota
	OpSub
	OpMul
	OpDiv
	OpFloorDiv
	OpMod
	OpPow
	OpBitAnd
	OpBitOr
	OpBitXor
	OpShiftL
	OpShiftR
	OpEq
	OpLt
	OpLeq
	OpConcat
)

Here is the list of available binary operators.

type Bool

type Bool bool

A Bool is a boolean literal.

func (Bool) ShortString

func (b Bool) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

A Builder helps build a code Unit (in particular it calculates the offsets for jump instructions).

func NewBuilder

func NewBuilder(source string) *Builder

NewBuilder returns an empty Builder for the given source.

func (*Builder) AddConstant

func (c *Builder) AddConstant(k Constant)

AddConstant adds a constant.

func (*Builder) Emit

func (c *Builder) Emit(opcode Opcode, line int)

Emit adds an opcode (associating it with a source code line).

func (*Builder) EmitJump

func (c *Builder) EmitJump(opcode Opcode, lbl Label, line int)

EmitJump adds a jump opcode, jumping to the given label. The offset part of the opcode must be left as 0, it will be filled by the builder when the location of the label is known.

func (*Builder) EmitLabel

func (c *Builder) EmitLabel(lbl Label)

EmitLabel adds a label for the current location. It panics if called twice with the same label at different locations.

func (*Builder) GetUnit

func (c *Builder) GetUnit() *Unit

GetUnit returns the build code Unit.

func (*Builder) Offset

func (c *Builder) Offset() uint

Offset returns the current location. It must be called when all emitted jump labels have been resolved, otherwise it panice.

type ClStackOffset

type ClStackOffset uint16

ClStackOffset is an offset from the bottom of the close stack

type Code

type Code struct {
	Name                   string   // Name of the function (if it has one)
	StartOffset, EndOffset uint     // Where to find the opcode in the code Unit this belongs to
	UpvalueCount           int16    // Number of upvalues
	CellCount              int16    // Number of cell registers needed to run the code
	RegCount               int16    // Number of registers needed to run the coee
	UpNames                []string // Names of the upvalues
}

Code is a constant representing a chunk of code. It doesn't contain any actual opcodes, but refers to a range in the code unit it belongs to.

func (Code) GetSpan

func (c Code) GetSpan() (name string, start, end int)

GetSpan returns the name of the function this code is compiled from, and the range of instructions in the code Unit this code belongs to.

func (Code) ShortString

func (c Code) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type Constant

type Constant interface {
	ShortString() string
}

A Constant is a literal that can be loaded into a register (that include code chunks).

type Flag

type Flag uint8

Flag is an On / Off switch that can be used in several types of opcodes.

const (
	On  Flag = 1
	Off Flag = 0
)

Flags have two values: On or Off

type Float

type Float float64

A Float is a floating point literal.

func (Float) ShortString

func (f Float) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type Index8

type Index8 uint8

Index8 is an 8 bit index (0 - 255).

func Index8FromInt

func Index8FromInt(n int) Index8

Index8FromInt returns an Index8 encoding the given int, which must fit in an uint8.

type Int

type Int int64

An Int is an integer literal.

func (Int) ShortString

func (i Int) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type JumpOp

type JumpOp uint8

JumpOp is the type of jump supported by Type5 opcode.

const (
	OpCall JumpOp = iota
	OpJump
	OpJumpIf
	OpClStack // Operate on the Close Stack
)

Here are the types of jumps

type KIndex

type KIndex uint16

KIndex is an index into the constants table

func KIndexFromInt

func KIndexFromInt(i int) KIndex

KIndexFromInt returns a KIndex encoding the given index i, panicking if out of range.

type Label

type Label uint

A Label represent a location in the code.

type Lit16

type Lit16 uint16

Lit16 is a 16 bit literal used in several opcode types, used to represent constant values, offsets or indexes into the constants table.

func Lit16FromInt16

func Lit16FromInt16(n int16) Lit16

Lit16FromInt16 converts an int16 into a Lit16.

func Lit16FromStr2

func Lit16FromStr2(b []byte) Lit16

Lit16FromStr2 converts a slice into a Lit16. The slice must have length 2.

func (Lit16) ToInt16

func (l Lit16) ToInt16() int16

ToInt16 converts l to an int16

func (Lit16) ToKIndex

func (l Lit16) ToKIndex() KIndex

ToKIndex converts a Lit16 into a KIndex.

func (Lit16) ToStr2

func (l Lit16) ToStr2() []byte

ToStr2 converts a Lit16 to a slice of two bytes.

type Lit8

type Lit8 uint8

Lit8 is an 8 bit literal that can encode different types of constants inline.

func Lit8FromBool

func Lit8FromBool(b bool) Lit8

Lit8FromBool encodes a Lit8 from a bool.

func Lit8FromStr1

func Lit8FromStr1(b []byte) Lit8

Lit8FromStr1 encodes a Lit8 from a byte string of length 1. Panics if b has length 0.

func (Lit8) ToBool

func (l Lit8) ToBool() bool

ToBool converts a Lit8 to a boolean.

func (Lit8) ToStr1

func (l Lit8) ToStr1() []byte

ToStr1 converts a Lit8 to a slice of 1 byte.

type NilType

type NilType struct{}

NilType is the type of the nil literal.

func (NilType) ShortString

func (n NilType) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type Offset

type Offset int16

An Offset is a relative position in the code for jumping to.

type Opcode

type Opcode uint32

Opcode is the type of opcodes

const (
	Type1Pfx Opcode = 1 << 31 // 1......
	Type2Pfx Opcode = 7 << 28 // 0111...
	Type3Pfx Opcode = 6 << 28 // 0110...
	Type4Pfx Opcode = 5 << 28 // 0101...
	Type5Pfx Opcode = 4 << 28 // 0100...
	Type6Pfx Opcode = 3 << 28 // 0011...
	Type7Pfx Opcode = 2 << 28 // 0010...
	Type0Pfx Opcode = 0 << 28 // 0000...

)

Prefixes for the different types of opcodes. Note: there is an unused prefix (0001).

func AdvForLoop

func AdvForLoop(rStart, rStop, rStep Reg) Opcode

AdvForLoop increments rStart by rStep, making sure that it doesn't wrap around if it is an integer. If it wraps around then the loop should stop. If the loop should stop, rStart is set to nil

func Call

func Call(r Reg) Opcode

Call encodes call r

r must contain a continuation that is ready to be called.

func ClPush

func ClPush(r Reg) Opcode

ClPush encodes clpush r

r should contain either nil, false, or a value with a "__close" metamethod. This opcode is introduced to support Lua 5.4's "to-be-closed" variables.

func ClTrunc

func ClTrunc(h uint16) Opcode

ClTrunc encodes cltrunc h

It truncates the close stack to the given height. Each value on the close stack which is removed should either be nil or false, or be a value with a "__close" metamethod, in which case this metamethod is called. This opcode is introduced to support Lua 5.4's "to-be-closed" variables.

func Clear

func Clear(r Reg) Opcode

Clear encodes clear r

This clears the register. If the register contains a cell, the cell is removed, so this is different from r <- nil

func Combine

func Combine(op BinOp, r1, r2, r3 Reg) Opcode

Combine encodes r1 <- op(r2, r3)

func Cont

func Cont(r1, r2 Reg) Opcode

Cont encodes r1 <- cont(r2)

r2 must contain a closure, r1 then contains a new continuation for that closure, whose next continuation is the cc.

func FillTable

func FillTable(r1, r2 Reg, i int) Opcode

FillTable encodes fill r1, i, r2

This fills the table r1 with all values from r2 (as an etc vector) starting from index i.

func Jump

func Jump(j Offset) Opcode

Jump encodes an unconditional jump

jump j

func JumpIf

func JumpIf(j Offset, r Reg) Opcode

JumpIf encodes a conditional jump.

jump j if r

func JumpIfNot

func JumpIfNot(j Offset, r Reg) Opcode

JumpIfNot encodes a conditional jump.

jump j if not r

func LoadBool

func LoadBool(r Reg, b bool) Opcode

LoadBool encodes r <- true or r <- false.

func LoadClosure

func LoadClosure(r1 Reg, i KIndex) Opcode

LoadClosure encodes r <- clos(Ki)

func LoadConst

func LoadConst(r Reg, i KIndex) Opcode

LoadConst encodes r <- Ki

func LoadEmptyTable

func LoadEmptyTable(r Reg) Opcode

LoadEmptyTable encodes r <- {}

func LoadEtcLookup

func LoadEtcLookup(r1, r2 Reg, i int) Opcode

LoadEtcLookup encodes r1 <- etclookup(r2, i)

loads the (i + 1)-th element of r2 (as an etc vector) into r1.

func LoadInt16

func LoadInt16(r Reg, n int16) Opcode

LoadInt16 encodes r <- n

func LoadLookup

func LoadLookup(r1, r2, r3 Reg) Opcode

LoadLookup encodes r1 <- r2[r3]

func LoadNil

func LoadNil(r Reg) Opcode

LoadNil encodes r <- nil

func LoadShortString

func LoadShortString(r Reg, b []byte) (Opcode, bool)

LoadShortString attempts to encode loading a short string. Returns the opcode and true if it did.

func LoadSmallInt

func LoadSmallInt(r Reg, n int) (Opcode, bool)

LoadSmallInt attempts to load a small integer (atm it has to be representable as an int16).

func LoadStr0

func LoadStr0(r Reg) Opcode

LoadStr0 encodes r <- ""

func LoadStr1

func LoadStr1(r Reg, b []byte) Opcode

LoadStr1 encodes r <- "x"

func LoadStr2

func LoadStr2(r Reg, b []byte) Opcode

LoadStr2 encodes r <- "xy"

func PrepForLoop

func PrepForLoop(rStart, rStop, rStep Reg) Opcode

PrepForLoop makes sure rStart, rStep, rStop are all numbers and converts rStart and rStep to the same numeric type. If the for loop should already stop then rStart is set to nil

func Push

func Push(r1, r2 Reg) Opcode

Push encodes push r1, r2

r1 must contain a continuation.

func PushEtc

func PushEtc(r1, r2 Reg) Opcode

PushEtc encodes pushetc r1, ...r2

r1 must contain a continuation, r2 an etc.

func Receive

func Receive(r Reg) Opcode

Receive encodes recv r

recv r is the pendant of push.

func ReceiveEtc

func ReceiveEtc(r Reg) Opcode

ReceiveEtc encodes recv ...r

accumulates pushes into r (as an Etc)

func SetIndex

func SetIndex(r1, r2, r3 Reg) Opcode

SetIndex encodes r2[r3] <- r1

func TailCall

func TailCall(r Reg) Opcode

TailCall encodes tailcall r

r must contain a continuation that is ready to be called.

func TailCont

func TailCont(r1, r2 Reg) Opcode

TailCont encodes r1 <- tailcont(r2)

r2 must contain a closure, r1 then contains a new continuatino for that closure, whose next continuation is the cc's next continuation.

func Transform

func Transform(op UnOp, r1, r2 Reg) Opcode

Transform encodes r1 <- op(r2)

func Upval

func Upval(r1, r2 Reg) Opcode

Upval encodes upval r1, r2

r1 must contain a closure. This appends the value of r2 to the list of upvalues of r1.

func (Opcode) Disassemble

func (c Opcode) Disassemble(d OpcodeDisassembler, i int) string

Disassemble gets a human readable representation of an opcode.

func (Opcode) GetA

func (c Opcode) GetA() Reg

GetA returns the register rA encoded in the opcode.

func (Opcode) GetB

func (c Opcode) GetB() Reg

GetB returns the register rB encoded in the opcode.

func (Opcode) GetC

func (c Opcode) GetC() Reg

GetC returns the register rC encoded in the opcode.

func (Opcode) GetClStackOffset

func (c Opcode) GetClStackOffset() ClStackOffset

func (Opcode) GetF

func (c Opcode) GetF() bool

GetF decodes the flag and returns true if the flag is On.

func (Opcode) GetJ

func (c Opcode) GetJ() JumpOp

GetJ decodes the JumpOp from this opcode.

func (Opcode) GetKIndex

func (c Opcode) GetKIndex() KIndex

GetKIndex decodes the KIndex from the opcode.

func (Opcode) GetL

func (c Opcode) GetL() Lit8

GetL decodes the L field of the opcode.

func (Opcode) GetM

func (c Opcode) GetM() Index8

GetM decodes the Index8 from the opcode.

func (Opcode) GetN

func (c Opcode) GetN() Lit16

GetN decodes the Lit16 from the opcode.

func (Opcode) GetOffset

func (c Opcode) GetOffset() Offset

GetOffset decodes the Offset from the opcode.

func (Opcode) GetUnOp

func (c Opcode) GetUnOp() UnOp

GetUnOp decodes the UnOp in the opcode.

func (Opcode) GetUnOpK

func (c Opcode) GetUnOpK() UnOpK

GetUnOpK decodes the UnOpK in the opcode.

func (Opcode) GetX

func (c Opcode) GetX() BinOp

GetX decodes the BinOp from this opcode.

func (Opcode) GetY

func (c Opcode) GetY() UnOpK16

GetY decodes the UnOpK16 from the opcode.

func (Opcode) HasType0

func (c Opcode) HasType0() bool

HasType0 returns true if the opcdoe is Type0.

func (Opcode) HasType1

func (c Opcode) HasType1() bool

HasType1 returns true if the opcode is Type1.

func (Opcode) HasType4a

func (c Opcode) HasType4a() bool

HasType4a returns true if the opcode is Type4a, assuming that it is Type4.

func (Opcode) SetKIndex

func (c Opcode) SetKIndex(i KIndex) Opcode

SetKIndex returns a copy of the opcode with a new KIndex.

func (Opcode) SetOffset

func (c Opcode) SetOffset(n Offset) Opcode

SetOffset returns a copy of the opcode with the given offset.

func (Opcode) TypePfx

func (c Opcode) TypePfx() Opcode

TypePfx returns the type prefix of the opcode. (valid for all types apart from Type1, which has MSB 1).

type OpcodeDisassembler

type OpcodeDisassembler interface {
	ShortKString(KIndex) string // Gets a string representation of a constant
	GetLabel(int) string        // Gets a constistent label name for a code offset
}

OpcodeDisassembler is an interface that helps disassemble an opcode.

type Reg

type Reg struct {
	// contains filtered or unexported fields
}

Reg is a register

func CellReg

func CellReg(idx uint8) Reg

CellReg returns a cell register.

func ValueReg

func ValueReg(idx uint8) Reg

ValueReg returns a value register.

func (Reg) Idx

func (r Reg) Idx() uint8

Idx returns the index of the register

func (Reg) IsCell

func (r Reg) IsCell() bool

IsCell returns true if r is a cell.

func (Reg) RegType

func (r Reg) RegType() RegType

RegType returns the type of the register

func (Reg) String

func (r Reg) String() string

type RegType

type RegType uint8

RegType represents the type of a register

const (
	ValueRegType RegType = 0
	CellRegType          = 1
)

ValueRegType types

type String

type String string

A String is a string literal.

func (String) ShortString

func (s String) ShortString() string

ShortString returns a short string describing this constant (e.g. for disassembly)

type UnOp

type UnOp uint8

UnOp is the type of operators available in Type4a opcodes.

const (
	OpNeg      UnOp = iota // numerical negation
	OpBitNot               // bitwise negation
	OpLen                  // length
	OpCont                 // make a continuation for the closure
	OpTailCont             // make a "tail continuation" for the closure (its next is cc's next)
	OpId                   // identity
	OpTruth                // Turn operand to boolean
	OpNot                  // Added afterwards - why did I not have it in the first place?
	OpUpvalue              // get an upvalue
	OpEtcId                // etc identity
)

Available unary operators

type UnOpK

type UnOpK uint8

UnOpK is the type of operators available in Type4b opcodes.

const (
	OpNil UnOpK = iota
	OpStr0
	OpTable
	OpStr1
	OpBool
	OpCC
	OpClear
	OpInt   // Extra 64 bits (2 opcodes)
	OpFloat // Extra 64 bits (2 opcodes)
	OpStrN  // Extra [n / 4] opcodes
)

Available Constant operators

type UnOpK16

type UnOpK16 uint8

UnOpK16 is the type of operator available in Type3 opcodes.

const (
	OpInt16 UnOpK16 = iota
	OpK
	OpClosureK
	OpStr2
)

Here is the list of available UnOpK16 operators.

func (UnOpK16) LoadsK

func (op UnOpK16) LoadsK() bool

LoadsK returns true if it loads a constant from the constant vector (not a literal encoded in the opcode).

type Unit

type Unit struct {
	Source    string     // Shows were the unit comes from (e.g. a filename) - only for information.
	Code      []Opcode   // The code
	Lines     []int32    // Optional: source code line for the corresponding opcode
	Constants []Constant // All the constants required for running the code
}

A Unit is a chunk of code with associated constants.

func (*Unit) Disassemble

func (u *Unit) Disassemble(w io.Writer)

Disassemble outputs the disassembly of the unit code into the given io.Writer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL