Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not allow inline VirtualImmediate* instantiations #6852

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading