Skip to content

Commit

Permalink
Do not allow inline VirtualImmediate* instantiations
Browse files Browse the repository at this point in the history
  • Loading branch information
vaivaswatha committed Jan 22, 2025
1 parent 7aa59f9 commit 8313784
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 192 deletions.
4 changes: 2 additions & 2 deletions sway-core/src/asm_generation/finalized_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ fn to_bytecode_mut(
}
AllocatedOpcode::ConfigurablesOffsetPlaceholder => 8,
AllocatedOpcode::DataSectionOffsetPlaceholder => 8,
AllocatedOpcode::BLOB(count) => count.value as u64 * 4,
AllocatedOpcode::CFEI(i) | AllocatedOpcode::CFSI(i) if i.value == 0 => 0,
AllocatedOpcode::BLOB(count) => count.value() as u64 * 4,
AllocatedOpcode::CFEI(i) | AllocatedOpcode::CFSI(i) if i.value() == 0 => 0,
_ => 4,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl AllocatedAbstractInstructionSet {
let remove = match &op.opcode {
// `cfei i0` and `cfsi i0` pairs.
Either::Left(AllocatedOpcode::CFEI(imm))
| Either::Left(AllocatedOpcode::CFSI(imm)) => imm.value == 0u32,
| Either::Left(AllocatedOpcode::CFSI(imm)) => imm.value() == 0u32,
// `cfe $zero` and `cfs $zero` pairs.
Either::Left(AllocatedOpcode::CFE(reg))
| Either::Left(AllocatedOpcode::CFS(reg)) => reg.is_zero(),
Expand Down Expand Up @@ -145,14 +145,14 @@ impl AllocatedAbstractInstructionSet {
.collect::<Vec<_>>();

let (mask_l, mask_h) = generate_mask(&regs);
if mask_l.value != 0 {
if mask_l.value() != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::PSHL(mask_l)),
comment: "save registers 16..40".into(),
owning_span: op.owning_span.clone(),
});
}
if mask_h.value != 0 {
if mask_h.value() != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::PSHH(mask_h)),
comment: "save registers 40..64".into(),
Expand All @@ -171,14 +171,14 @@ impl AllocatedAbstractInstructionSet {
.collect::<Vec<_>>();

let (mask_l, mask_h) = generate_mask(&regs);
if mask_h.value != 0 {
if mask_h.value() != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::POPH(mask_h)),
comment: "restore registers 40..64".into(),
owning_span: op.owning_span.clone(),
});
}
if mask_l.value != 0 {
if mask_l.value() != 0 {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::POPL(mask_l)),
comment: "restore registers 16..40".into(),
Expand Down Expand Up @@ -334,7 +334,7 @@ impl AllocatedAbstractInstructionSet {
opcode: AllocatedOpcode::SRLI(
r1.clone(),
r1.clone(),
VirtualImmediate12 { value: 2 },
VirtualImmediate12::new_unchecked(2, "two must fit in 12 bits"),
),
owning_span: owning_span.clone(),
comment: "get current instruction offset in 32-bit words".into(),
Expand Down Expand Up @@ -469,13 +469,13 @@ impl AllocatedAbstractInstructionSet {
// cfei 0 and cfsi 0 are omitted from asm emission, don't count them for offsets
Either::Left(AllocatedOpcode::CFEI(ref op))
| Either::Left(AllocatedOpcode::CFSI(ref op))
if op.value == 0 =>
if op.value() == 0 =>
{
0
}

// Another special case for the blob opcode, used for testing.
Either::Left(AllocatedOpcode::BLOB(ref count)) => count.value as u64,
Either::Left(AllocatedOpcode::BLOB(ref count)) => count.value() as u64,

// These ops will end up being exactly one op, so the cur_offset goes up one.
Either::Right(Jump(..) | JumpIfNotZero(..) | Call(..) | LoadLabel(..))
Expand Down Expand Up @@ -612,15 +612,15 @@ impl AllocatedAbstractInstructionSet {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::JMPB(
AllocatedRegister::Constant(ConstantRegister::Scratch),
VirtualImmediate18 { value: 0 },
VirtualImmediate18::new_unchecked(0, "zero must fit in 18 bits"),
)),
..op
});
} else {
new_ops.push(AllocatedAbstractOp {
opcode: Either::Left(AllocatedOpcode::JMPF(
AllocatedRegister::Constant(ConstantRegister::Scratch),
VirtualImmediate18 { value: 0 },
VirtualImmediate18 ::new_unchecked(0, "zero must fit in 18 bits"),
)),
..op
});
Expand Down Expand Up @@ -656,7 +656,7 @@ impl AllocatedAbstractInstructionSet {
opcode: Either::Left(AllocatedOpcode::JNZB(
r1.clone(),
AllocatedRegister::Constant(ConstantRegister::Scratch),
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "zero must fit in 12 bits"),
)),
..op
});
Expand All @@ -665,7 +665,7 @@ impl AllocatedAbstractInstructionSet {
opcode: Either::Left(AllocatedOpcode::JNZF(
r1.clone(),
AllocatedRegister::Constant(ConstantRegister::Scratch),
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "zero must fit in 12 bits"),
)),
..op
});
Expand Down
11 changes: 4 additions & 7 deletions sway-core/src/asm_generation/fuel/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ use sway_error::{
};
use sway_types::Span;

use crate::asm_lang::{
allocated_ops::{AllocatedOp, AllocatedOpcode},
VirtualImmediate18,
};
use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode};

/// Checks if an opcode is one that cannot be executed from within a script.
/// If so, throw an error.
Expand All @@ -31,8 +28,8 @@ pub(crate) fn check_script_opcodes(
// Preemptively avoids the creation of scripts with opcodes not allowed at runtime.
handler.scope(|handler| {
for op in ops {
match op.opcode {
GM(_, VirtualImmediate18 { value: 1..=2 }) => {
match &op.opcode {
GM(_, imm) if (1..=2).contains(&imm.value()) => {
handler.emit_err(CompileError::GMFromExternalContext {
span: get_op_span(op),
});
Expand Down Expand Up @@ -102,7 +99,7 @@ pub(crate) fn check_predicate_opcodes(
CCP(..) => invalid_opcode("CCP"),
CROO(..) => invalid_opcode("CROO"),
CSIZ(..) => invalid_opcode("CSIZ"),
GM(_, VirtualImmediate18 { value: 1..=2 }) => {
GM(_, imm) if (1..=2).contains(&imm.value()) => {
handler.emit_err(CompileError::GMFromExternalContext {
span: get_op_span(op),
});
Expand Down
62 changes: 35 additions & 27 deletions sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,10 @@ impl AsmBuilder for FuelAsmBuilder<'_, '_> {
opcode: Either::Left(VirtualOp::ADDI(
VirtualRegister::Constant(ConstantRegister::FuncArg1),
VirtualRegister::Constant(ConstantRegister::Zero),
VirtualImmediate12 {
value: encoded_bytes.len() as u16,
},
VirtualImmediate12::new_unchecked(
encoded_bytes.len() as u64,
"Error representing encoded_bytes length as 12-bit immediate",
),
)),
comment: format!("get length of configurable {} default value", name),
owning_span: None,
Expand All @@ -153,9 +154,10 @@ impl AsmBuilder for FuelAsmBuilder<'_, '_> {
opcode: Either::Left(VirtualOp::ADDI(
VirtualRegister::Constant(ConstantRegister::FuncArg2),
VirtualRegister::Constant(ConstantRegister::StackStartPointer),
VirtualImmediate12 {
value: global.offset_in_bytes as u16,
},
VirtualImmediate12::new_unchecked(
global.offset_in_bytes,
"Error representing global offset as 12-bit immediate",
),
)),
comment: format!("get pointer to configurable {} stack address", name),
owning_span: None,
Expand Down Expand Up @@ -698,7 +700,10 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::XORI(
res_reg.clone(),
res_reg.clone(),
VirtualImmediate12 { value: 1 },
VirtualImmediate12::new_unchecked(
1,
"Error representing 1 as 12-bit immediate",
),
)),
comment: "[bitcast to bool]: invert inverted boolean".into(),
owning_span: self.md_mgr.val_to_span(self.context, *instr_val),
Expand Down Expand Up @@ -1278,7 +1283,10 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::MULI(
instr_reg.clone(),
instr_reg.clone(),
VirtualImmediate12 { value: 8u16 },
VirtualImmediate12::new_unchecked(
8,
"Error representing 8 as 12-bit immediate",
),
)),
comment: "get byte offset to local from base".into(),
owning_span: owning_span.clone(),
Expand Down Expand Up @@ -1345,9 +1353,10 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: either::Either::Left(VirtualOp::ADDI(
addr_reg.clone(),
VirtualRegister::Constant(ConstantRegister::StackStartPointer),
VirtualImmediate12 {
value: g.offset_in_bytes as u16,
},
VirtualImmediate12::new_unchecked(
g.offset_in_bytes,
"offset must fit in 12 bits",
),
)),
comment: format!("get address of configurable {}", name),
owning_span: self.md_mgr.val_to_span(self.context, *addr_val),
Expand Down Expand Up @@ -1382,9 +1391,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: either::Either::Left(VirtualOp::GTF(
instr_reg.clone(),
index_reg,
VirtualImmediate12 {
value: tx_field_id as u16,
},
VirtualImmediate12::new_unchecked(tx_field_id, "tx_field_id must fit in 12 bits"),
)),
comment: "get transaction field".into(),
owning_span: self.md_mgr.val_to_span(self.context, *instr_val),
Expand Down Expand Up @@ -1416,7 +1423,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LB(
instr_reg.clone(),
src_reg,
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"),
)),
comment: "load byte".into(),
owning_span,
Expand All @@ -1427,7 +1434,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LW(
instr_reg.clone(),
src_reg,
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"),
)),
comment: "load word".into(),
owning_span,
Expand Down Expand Up @@ -1479,9 +1486,10 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MOVI(
len_reg.clone(),
VirtualImmediate18 {
value: byte_len as u32,
},
VirtualImmediate18::new_unchecked(
byte_len,
"cannot fit byte length in 18 bits",
),
)),
comment: "get data length for memory copy".into(),
owning_span: owning_span.clone(),
Expand Down Expand Up @@ -1555,7 +1563,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LW(
ptr_reg.clone(),
log_val_reg.clone(),
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "zero must fit in 12 bits"),
)),
owning_span: owning_span.clone(),
comment: "load slice pointer for logging data".into(),
Expand All @@ -1564,7 +1572,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LW(
size_reg.clone(),
log_val_reg.clone(),
VirtualImmediate12 { value: 1 },
VirtualImmediate12::new_unchecked(1, "one must fit in 12 bits"),
)),
owning_span: owning_span.clone(),
comment: "load slice size for logging data".into(),
Expand Down Expand Up @@ -1675,7 +1683,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LW(
size_reg.clone(),
ret_reg.clone(),
VirtualImmediate12 { value: 1 },
VirtualImmediate12::new_unchecked(1, "one must fit in 12 bits"),
)),
owning_span: owning_span.clone(),
comment: "load size of returned slice".into(),
Expand All @@ -1684,7 +1692,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::LW(
ret_reg.clone(),
ret_reg.clone(),
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "zero must fit in 12 bits"),
)),
owning_span: owning_span.clone(),
comment: "load pointer to returned slice".into(),
Expand Down Expand Up @@ -2004,7 +2012,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::SB(
dst_reg,
val_reg,
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"),
)),
comment: "store byte".into(),
owning_span,
Expand All @@ -2015,7 +2023,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
opcode: Either::Left(VirtualOp::SW(
dst_reg,
val_reg,
VirtualImmediate12 { value: 0 },
VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"),
)),
comment: "store word".into(),
owning_span,
Expand Down Expand Up @@ -2179,7 +2187,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
reg,
#[allow(clippy::unnecessary_unwrap)]
base.unwrap().clone(),
VirtualImmediate12 { value: imm as u16 },
VirtualImmediate12::new_unchecked(imm, "immediate must fit in 12 bits"),
)),
comment: comment.into(),
owning_span: span,
Expand All @@ -2189,7 +2197,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MOVI(
reg.clone(),
VirtualImmediate18 { value: imm as u32 },
VirtualImmediate18::new_unchecked(imm, "immediate must fit in 12 bits"),
)),
comment: comment.clone(),
owning_span: span.clone(),
Expand Down
Loading

0 comments on commit 8313784

Please sign in to comment.