asm

package
v0.0.0-...-29e2939 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 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 giga bytes of native JITed 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 assmembler that the next node must be
	// assigned to the given nodes'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 calcualted offsets into pre-allocated
	// `table` slice in litte endian.
	//
	// TODO: This can be hidden into assembler implementation after golang-asm removal.
	BuildJumpTable(table []byte, 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
	// CompileJumpToMemory adds jump-type instruction whose destination is stored in the memory address specified by `baseReg+offset`,
	// and returns the corresponding Node in the assembled linked list.
	CompileJumpToMemory(jmpInstruction Instruction, baseReg Register, offset ConstantValue)
	// 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 a 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. Note: this interface is coupled and heavily influenced by golang-asm's API (i.e. Go's official assembler). Therefore, we will do the refactoring after golang-asm removal.

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 []byte, 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 conditinal state, and can be used to indicate that no conditional state is specificed.

type ConstantValue

type ConstantValue = int64

ConstantValue represents a constant value used in an instruction.

type Instruction

type Instruction byte

Instruction represents architecture-specific instructions.

type NewAssembler

type NewAssembler func(temporaryRegister Register) (AssemblerBase, error)

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 constnat as the destination
	// of the instruction for this node.
	AssignDestinationConstant(value ConstantValue)
	// AssignSourceConstant assigns the given constnat 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.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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