compile

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2019 License: BSD-3-Clause Imports: 13 Imported by: 0

Documentation

Overview

Package compile is used internally by wagon to convert standard structured WebAssembly bytecode into an unstructured form suitable for execution by it's VM. The conversion process consists of translating block instruction sequences and branch operators (br, br_if, br_table) to absolute jumps to PC values. For instance, an instruction sequence like:

loop
  i32.const 1
  get_local 0
  i32.add
  set_local 0
  get_local 1
  i32.const 1
  i32.add
  tee_local 1
  get_local 2
  i32.eq
  br_if 0
end

Is "compiled" to:

i32.const 1
i32.add
set_local 0
get_local 1
i32.const 1
i32.add
tee_local 1
get_local 2
i32.eq
jmpnz <addr> <preserve> <discard>

Where jmpnz is a jump-if-not-zero operator that takes certain arguments plus the jump address as immediates. This is in contrast with original WebAssembly bytecode, where the target of branch operators are relative block depths instead.

Index

Constants

View Source
const (
	// APushWasmStack is a symbolic instruction representing the movement
	// of a value in an x86-64 register, to the top of the WASM stack.
	APushWasmStack = x86.ALAST + iota
	// APopWasmStack is a symbolic instruction representing the movement
	// of the top of the WASM stack, to a value in an x86-64 register.
	APopWasmStack
	// ALoadGlobalsSliceHeader is a symbolic instruction representing that
	// the slice header for wasm globals should be loaded into R15. This
	// allows us to defer instruction generation till later phases, so
	// this instruction can be a NOP if already loaded.
	ALoadGlobalsSliceHeader
	// ALoadLocalsFirstElem is a symbolic instruction representing that
	// the first wasm should be loaded into R15. This allows us to defer
	// instruction generation till later phases, so this instruction can
	// be a NOP if already loaded.
	ALoadLocalsFirstElem
	// AFlushStackLength is a symbolic instruction representing that
	// the WASM stack length should be flushed from registers to main memory,
	// if it is dirty.
	AFlushStackLength
)

Variables

View Source
var (
	// OpJmp unconditionally jumps to the provided address.
	OpJmp byte = 0x0c
	// OpJmpZ jumps to the given address if the value at the top of the stack is zero.
	OpJmpZ byte = 0x03
	// OpJmpNz jumps to the given address if the value at the top of the
	// stack is not zero. It also discards elements and optionally preserves
	// the topmost value on the stack
	OpJmpNz byte = 0x0d
	// OpDiscard discards a given number of elements from the execution stack.
	OpDiscard byte = 0x0b
	// OpDiscardPreserveTop discards a given number of elements from the
	// execution stack, while preserving the value on the top of the stack.
	OpDiscardPreserveTop byte = 0x05
)

Functions

This section is empty.

Types

type AMD64Backend

type AMD64Backend struct {
	EmitBoundsChecks bool
	// contains filtered or unexported fields
}

AMD64Backend is the native compiler backend for x86-64 architectures.

func (*AMD64Backend) Build

func (b *AMD64Backend) Build(candidate CompilationCandidate, code []byte, meta *BytecodeMetadata) ([]byte, error)

Build implements exec.instructionBuilder.

func (*AMD64Backend) Scanner

func (b *AMD64Backend) Scanner() *scanner

Scanner returns a scanner that can be used for emitting compilation candidates.

type BranchTable

type BranchTable struct {
	Targets       []Target // A list of targets, br_table pops an int value, and jumps to Targets[val]
	DefaultTarget Target   // If val > len(Targets), the VM will jump here
	// contains filtered or unexported fields
}

BranchTable is the structure pointed to by a rewritten br_table instruction. A rewritten br_table instruction is of the format:

br_table <table_index>

where <table_index> is the index to an array of BranchTable objects stored by the VM.

type BytecodeMetadata

type BytecodeMetadata struct {
	BranchTables []*BranchTable
	Instructions []InstructionMetadata

	// Inbound jumps - used by the AOT/JIT scanner to
	// avoid generating native code which has an inbound
	// jump target somewhere deep inside.
	InboundTargets map[int64]struct{}
}

BytecodeMetadata encapsulates metadata about a bytecode stream.

func Compile

func Compile(disassembly []disasm.Instr) ([]byte, *BytecodeMetadata)

Compile rewrites WebAssembly bytecode from its disassembly. TODO(vibhavp): Add options for optimizing code. Operators like i32.reinterpret/f32 are no-ops, and can be safely removed.

type CompilationCandidate

type CompilationCandidate struct {
	Start            uint    // Bytecode index of the first opcode.
	End              uint    // Bytecode index of the last byte in the instruction.
	StartInstruction int     // InstructionMeta index of the first instruction.
	EndInstruction   int     // InstructionMeta index of the last instruction.
	Metrics          Metrics // Metrics about the instructions between first & last index.
}

CompilationCandidate describes a range of bytecode that can be translated to native code.

func (*CompilationCandidate) Bounds

func (s *CompilationCandidate) Bounds() (uint, uint)

Bounds returns the beginning & end index in the bytecode which this candidate would replace. The end index is not inclusive.

type CompletionStatus

type CompletionStatus uint64

CompletionStatus describes the final status of a native execution.

const (
	CompletionOK CompletionStatus = iota
	CompletionBadBounds
	CompletionUnreachable
	CompletionFatalInternalError
)

Valid completion statuses.

type InstructionMetadata

type InstructionMetadata struct {
	Op byte
	// Start represents the byte offset of this instruction
	// in the function's instruction stream.
	Start int
	// Size is the number of bytes in the instruction stream
	// needed to represent this instruction.
	Size int
}

InstructionMetadata describes a bytecode instruction.

type JITExitSignal

type JITExitSignal uint64

JITExitSignal is the value returned from the execution of a native section. The bits of this packed 64bit value is encoded as follows: [00:04] Completion Status [04:08] Reserved [08:32] Index of the WASM instruction where the exit occurred. [32:64] Status-specific 32bit value.

func (JITExitSignal) CompletionStatus

func (s JITExitSignal) CompletionStatus() CompletionStatus

CompletionStatus decodes and returns the completion status of the exit.

func (JITExitSignal) Index

func (s JITExitSignal) Index() int

Index returns the index to the instruction where the exit happened. 0xffffff is returned if the exit was due to normal completion.

type MMapAllocator

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

MMapAllocator copies instructions into executable memory.

func (*MMapAllocator) AllocateExec

func (a *MMapAllocator) AllocateExec(asm []byte) (NativeCodeUnit, error)

AllocateExec allocates a block of executable memory with the given code contained.

func (*MMapAllocator) Close

func (a *MMapAllocator) Close() error

Close frees all pages allocated by the allocator.

type Metrics

type Metrics struct {
	MemoryReads, MemoryWrites uint
	StackReads, StackWrites   uint

	AllOps     int
	IntegerOps int
	FloatOps   int
}

Metrics describes the heuristics of an instruction sequence.

type NativeCodeUnit

type NativeCodeUnit interface {
	Invoke(stack, locals, globals *[]uint64, mem *[]byte) JITExitSignal
}

NativeCodeUnit represents compiled native code.

type Target

type Target struct {
	Addr        int64 // The absolute address of the target
	Discard     int64 // The number of elements to discard
	PreserveTop bool  // Whether the top of the stack is to be preserved
	Return      bool  // Whether to return in order to take this branch/target
}

Target is the "target" of a br_table instruction. Unlike other control instructions, br_table does jumps and discarding all by itself.

Jump to

Keyboard shortcuts

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