1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
struct BranchLabel: Equatable {
let label: Label
var index: LabelIndex
}
/// See spec's
/// [definition](https://webassembly.github.io/spec/core/text/instructions.html?highlight=pseudo#control-instructions).
/// > The `block`, `loop` and `if` instructions are structured instructions. They bracket nested sequences of
/// > instructions, called blocks, terminated with, or separated by, end or else pseudo-instructions. As the
/// > grammar prescribes, they must be well-nested.
enum PseudoInstruction {
case `else`
case end
}
struct InstructionSequence: Equatable {
let instructions: UnsafeBufferPointer<Instruction>
init(instructions: [Instruction]) {
assert(_isPOD(Instruction.self))
let buffer = UnsafeMutableBufferPointer<Instruction>.allocate(capacity: instructions.count + 1)
for (idx, instruction) in instructions.enumerated() {
buffer[idx] = instruction
}
buffer[instructions.count] = .endOfFunction
self.instructions = UnsafeBufferPointer(buffer)
}
func deallocate() {
instructions.deallocate()
}
var baseAddress: UnsafePointer<Instruction> {
self.instructions.baseAddress!
}
static func == (lhs: InstructionSequence, rhs: InstructionSequence) -> Bool {
lhs.instructions.baseAddress == rhs.instructions.baseAddress
}
}
extension InstructionSequence: ExpressibleByArrayLiteral {
init(arrayLiteral elements: Instruction...) {
self.init(instructions: elements)
}
}
struct ExpressionRef: Equatable {
let _relativeOffset: UInt32
var relativeOffset: Int {
Int(_relativeOffset)
}
init(_ relativeOffset: Int) {
self._relativeOffset = UInt32(relativeOffset)
}
}
/// > Note:
/// <https://webassembly.github.io/spec/core/syntax/instructions.html#expressions>
typealias Expression = [Instruction]
|