asm

package
v1.0.0-pre.1 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2022 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Index

Constants

View Source
const JumpTableMaximumOffset = math.MaxUint32

JumpTableMaximumOffset represents the limit on the size of jump table in bytes. When users try loading an extremely large WebAssembly binary which contains a br_table statement with approximately 4294967296 (2^32) targets. Realistically speaking, that kind of binary could result in more than ten gigabytes of native compiled code where we have to care about huge stacks whose height might exceed 32-bit range, and such huge stack doesn't work with the current implementation.

Variables

This section is empty.

Functions

This section is empty.

Types

type AssemblerBase

type AssemblerBase interface {
	// Assemble produces the final binary for the assembled operations.
	Assemble() ([]byte, error)

	// SetJumpTargetOnNext instructs the assembler that the next node must be
	// assigned to the given node's jump destination.
	SetJumpTargetOnNext(nodes ...Node)

	// BuildJumpTable calculates the offsets between the first instruction `initialInstructions[0]`
	// and others (e.g. initialInstructions[3]), and wrote the calculated offsets into pre-allocated
	// `table` StaticConst in little endian.
	BuildJumpTable(table *StaticConst, initialInstructions []Node)

	// CompileStandAlone adds an instruction to take no arguments.
	CompileStandAlone(instruction Instruction) Node

	// CompileConstToRegister adds an instruction where source operand is `value` as constant and destination is `destinationReg` register.
	CompileConstToRegister(instruction Instruction, value ConstantValue, destinationReg Register) Node

	// CompileRegisterToRegister adds an instruction where source and destination operands are registers.
	CompileRegisterToRegister(instruction Instruction, from, to Register)

	// CompileMemoryToRegister adds an instruction where source operands is the memory address specified by `sourceBaseReg+sourceOffsetConst`
	// and the destination is `destinationReg` register.
	CompileMemoryToRegister(
		instruction Instruction,
		sourceBaseReg Register,
		sourceOffsetConst ConstantValue,
		destinationReg Register,
	)

	// CompileRegisterToMemory adds an instruction where source operand is `sourceRegister` register and the destination is the
	// memory address specified by `destinationBaseRegister+destinationOffsetConst`.
	CompileRegisterToMemory(
		instruction Instruction,
		sourceRegister Register,
		destinationBaseRegister Register,
		destinationOffsetConst ConstantValue,
	)

	// CompileJump adds jump-type instruction and returns the corresponding Node in the assembled linked list.
	CompileJump(jmpInstruction Instruction) Node

	// CompileJumpToRegister adds jump-type instruction whose destination is the memory address specified by `reg` register.
	CompileJumpToRegister(jmpInstruction Instruction, reg Register)

	// CompileReadInstructionAddress adds an ADR instruction to set the absolute address of "target instruction"
	// into destinationRegister. "target instruction" is specified by beforeTargetInst argument and
	// the target is determined by "the instruction right after beforeTargetInst type".
	//
	// For example, if `beforeTargetInst == RET` and we have the instruction sequence like
	// `ADR -> X -> Y -> ... -> RET -> MOV`, then the `ADR` instruction emitted by this function set the absolute
	// address of `MOV` instruction into the destination register.
	CompileReadInstructionAddress(destinationRegister Register, beforeAcquisitionTargetInstruction Instruction)
}

AssemblerBase is the common interface for assemblers among multiple architectures.

Note: some of them can be implemented in an arch-independent way, but not all can be implemented as such. However, we intentionally put such arch-dependant methods here in order to provide the common documentation interface.

type BaseAssemblerImpl

type BaseAssemblerImpl struct {
	// SetBranchTargetOnNextNodes holds branch kind instructions (BR, conditional BR, etc.)
	// where we want to set the next coming instruction as the destination of these BR instructions.
	SetBranchTargetOnNextNodes []Node

	// OnGenerateCallbacks holds the callbacks which are called after generating native code.
	OnGenerateCallbacks []func(code []byte) error
}

BaseAssemblerImpl includes code common to all architectures.

Note: When possible, add code here instead of in architecture-specific files to reduce drift: As this is internal, exporting symbols only to reduce duplication is ok.

func (*BaseAssemblerImpl) AddOnGenerateCallBack

func (a *BaseAssemblerImpl) AddOnGenerateCallBack(cb func([]byte) error)

AddOnGenerateCallBack implements AssemblerBase.AddOnGenerateCallBack

func (*BaseAssemblerImpl) BuildJumpTable

func (a *BaseAssemblerImpl) BuildJumpTable(table *StaticConst, labelInitialInstructions []Node)

BuildJumpTable implements AssemblerBase.BuildJumpTable

func (*BaseAssemblerImpl) SetJumpTargetOnNext

func (a *BaseAssemblerImpl) SetJumpTargetOnNext(nodes ...Node)

SetJumpTargetOnNext implements AssemblerBase.SetJumpTargetOnNext

type ConditionalRegisterState

type ConditionalRegisterState byte

ConditionalRegisterState represents architecture-specific conditional register's states.

const ConditionalRegisterStateUnset ConditionalRegisterState = 0

ConditionalRegisterStateUnset is the only architecture-independent conditional state, and can be used to indicate that no conditional state is specified.

type ConstantValue

type ConstantValue = int64

ConstantValue represents a constant value used in an instruction.

type Instruction

type Instruction uint16 // to accommodate the high cardinality of vector ops

Instruction represents architecture-specific instructions.

type Node

type Node interface {
	fmt.Stringer

	// AssignJumpTarget assigns the given target node as the destination of
	// jump instruction for this Node.
	AssignJumpTarget(target Node)

	// AssignDestinationConstant assigns the given constant as the destination
	// of the instruction for this node.
	AssignDestinationConstant(value ConstantValue)

	// AssignSourceConstant assigns the given constant as the source
	// of the instruction for this node.
	AssignSourceConstant(value ConstantValue)

	// OffsetInBinary returns the offset of this node in the assembled binary.
	OffsetInBinary() NodeOffsetInBinary
}

Node represents a node in the linked list of assembled operations.

type NodeOffsetInBinary

type NodeOffsetInBinary = uint64

NodeOffsetInBinary represents an offset of this node in the final binary.

type Register

type Register byte

Register represents architecture-specific registers.

const NilRegister Register = 0

NilRegister is the only architecture-independent register, and can be used to indicate that no register is specified.

type StaticConst

type StaticConst struct {
	Raw []byte
	// contains filtered or unexported fields
}

StaticConst represents an arbitrary constant bytes which are pooled and emitted by assembler into the binary. These constants can be referenced by instructions.

func NewStaticConst

func NewStaticConst(raw []byte) *StaticConst

NewStaticConst returns the pointer to the new NewStaticConst for given bytes.

func (*StaticConst) AddOffsetFinalizedCallback

func (s *StaticConst) AddOffsetFinalizedCallback(cb func(offsetOfConstInBinary uint64))

AddOffsetFinalizedCallback adds a callback into offsetFinalizedCallbacks.

func (*StaticConst) SetOffsetInBinary

func (s *StaticConst) SetOffsetInBinary(offset uint64)

SetOffsetInBinary finalizes the offset of this StaticConst, and invokes callbacks.

type StaticConstPool

type StaticConstPool struct {
	// FirstUseOffsetInBinary holds the offset of the first instruction which accesses this const pool .
	FirstUseOffsetInBinary *NodeOffsetInBinary
	Consts                 []*StaticConst

	// PoolSizeInBytes is the current size of the pool in bytes.
	PoolSizeInBytes int
	// contains filtered or unexported fields
}

StaticConstPool holds a bulk of StaticConst which are yet to be emitted into the binary.

func NewStaticConstPool

func NewStaticConstPool() *StaticConstPool

NewStaticConstPool returns the pointer to a new StaticConstPool.

func (*StaticConstPool) AddConst

func (p *StaticConstPool) AddConst(c *StaticConst, useOffset NodeOffsetInBinary)

AddConst adds a *StaticConst into the pool if it's not already added.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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