sway_core/asm_generation/fuel/
abstract_instruction_set.rs

1use sway_error::error::CompileError;
2
3use crate::asm_lang::{allocated_ops::AllocatedOp, Op, RealizedOp};
4
5use std::fmt;
6
7use super::{
8    allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, register_allocator,
9};
10
11/// An [AbstractInstructionSet] is a set of instructions that use entirely virtual registers
12/// and excessive moves, with the intention of later optimizing it.
13#[derive(Clone)]
14pub struct AbstractInstructionSet {
15    pub(crate) ops: Vec<Op>,
16}
17
18impl AbstractInstructionSet {
19    /// Allocate registers.
20    pub(crate) fn allocate_registers(
21        self,
22    ) -> Result<AllocatedAbstractInstructionSet, CompileError> {
23        register_allocator::allocate_registers(&self.ops)
24    }
25}
26
27impl fmt::Display for AbstractInstructionSet {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        write!(
30            f,
31            ".program:\n{}",
32            self.ops
33                .iter()
34                .map(|x| format!("{x}"))
35                .collect::<Vec<_>>()
36                .join("\n")
37        )
38    }
39}
40
41/// "Realized" here refers to labels -- there are no more organizational
42/// ops or labels. In this struct, they are all "realized" to offsets.
43pub struct RealizedAbstractInstructionSet {
44    pub(super) ops: Vec<RealizedOp>,
45}
46
47impl RealizedAbstractInstructionSet {
48    pub(crate) fn allocated_ops(self) -> Vec<AllocatedOp> {
49        self.ops
50            .into_iter()
51            .map(
52                |RealizedOp {
53                     opcode,
54                     comment,
55                     owning_span,
56                 }| {
57                    AllocatedOp {
58                        opcode,
59                        comment,
60                        owning_span,
61                    }
62                },
63            )
64            .collect::<Vec<_>>()
65    }
66}