diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 1c8d3fdd5cc..f91896746fb 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1947,12 +1947,12 @@ fn report_assembly_information( // https://github.com/FuelLabs/sway/blob/afd6a6709e7cb11c676059a5004012cc466e653b/sway-core/src/asm_generation/fuel/data_section.rs#L147 fn calculate_entry_size(entry: &sway_core::asm_generation::Entry) -> u64 { match &entry.value { - sway_core::asm_generation::Datum::Byte(value) => std::mem::size_of_val(value) as u64, + sway_core::asm_generation::Datum::U8(value) => std::mem::size_of_val(value) as u64, + sway_core::asm_generation::Datum::U16(value) => std::mem::size_of_val(value) as u64, + sway_core::asm_generation::Datum::U32(value) => std::mem::size_of_val(value) as u64, + sway_core::asm_generation::Datum::U64(value) => std::mem::size_of_val(value) as u64, - sway_core::asm_generation::Datum::Word(value) => std::mem::size_of_val(value) as u64, - - sway_core::asm_generation::Datum::ByteArray(bytes) - | sway_core::asm_generation::Datum::Slice(bytes) => { + sway_core::asm_generation::Datum::ByRef(bytes) => { if bytes.len() % 8 == 0 { bytes.len() as u64 } else { diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index 43b146583d2..a40e1e5a04f 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -377,7 +377,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "b45b5f58ff2f05c3593ffe4241188c14644aaa1e42dc7defae12b8d09cc6a292", + "654c47c7cc216cd33480712fccf5998ba89874e669ee9b07d4f835f3cba85aba", ) .unwrap(), proxy: None, @@ -421,7 +421,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "b45b5f58ff2f05c3593ffe4241188c14644aaa1e42dc7defae12b8d09cc6a292", + "654c47c7cc216cd33480712fccf5998ba89874e669ee9b07d4f835f3cba85aba", ) .unwrap(), proxy: None, @@ -468,7 +468,7 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "b45b5f58ff2f05c3593ffe4241188c14644aaa1e42dc7defae12b8d09cc6a292", + "654c47c7cc216cd33480712fccf5998ba89874e669ee9b07d4f835f3cba85aba", ) .unwrap(), proxy: Some( diff --git a/forc-plugins/forc-debug/src/server/handlers/handle_variables.rs b/forc-plugins/forc-debug/src/server/handlers/handle_variables.rs index 498413a0a80..185d4cc563e 100644 --- a/forc-plugins/forc-debug/src/server/handlers/handle_variables.rs +++ b/forc-plugins/forc-debug/src/server/handlers/handle_variables.rs @@ -169,8 +169,12 @@ fn ra(instruction: Instruction) -> Option { Instruction::XORI(op) => Some(op.ra()), Instruction::JNEI(op) => Some(op.ra()), Instruction::LB(op) => Some(op.ra()), + Instruction::LQW(op) => Some(op.ra()), + Instruction::LHW(op) => Some(op.ra()), Instruction::LW(op) => Some(op.ra()), Instruction::SB(op) => Some(op.ra()), + Instruction::SQW(op) => Some(op.ra()), + Instruction::SHW(op) => Some(op.ra()), Instruction::SW(op) => Some(op.ra()), Instruction::MCPI(op) => Some(op.ra()), Instruction::GTF(op) => Some(op.ra()), diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index bf94f4ce522..2843602a0f3 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -3,6 +3,7 @@ use super::{ fuel::{checks, data_section::DataSection}, ProgramABI, ProgramKind, }; +use crate::asm_generation::fuel::compiler_constants::EIGHTEEN_BITS; use crate::asm_generation::fuel::data_section::{Datum, Entry, EntryName}; use crate::asm_lang::allocated_ops::{AllocatedInstruction, AllocatedOp, FuelAsmData}; use crate::decl_engine::DeclRefFunction; @@ -180,7 +181,11 @@ fn to_bytecode_mut( // The -4 is because $pc is added in the *next* instruction. let pointer_offset_from_current_instr = offset_to_data_section_in_bytes - offset_from_instr_start + offset_bytes - 4; - data_section.append_pointer(pointer_offset_from_current_instr); + + // If the pointer can't be loaded using a simple MOVI op, we need to use the data section + if pointer_offset_from_current_instr > EIGHTEEN_BITS { + data_section.append_pointer(pointer_offset_from_current_instr); + } } _ => (), } @@ -314,11 +319,11 @@ fn to_bytecode_mut( print!("{}{:#010x} ", " ".repeat(indentation), offset); match &pair.value { - Datum::Byte(w) => println!(".byte i{w}, as hex {w:02X}"), - Datum::Word(w) => { - println!(".word i{w}, as hex be bytes ({:02X?})", w.to_be_bytes()) - } - Datum::ByteArray(bs) => { + Datum::U8(v) => println!(".byte i{}, as hex {:02X}", v, v), + Datum::U16(v) => println!(".quarterword i{}, as hex {:02X?}", v, v.to_be_bytes()), + Datum::U32(v) => println!(".halfword i{}, as hex {:02X?}", v, v.to_be_bytes()), + Datum::U64(v) => println!(".word i{}, as hex {:02X?}", v, v.to_be_bytes()), + Datum::ByRef(bs) => { print!(".bytes as hex ({bs:02X?}), len i{}, as ascii \"", bs.len()); for b in bs { @@ -333,21 +338,6 @@ fn to_bytecode_mut( } println!("\""); } - Datum::Slice(bs) => { - print!(".slice as hex ({bs:02X?}), len i{}, as ascii \"", bs.len()); - - for b in bs { - print!( - "{}", - if *b == b' ' || b.is_ascii_graphic() { - *b as char - } else { - '.' - } - ); - } - println!("\""); - } Datum::Collection(els) => { println!(".collection"); for e in els { diff --git a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs index e63d5da0dda..896dd5afa53 100644 --- a/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs @@ -607,21 +607,14 @@ pub(crate) fn compile_jump( if curr_offset > target_offset { let delta = curr_offset - target_offset - 1; return if far { - let data_id = data_section.insert_data_value(Entry::new_word( - delta + 1, // +1 since the load instruction must be skipped as well - EntryName::NonConfigurable, - None, - )); - vec![ - RealizedOp { - opcode: AllocatedInstruction::LoadDataId( - AllocatedRegister::Constant(ConstantRegister::Scratch), - data_id, - ), - owning_span: owning_span.clone(), - comment: "load far jump target address".into(), - }, + compile_load_integer_constant( + data_section, + AllocatedRegister::Constant(ConstantRegister::Scratch), + delta + 1, // +1 since the load instruction must be skipped as well + "load far jump target address".into(), + owning_span.clone(), + ), RealizedOp { opcode: if let Some(cond_nz) = condition_nonzero { AllocatedInstruction::JNZB( @@ -662,21 +655,14 @@ pub(crate) fn compile_jump( let delta = target_offset - curr_offset - 1; if far { - let data_id = data_section.insert_data_value(Entry::new_word( - delta - 1, - EntryName::NonConfigurable, - None, - )); - vec![ - RealizedOp { - opcode: AllocatedInstruction::LoadDataId( - AllocatedRegister::Constant(ConstantRegister::Scratch), - data_id, - ), - owning_span: owning_span.clone(), - comment: "load far jump target address".into(), - }, + compile_load_integer_constant( + data_section, + AllocatedRegister::Constant(ConstantRegister::Scratch), + delta - 1, + "load far jump target address".into(), + owning_span.clone(), + ), RealizedOp { opcode: if let Some(cond_nz) = condition_nonzero { AllocatedInstruction::JNZF( @@ -746,54 +732,14 @@ pub(crate) fn compile_call_inner( // with the PC register. The overflow cannot occur since programs cannot be 2**60 bytes large. let delta_instr = (delta - 1) * (Instruction::SIZE as u64); - // Attempt MOVI-based approach, that has larger immediate size but doesn't require data section. - if let Ok(imm) = VirtualImmediate18::new(delta_instr, Span::dummy()) { - return vec![ - RealizedOp { - opcode: AllocatedInstruction::MOVI( - AllocatedRegister::Constant(ConstantRegister::Scratch), - imm, - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, - RealizedOp { - opcode: AllocatedInstruction::ADD( - AllocatedRegister::Constant(ConstantRegister::Scratch), - AllocatedRegister::Constant(ConstantRegister::ProgramCounter), - AllocatedRegister::Constant(ConstantRegister::Scratch), - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, - RealizedOp { - opcode: AllocatedInstruction::JAL( - AllocatedRegister::Constant(ConstantRegister::CallReturnAddress), - AllocatedRegister::Constant(ConstantRegister::Scratch), - VirtualImmediate12::new_unchecked(0, "unreachable()"), - ), - owning_span, - comment, - }, - ]; - } - - // if the offset is too large for MOVI, use data section to store the full offset. - let data_id = data_section.insert_data_value(Entry::new_word( - delta_instr, - EntryName::NonConfigurable, - None, - )); - return vec![ - RealizedOp { - opcode: AllocatedInstruction::LoadDataId( - AllocatedRegister::Constant(ConstantRegister::Scratch), - data_id, - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, + compile_load_integer_constant( + data_section, + AllocatedRegister::Constant(ConstantRegister::Scratch), + delta_instr, + "load call target address".into(), + owning_span.clone(), + ), RealizedOp { opcode: AllocatedInstruction::ADD( AllocatedRegister::Constant(ConstantRegister::Scratch), @@ -853,54 +799,14 @@ pub(crate) fn compile_call_inner( // with the PC register. The overflow cannot occur since programs cannot be 2**60 bytes large. let delta_instr = (delta + 1) * (Instruction::SIZE as u64); - // Attempt MOVI-based approach. - if let Ok(imm) = VirtualImmediate18::new(delta_instr, Span::dummy()) { - return vec![ - RealizedOp { - opcode: AllocatedInstruction::MOVI( - AllocatedRegister::Constant(ConstantRegister::Scratch), - imm, - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, - RealizedOp { - opcode: AllocatedInstruction::SUB( - AllocatedRegister::Constant(ConstantRegister::Scratch), - AllocatedRegister::Constant(ConstantRegister::ProgramCounter), - AllocatedRegister::Constant(ConstantRegister::Scratch), - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, - RealizedOp { - opcode: AllocatedInstruction::JAL( - AllocatedRegister::Constant(ConstantRegister::CallReturnAddress), - AllocatedRegister::Constant(ConstantRegister::Scratch), - VirtualImmediate12::new_unchecked(0, "unreachable()"), - ), - owning_span, - comment, - }, - ]; - } - - // And lastly, fall back to the data section backed approach. - let data_id = data_section.insert_data_value(Entry::new_word( - delta_instr, - EntryName::NonConfigurable, - None, - )); - vec![ - RealizedOp { - opcode: AllocatedInstruction::LoadDataId( - AllocatedRegister::Constant(ConstantRegister::Scratch), - data_id, - ), - owning_span: owning_span.clone(), - comment: "load call target address".into(), - }, + compile_load_integer_constant( + data_section, + AllocatedRegister::Constant(ConstantRegister::Scratch), + delta_instr, + "load call target address".into(), + owning_span.clone(), + ), RealizedOp { opcode: AllocatedInstruction::SUB( AllocatedRegister::Constant(ConstantRegister::Scratch), @@ -948,3 +854,54 @@ pub(crate) fn compile_call( } res } + +/// Compiles loading of an integer constant into a register, +/// possibly using the data section if that's more efficient. +pub(crate) fn compile_load_integer_constant( + data_section: &mut DataSection, + register: AllocatedRegister, + value: u64, + comment: String, + owning_span: Option, +) -> RealizedOp { + // Attempt MOVI + if let Ok(imm) = VirtualImmediate18::new(value, Span::dummy()) { + return RealizedOp { + opcode: AllocatedInstruction::MOVI(register, imm), + owning_span, + comment, + }; + } + + // Attempt various tricks for known constants + if value == u64::MAX { + return RealizedOp { + opcode: AllocatedInstruction::NOT( + register, + AllocatedRegister::Constant(ConstantRegister::Zero), + ), + owning_span, + comment, + }; + } + if value == u64::MAX - 1 { + return RealizedOp { + opcode: AllocatedInstruction::NOT( + register, + AllocatedRegister::Constant(ConstantRegister::One), + ), + owning_span, + comment, + }; + } + + // Fall back to the data section backed approach. + let data_id = + data_section.insert_data_value(Entry::new_min_int(value, EntryName::NonConfigurable, None)); + + RealizedOp { + opcode: AllocatedInstruction::LoadDataId(register, data_id), + owning_span, + comment, + } +} diff --git a/sway-core/src/asm_generation/fuel/data_section.rs b/sway-core/src/asm_generation/fuel/data_section.rs index d4edb72d657..eada7f07045 100644 --- a/sway-core/src/asm_generation/fuel/data_section.rs +++ b/sway-core/src/asm_generation/fuel/data_section.rs @@ -31,27 +31,47 @@ pub struct Entry { #[derive(Clone, Debug, serde::Serialize)] pub enum Datum { - Byte(u8), - Word(u64), - ByteArray(Vec), - Slice(Vec), + /// A single byte, loaded into a register. + U8(u8), + /// A quarterword, loaded into a register. + U16(u16), + /// A halfword, loaded into a register. + U32(u32), + /// A word, loaded into a register. + U64(u64), + /// Data behind a pointer. + ByRef(Vec), + /// Collection of entries. Collection(Vec), } impl Entry { - pub(crate) fn new_byte(value: u8, name: EntryName, padding: Option) -> Entry { - Entry { - value: Datum::Byte(value), - padding: padding.unwrap_or(Padding::default_for_u8(value)), - name, - } - } - - pub(crate) fn new_word(value: u64, name: EntryName, padding: Option) -> Entry { - Entry { - value: Datum::Word(value), - padding: padding.unwrap_or(Padding::default_for_u64(value)), - name, + /// Creates smallest integer entry that can hold the value. + pub(crate) fn new_min_int(value: u64, name: EntryName, padding: Option) -> Entry { + if value <= u8::MAX as u64 { + Self { + value: Datum::U8(value as u8), + padding: padding.unwrap_or(Padding::default_for_u8(value as u8)), + name, + } + } else if value <= u16::MAX as u64 { + Self { + value: Datum::U16(value as u16), + padding: padding.unwrap_or(Padding::default_for_u16(value as u16)), + name, + } + } else if value <= u32::MAX as u64 { + Self { + value: Datum::U32(value as u32), + padding: padding.unwrap_or(Padding::default_for_u32(value as u32)), + name, + } + } else { + Self { + value: Datum::U64(value), + padding: padding.unwrap_or(Padding::default_for_u64(value)), + name, + } } } @@ -62,15 +82,7 @@ impl Entry { ) -> Entry { Entry { padding: padding.unwrap_or(Padding::default_for_byte_array(&bytes)), - value: Datum::ByteArray(bytes), - name, - } - } - - pub(crate) fn new_slice(bytes: Vec, name: EntryName, padding: Option) -> Entry { - Entry { - padding: padding.unwrap_or(Padding::default_for_byte_array(&bytes)), - value: Datum::Slice(bytes), + value: Datum::ByRef(bytes), name, } } @@ -110,15 +122,22 @@ impl Entry { // Not an enum, no more special handling required. match &constant.value { - ConstantValue::Undef | ConstantValue::Unit => Entry::new_byte(0, name, padding), - ConstantValue::Bool(value) => Entry::new_byte(u8::from(*value), name, padding), - ConstantValue::Uint(value) => { - if constant.ty.is_uint8(context) { - Entry::new_byte(*value as u8, name, padding) - } else { - Entry::new_word(*value, name, padding) - } - } + // TODO: why ZSTs can be allocated? + ConstantValue::Undef | ConstantValue::Unit => Entry { + value: Datum::U8(0), + padding: padding.unwrap_or(Padding::default_for_u8(0)), + name, + }, + ConstantValue::Bool(value) => Entry { + value: Datum::U8(*value as u8), + padding: padding.unwrap_or(Padding::default_for_u8(0)), + name, + }, + ConstantValue::Uint(value) => Entry { + value: Datum::U64(*value), + padding: padding.unwrap_or(Padding::default_for_u64(0)), + name, + }, ConstantValue::U256(value) => { Entry::new_byte_array(value.to_be_bytes().to_vec(), name, padding) } @@ -126,31 +145,29 @@ impl Entry { Entry::new_byte_array(value.to_be_bytes().to_vec(), name, padding) } ConstantValue::String(bytes) => Entry::new_byte_array(bytes.clone(), name, padding), - ConstantValue::Array(_) => Entry::new_collection( - constant - .array_elements_with_padding(context) - .expect("Constant is an array.") - .into_iter() - .map(|(elem, padding)| { + ConstantValue::Array(elements) => Entry::new_collection( + elements + .iter() + .map(|elem| { Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) }) .collect(), name, padding, ), - ConstantValue::Struct(_) => Entry::new_collection( - constant - .struct_fields_with_padding(context) - .expect("Constant is a struct.") - .into_iter() - .map(|(elem, padding)| { + ConstantValue::Struct(fields) => Entry::new_collection( + fields + .iter() + .map(|elem| { Entry::from_constant(context, elem, EntryName::NonConfigurable, padding) }) .collect(), name, padding, ), - ConstantValue::RawUntypedSlice(bytes) => Entry::new_slice(bytes.clone(), name, padding), + ConstantValue::RawUntypedSlice(bytes) => { + Entry::new_byte_array(bytes.clone(), name, padding) + } ConstantValue::Reference(_) => { todo!("Constant references are currently not supported.") } @@ -164,10 +181,12 @@ impl Entry { pub(crate) fn to_bytes(&self) -> Vec { // Get the big-endian byte representation of the basic value. let bytes = match &self.value { - Datum::Byte(value) => vec![*value], - Datum::Word(value) => value.to_be_bytes().to_vec(), - Datum::ByteArray(bytes) | Datum::Slice(bytes) if bytes.len() % 8 == 0 => bytes.clone(), - Datum::ByteArray(bytes) | Datum::Slice(bytes) => bytes + Datum::U8(value) => vec![*value], + Datum::U16(value) => value.to_be_bytes().to_vec(), + Datum::U32(value) => value.to_be_bytes().to_vec(), + Datum::U64(value) => value.to_be_bytes().to_vec(), + Datum::ByRef(bytes) if bytes.len() % 8 == 0 => bytes.clone(), + Datum::ByRef(bytes) => bytes .iter() .chain([0; 8].iter()) .copied() @@ -188,19 +207,20 @@ impl Entry { } pub(crate) fn has_copy_type(&self) -> bool { - matches!(self.value, Datum::Word(_) | Datum::Byte(_)) - } - - pub(crate) fn is_byte(&self) -> bool { - matches!(self.value, Datum::Byte(_)) + matches!( + self.value, + Datum::U64(_) | Datum::U32(_) | Datum::U16(_) | Datum::U8(_) + ) } pub(crate) fn equiv(&self, entry: &Entry) -> bool { fn equiv_data(lhs: &Datum, rhs: &Datum) -> bool { match (lhs, rhs) { - (Datum::Byte(l), Datum::Byte(r)) => l == r, - (Datum::Word(l), Datum::Word(r)) => l == r, - (Datum::ByteArray(l), Datum::ByteArray(r)) => l == r, + (Datum::U8(l), Datum::U8(r)) => l == r, + (Datum::U16(l), Datum::U16(r)) => l == r, + (Datum::U32(l), Datum::U32(r)) => l == r, + (Datum::U64(l), Datum::U64(r)) => l == r, + (Datum::ByRef(l), Datum::ByRef(r)) => l == r, (Datum::Collection(l), Datum::Collection(r)) => { l.len() == r.len() && l.iter() @@ -219,7 +239,7 @@ impl Entry { } } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum DataIdEntryKind { NonConfigurable, Configurable, @@ -235,7 +255,7 @@ impl fmt::Display for DataIdEntryKind { } /// An address which refers to a value in the data section of the asm. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub(crate) struct DataId { pub(crate) idx: u32, pub(crate) kind: DataIdEntryKind, @@ -278,7 +298,7 @@ impl DataSection { } /// Get entry at id - fn get(&self, id: &DataId) -> Option<&Entry> { + pub(crate) fn get(&self, id: &DataId) -> Option<&Entry> { match id.kind { DataIdEntryKind::NonConfigurable => self.non_configurables.get(id.idx as usize), DataIdEntryKind::Configurable => self.configurables.get(id.idx as usize), @@ -319,11 +339,6 @@ impl DataSection { self.get(id).map(|entry| entry.has_copy_type()) } - /// Returns whether a specific [DataId] value is a byte entry. - pub(crate) fn is_byte(&self, id: &DataId) -> Option { - self.get(id).map(|entry| entry.is_byte()) - } - /// When generating code, sometimes a hard-coded data pointer is needed to reference /// static values that have a length longer than one word. /// This method appends pointers to the end of the data section (thus, not altering the data @@ -332,12 +347,12 @@ impl DataSection { /// relative to the current (load) instruction. pub(crate) fn append_pointer(&mut self, pointer_value: u64) -> DataId { // The 'pointer' is just a literal 64 bit address. - let data_id = self.insert_data_value(Entry::new_word( + let data_id = self.insert_data_value(Entry::new_min_int( pointer_value, EntryName::NonConfigurable, None, )); - self.pointer_id.insert(pointer_value, data_id.clone()); + self.pointer_id.insert(pointer_value, data_id); data_id } @@ -376,19 +391,21 @@ impl DataSection { } } - // If the stored data is Datum::Word, return the inner value. - pub(crate) fn get_data_word(&self, data_id: &DataId) -> Option { - let value_pairs = match data_id.kind { - DataIdEntryKind::NonConfigurable => &self.non_configurables, - DataIdEntryKind::Configurable => &self.configurables, - }; - value_pairs.get(data_id.idx as usize).and_then(|entry| { - if let Datum::Word(w) = entry.value { - Some(w) - } else { - None - } - }) + /// When a load from data section is realized and targets a (register-placeable) copy type, + /// this is the value that will be loaded into the register. + /// For non-copy types or configurable values, returns `None` instead. + pub(crate) fn get_const_reg_value(&self, data_id: DataId) -> Option { + let entry = self.get(&data_id)?; + if matches!(entry.name, EntryName::Configurable(_)) { + return None; + } + match &entry.value { + Datum::U8(v) => Some(*v as u64), + Datum::U16(v) => Some(*v as u64), + Datum::U32(v) => Some(*v as u64), + Datum::U64(v) => Some(*v), + _ => None, + } } } @@ -396,10 +413,11 @@ impl fmt::Display for DataSection { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn display_entry(datum: &Datum) -> String { match datum { - Datum::Byte(w) => format!(".byte {w}"), - Datum::Word(w) => format!(".word {w}"), - Datum::ByteArray(bs) => display_bytes_for_data_section(bs, ".bytes"), - Datum::Slice(bs) => display_bytes_for_data_section(bs, ".slice"), + Datum::U8(v) => format!(".byte {v}"), + Datum::U16(v) => format!(".quarterword {v}"), + Datum::U32(v) => format!(".halfword {v}"), + Datum::U64(v) => format!(".word {v}"), + Datum::ByRef(bs) => display_bytes_for_data_section(bs, ".bytes"), Datum::Collection(els) => format!( ".collection {{ {} }}", els.iter() diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index 08b86dcd2e2..6f73eefaa98 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -1276,7 +1276,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { // Allocate a register for it, and an address_of instruction. let reg = self.reg_seqr.next(); self.cur_bytecode.push(Op { - opcode: either::Either::Left(VirtualOp::AddrDataId(reg.clone(), data_id.clone())), + opcode: either::Either::Left(VirtualOp::AddrDataId(reg.clone(), data_id)), comment: "get constant's address in data section".into(), owning_span: Some(span), }); @@ -1351,7 +1351,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { Some(Storage::Data(data_id)) => { let instr_reg = self.reg_seqr.next(); self.cur_bytecode.push(Op { - opcode: Either::Left(VirtualOp::LoadDataId(instr_reg.clone(), data_id.clone())), + opcode: Either::Left(VirtualOp::LoadDataId(instr_reg.clone(), *data_id)), comment: "get local constant".into(), owning_span, }); @@ -1401,10 +1401,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { // Otherwise it is a configurable with encoding v0 and must be at configurable_v0_data_id let dataid = self.configurable_v0_data_id.get(name).unwrap(); self.cur_bytecode.push(Op { - opcode: either::Either::Left(VirtualOp::AddrDataId( - addr_reg.clone(), - dataid.clone(), - )), + opcode: either::Either::Left(VirtualOp::AddrDataId(addr_reg.clone(), *dataid)), comment: format!("get address of configurable {}", name), owning_span: self.md_mgr.val_to_span(self.context, *addr_val), }); @@ -1464,6 +1461,28 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { owning_span, }); } + 2 => { + self.cur_bytecode.push(Op { + opcode: Either::Left(VirtualOp::LQW( + instr_reg.clone(), + src_reg, + VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"), + )), + comment: "load quadword".into(), + owning_span, + }); + } + 4 => { + self.cur_bytecode.push(Op { + opcode: Either::Left(VirtualOp::LHW( + instr_reg.clone(), + src_reg, + VirtualImmediate12::new_unchecked(0, "Zero must fit in 12 bits"), + )), + comment: "load halfword".into(), + owning_span, + }); + } 8.. => { self.cur_bytecode.push(Op { opcode: Either::Left(VirtualOp::LW( @@ -2138,10 +2157,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { // Allocate a register for it, and a load instruction. let reg = self.reg_seqr.next(); self.cur_bytecode.push(Op { - opcode: either::Either::Left(VirtualOp::LoadDataId( - reg.clone(), - data_id.clone(), - )), + opcode: either::Either::Left(VirtualOp::LoadDataId(reg.clone(), data_id)), comment: "load constant from data section".into(), owning_span: span, }); @@ -2252,7 +2268,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { } } else { let comment = comment.into(); - let data_id = self.data_section.insert_data_value(Entry::new_word( + let data_id = self.data_section.insert_data_value(Entry::new_min_int( imm, EntryName::NonConfigurable, None, diff --git a/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs b/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs index b2c68109fc9..9dd6ebadfae 100644 --- a/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs +++ b/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs @@ -125,7 +125,7 @@ impl AbstractInstructionSet { } } VirtualOp::LoadDataId(dest, data_id) => { - if let Some(c) = data_section.get_data_word(data_id) { + if let Some(c) = data_section.get_const_reg_value(*data_id) { reg_contents.insert(dest.clone(), RegContents::Constant(c)); } else { reg_contents.remove(dest); diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index fe95b4ec993..67e6b53ec01 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -311,7 +311,7 @@ impl AbstractProgram { }; // Put the selector in the data section. - let data_label = self.data_section.insert_data_value(Entry::new_word( + let data_label = self.data_section.insert_data_value(Entry::new_min_int( u32::from_be_bytes(selector) as u64, EntryName::NonConfigurable, None, diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index 3172f09fc9f..7572f333e8f 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -11,9 +11,12 @@ use super::*; use crate::{ - asm_generation::fuel::{ - compiler_constants::DATA_SECTION_REGISTER, - data_section::{DataId, DataSection}, + asm_generation::{ + fuel::{ + compiler_constants::{DATA_SECTION_REGISTER, EIGHTEEN_BITS}, + data_section::{DataId, DataSection}, + }, + Datum, }, fuel_prelude::fuel_asm::{self, op}, }; @@ -161,6 +164,8 @@ pub(crate) enum AllocatedInstruction { CFE(AllocatedRegister), CFS(AllocatedRegister), LB(AllocatedRegister, AllocatedRegister, VirtualImmediate12), + LQW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), + LHW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), LW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), MCL(AllocatedRegister, AllocatedRegister), MCLI(AllocatedRegister, VirtualImmediate18), @@ -177,6 +182,8 @@ pub(crate) enum AllocatedInstruction { POPH(VirtualImmediate24), POPL(VirtualImmediate24), SB(AllocatedRegister, AllocatedRegister, VirtualImmediate12), + SQW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), + SHW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), SW(AllocatedRegister, AllocatedRegister, VirtualImmediate12), /* Contract Instructions */ @@ -366,6 +373,8 @@ impl AllocatedInstruction { CFE(_r1) => vec![], CFS(_r1) => vec![], LB(r1, _r2, _i) => vec![r1], + LQW(r1, _r2, _i) => vec![r1], + LHW(r1, _r2, _i) => vec![r1], LW(r1, _r2, _i) => vec![r1], MCL(_r1, _r2) => vec![], MCLI(_r1, _imm) => vec![], @@ -376,6 +385,8 @@ impl AllocatedInstruction { panic!("Cannot determine defined registers for register PUSH/POP instructions") } SB(_r1, _r2, _i) => vec![], + SQW(_r1, _r2, _i) => vec![], + SHW(_r1, _r2, _i) => vec![], SW(_r1, _r2, _i) => vec![], /* Contract Instructions */ @@ -498,6 +509,8 @@ impl fmt::Display for AllocatedInstruction { CFE(a) => write!(fmtr, "cfe {a}"), CFS(a) => write!(fmtr, "cfs {a}"), LB(a, b, c) => write!(fmtr, "lb {a} {b} {c}"), + LQW(a, b, c) => write!(fmtr, "lqw {a} {b} {c}"), + LHW(a, b, c) => write!(fmtr, "lhw {a} {b} {c}"), LW(a, b, c) => write!(fmtr, "lw {a} {b} {c}"), MCL(a, b) => write!(fmtr, "mcl {a} {b}"), MCLI(a, b) => write!(fmtr, "mcli {a} {b}"), @@ -509,6 +522,8 @@ impl fmt::Display for AllocatedInstruction { POPH(mask) => write!(fmtr, "poph {mask}"), POPL(mask) => write!(fmtr, "popl {mask}"), SB(a, b, c) => write!(fmtr, "sb {a} {b} {c}"), + SQW(a, b, c) => write!(fmtr, "sqw {a} {b} {c}"), + SHW(a, b, c) => write!(fmtr, "shw {a} {b} {c}"), SW(a, b, c) => write!(fmtr, "sw {a} {b} {c}"), /* Contract Instructions */ @@ -704,6 +719,8 @@ impl AllocatedOp { CFE(a) => op::CFE::new(a.to_reg_id()).into(), CFS(a) => op::CFS::new(a.to_reg_id()).into(), LB(a, b, c) => op::LB::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), + LQW(a, b, c) => op::LQW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), + LHW(a, b, c) => op::LHW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), LW(a, b, c) => op::LW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), MCL(a, b) => op::MCL::new(a.to_reg_id(), b.to_reg_id()).into(), MCLI(a, b) => op::MCLI::new(a.to_reg_id(), b.value().into()).into(), @@ -717,6 +734,8 @@ impl AllocatedOp { POPH(mask) => op::POPH::new(mask.value().into()).into(), POPL(mask) => op::POPL::new(mask.value().into()).into(), SB(a, b, c) => op::SB::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), + SQW(a, b, c) => op::SQW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), + SHW(a, b, c) => op::SHW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), SW(a, b, c) => op::SW::new(a.to_reg_id(), b.to_reg_id(), c.value().into()).into(), /* Contract Instructions */ @@ -855,7 +874,7 @@ fn addr_of( /// Converts a virtual load word instruction which uses data labels into one which uses /// actual bytewise offsets for use in bytecode. /// Returns one op if the type is less than one word big, but two ops if it has to construct -/// a pointer and add it to $is. +/// a pointer and add it to $pc. fn realize_load( dest: &AllocatedRegister, data_id: &DataId, @@ -863,81 +882,125 @@ fn realize_load( offset_to_data_section: u64, offset_from_instr_start: u64, ) -> Vec { - // if this data is larger than a word, instead of loading the data directly - // into the register, we want to load a pointer to the data into the register - // this appends onto the data section and mutates it by adding the pointer as a literal - let has_copy_type = data_section.has_copy_type(data_id).expect( + let entry = data_section.get(data_id).expect( "Internal miscalculation in data section -- data id did not match up to any actual data", ); - - let is_byte = data_section.is_byte(data_id).expect( - "Internal miscalculation in data section -- data id did not match up to any actual data", - ); - - // all data is word-aligned right now, and `offset_to_id` returns the offset in bytes let offset_bytes = data_section.data_id_to_offset(data_id) as u64; - assert!( - offset_bytes % 8 == 0, - "Internal miscalculation in data section -- data offset is not aligned to a word", - ); - let offset_words = offset_bytes / 8; - let imm = VirtualImmediate12::new( - if is_byte { offset_bytes } else { offset_words }, - Span::new(" ".into(), 0, 0, None).unwrap(), - ); - let offset = match imm { - Ok(value) => value, - Err(_) => panic!( - "Unable to offset into the data section more than 2^12 bits. \ - Unsupported data section length: {} words.", - offset_words - ), - }; - - if !has_copy_type { - // load the pointer itself into the register. `offset_to_data_section` is in bytes. - // The -4 is because $pc is added in the *next* instruction. - let pointer_offset_from_current_instr = - offset_to_data_section - offset_from_instr_start + offset_bytes - 4; - - // insert the pointer as bytes as a new data section entry at the end of the data - let data_id_for_pointer = data_section - .data_id_of_pointer(pointer_offset_from_current_instr) - .expect("Pointer offset must be in data_section"); - - // now load the pointer we just created into the `dest`ination - let mut buf = Vec::with_capacity(2); - buf.append(&mut realize_load( - dest, - &data_id_for_pointer, - data_section, - offset_to_data_section, - offset_from_instr_start, - )); - // add $pc to the pointer since it is relative to the current instruction. - buf.push( - fuel_asm::op::ADD::new( + match entry.value { + Datum::U8(_) => { + let Ok(imm) = VirtualImmediate12::new(offset_bytes, Span::dummy()) else { + panic!( + "Data section offset {} too large of 12 bit offset of u8 units.", + offset_bytes + ); + }; + vec![fuel_asm::op::LB::new( dest.to_reg_id(), + fuel_asm::RegId::new(DATA_SECTION_REGISTER), + imm.value().into(), + ) + .into()] + } + Datum::U16(_) => { + assert!( + offset_bytes % 2 == 0, + "Internal miscalculation in data section -- invalid alignment for u16 data", + ); + let Ok(imm) = VirtualImmediate12::new(offset_bytes / 2, Span::dummy()) else { + panic!( + "Data section offset {} too large of 12 bit offset of u16 units.", + offset_bytes + ); + }; + vec![fuel_asm::op::LQW::new( dest.to_reg_id(), - ConstantRegister::ProgramCounter.to_reg_id(), + fuel_asm::RegId::new(DATA_SECTION_REGISTER), + imm.value().into(), ) - .into(), - ); - buf - } else if is_byte { - vec![fuel_asm::op::LB::new( - dest.to_reg_id(), - fuel_asm::RegId::new(DATA_SECTION_REGISTER), - offset.value().into(), - ) - .into()] - } else { - vec![fuel_asm::op::LW::new( - dest.to_reg_id(), - fuel_asm::RegId::new(DATA_SECTION_REGISTER), - offset.value().into(), - ) - .into()] + .into()] + } + Datum::U32(_) => { + assert!( + offset_bytes % 4 == 0, + "Internal miscalculation in data section -- invalid alignment for u16 data", + ); + let Ok(imm) = VirtualImmediate12::new(offset_bytes / 4, Span::dummy()) else { + panic!( + "Data section offset {} too large of 12 bit offset of u32 units.", + offset_bytes + ); + }; + vec![fuel_asm::op::LHW::new( + dest.to_reg_id(), + fuel_asm::RegId::new(DATA_SECTION_REGISTER), + imm.value().into(), + ) + .into()] + } + Datum::U64(_) => { + assert!( + offset_bytes % 8 == 0, + "Internal miscalculation in data section -- invalid alignment for u16 data", + ); + let Ok(imm) = VirtualImmediate12::new(offset_bytes / 8, Span::dummy()) else { + panic!( + "Data section offset {} too large of 12 bit offset of u64 units.", + offset_bytes + ); + }; + vec![fuel_asm::op::LW::new( + dest.to_reg_id(), + fuel_asm::RegId::new(DATA_SECTION_REGISTER), + imm.value().into(), + ) + .into()] + } + _ => { + // if this data is larger than a word, instead of loading the data directly + // into the register, we want to load a pointer to the data into the register + // this appends onto the data section and mutates it by adding the pointer as a literal + + // load the pointer itself into the register. `offset_to_data_section` is in bytes. + // The -4 is because $pc is added in the *next* instruction. + let pointer_offset_from_current_instr = + offset_to_data_section - offset_from_instr_start + offset_bytes - 4; + + // now load the pointer we just created into the `dest`ination + let mut buf = Vec::with_capacity(2); + + // load the value of pointer offset + if pointer_offset_from_current_instr <= EIGHTEEN_BITS { + buf.push( + fuel_asm::op::MOVI::new( + dest.to_reg_id(), + Imm18::new(pointer_offset_from_current_instr as u32), + ) + .into(), + ) + } else { + let data_id_for_pointer = data_section + .data_id_of_pointer(pointer_offset_from_current_instr) + .expect("Pointer offset must be in data_section"); + buf.append(&mut realize_load( + dest, + &data_id_for_pointer, + data_section, + offset_to_data_section, + offset_from_instr_start, + )); + } + + // add $pc to the pointer since it is relative to the current instruction. + buf.push( + fuel_asm::op::ADD::new( + dest.to_reg_id(), + dest.to_reg_id(), + ConstantRegister::ProgramCounter.to_reg_id(), + ) + .into(), + ); + buf + } } } diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index 14f22fd6bef..ba51f29cf65 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -15,7 +15,7 @@ pub(crate) use virtual_ops::*; pub(crate) use virtual_register::*; use crate::{ - asm_generation::fuel::{data_section::DataId, register_allocator::RegisterPool}, + asm_generation::fuel::register_allocator::RegisterPool, asm_lang::allocated_ops::{AllocatedInstruction, AllocatedRegister}, language::AsmRegister, Ident, @@ -163,18 +163,6 @@ impl Op { owning_span: Some(owning_span), } } - /// Loads the data from [DataId] `data` into [VirtualRegister] `reg`. - pub(crate) fn unowned_load_data_comment( - reg: VirtualRegister, - data: DataId, - comment: impl Into, - ) -> Self { - Op { - opcode: Either::Left(VirtualOp::LoadDataId(reg, data)), - comment: comment.into(), - owning_span: None, - } - } /// Given a label, creates the actual asm line to put in the ASM which represents a label. /// Also attaches a comment to it. @@ -1194,6 +1182,8 @@ impl fmt::Display for VirtualOp { CFE(_sp, a) => write!(fmtr, "cfe {a}"), CFS(_sp, a) => write!(fmtr, "cfs {a}"), LB(a, b, c) => write!(fmtr, "lb {a} {b} {c}"), + LQW(a, b, c) => write!(fmtr, "lqw {a} {b} {c}"), + LHW(a, b, c) => write!(fmtr, "lhw {a} {b} {c}"), LW(a, b, c) => write!(fmtr, "lw {a} {b} {c}"), MCL(a, b) => write!(fmtr, "mcl {a} {b}"), MCLI(a, b) => write!(fmtr, "mcli {a} {b}"), @@ -1201,6 +1191,8 @@ impl fmt::Display for VirtualOp { MCPI(a, b, c) => write!(fmtr, "mcpi {a} {b} {c}"), MEQ(a, b, c, d) => write!(fmtr, "meq {a} {b} {c} {d}"), SB(a, b, c) => write!(fmtr, "sb {a} {b} {c}"), + SQW(a, b, c) => write!(fmtr, "sqw {a} {b} {c}"), + SHW(a, b, c) => write!(fmtr, "shw {a} {b} {c}"), SW(a, b, c) => write!(fmtr, "sw {a} {b} {c}"), /* Contract Instructions */ diff --git a/sway-core/src/asm_lang/virtual_ops.rs b/sway-core/src/asm_lang/virtual_ops.rs index 135567e4090..3decf5b7588 100644 --- a/sway-core/src/asm_lang/virtual_ops.rs +++ b/sway-core/src/asm_lang/virtual_ops.rs @@ -116,6 +116,8 @@ pub(crate) enum VirtualOp { CFE(VirtualRegister, VirtualRegister), CFS(VirtualRegister, VirtualRegister), LB(VirtualRegister, VirtualRegister, VirtualImmediate12), + LQW(VirtualRegister, VirtualRegister, VirtualImmediate12), + LHW(VirtualRegister, VirtualRegister, VirtualImmediate12), LW(VirtualRegister, VirtualRegister, VirtualImmediate12), MCL(VirtualRegister, VirtualRegister), MCLI(VirtualRegister, VirtualImmediate18), @@ -128,6 +130,8 @@ pub(crate) enum VirtualOp { VirtualRegister, ), SB(VirtualRegister, VirtualRegister, VirtualImmediate12), + SQW(VirtualRegister, VirtualRegister, VirtualImmediate12), + SHW(VirtualRegister, VirtualRegister, VirtualImmediate12), SW(VirtualRegister, VirtualRegister, VirtualImmediate12), /* Contract Instructions */ @@ -316,6 +320,8 @@ impl VirtualOp { CFE(sp, r1) => vec![sp, r1], CFS(sp, r1) => vec![sp, r1], LB(r1, r2, _i) => vec![r1, r2], + LQW(r1, r2, _i) => vec![r1, r2], + LHW(r1, r2, _i) => vec![r1, r2], LW(r1, r2, _i) => vec![r1, r2], MCL(r1, r2) => vec![r1, r2], MCLI(r1, _imm) => vec![r1], @@ -323,6 +329,8 @@ impl VirtualOp { MCPI(r1, r2, _imm) => vec![r1, r2], MEQ(r1, r2, r3, r4) => vec![r1, r2, r3, r4], SB(r1, r2, _i) => vec![r1, r2], + SQW(r1, r2, _i) => vec![r1, r2], + SHW(r1, r2, _i) => vec![r1, r2], SW(r1, r2, _i) => vec![r1, r2], /* Contract Instructions */ @@ -420,6 +428,8 @@ impl VirtualOp { | XORI(_, _, _) // Memory load | LB(_, _, _) + | LQW(_, _, _) + | LHW(_, _, _) | LW(_, _, _) // Blockchain read | BAL(_, _, _) @@ -461,6 +471,8 @@ impl VirtualOp { | MCPI(_, _, _) | MEQ(_, _, _, _) | SB(_, _, _) + | SQW(_, _, _) + | SHW(_, _, _) | SW(_, _, _) // Other blockchain etc ... | BHSH(_, _) @@ -563,6 +575,8 @@ impl VirtualOp { | JAL(_, _, _) | RET(_) | LB(_, _, _) + | LQW(_, _, _) + | LHW(_, _, _) | LW(_, _, _) | MCL(_, _) | MCLI(_, _) @@ -570,6 +584,8 @@ impl VirtualOp { | MCPI(_, _, _) | MEQ(_, _, _, _) | SB(_, _, _) + | SQW(_, _, _) + | SHW(_, _, _) | SW(_, _, _) | BAL(_, _, _) | BHEI(_) @@ -678,6 +694,8 @@ impl VirtualOp { CFE(sp, r1) => vec![sp, r1], CFS(sp, r1) => vec![sp, r1], LB(_r1, r2, _i) => vec![r2], + LQW(_r1, r2, _i) => vec![r2], + LHW(_r1, r2, _i) => vec![r2], LW(_r1, r2, _i) => vec![r2], MCL(r1, r2) => vec![r1, r2], MCLI(r1, _imm) => vec![r1], @@ -685,6 +703,8 @@ impl VirtualOp { MCPI(r1, r2, _imm) => vec![r1, r2], MEQ(_r1, r2, r3, r4) => vec![r2, r3, r4], SB(r1, r2, _i) => vec![r1, r2], + SQW(r1, r2, _i) => vec![r1, r2], + SHW(r1, r2, _i) => vec![r1, r2], SW(r1, r2, _i) => vec![r1, r2], /* Contract Instructions */ @@ -806,6 +826,8 @@ impl VirtualOp { CFE(sp, r1) => vec![sp, r1], CFS(sp, r1) => vec![sp, r1], LB(_r1, r2, _i) => vec![r2], + LQW(_r1, r2, _i) => vec![r2], + LHW(_r1, r2, _i) => vec![r2], LW(_r1, r2, _i) => vec![r2], MCL(r1, r2) => vec![r1, r2], MCLI(r1, _imm) => vec![r1], @@ -813,6 +835,8 @@ impl VirtualOp { MCPI(r1, r2, _imm) => vec![r1, r2], MEQ(_r1, r2, r3, r4) => vec![r2, r3, r4], SB(r1, r2, _i) => vec![r1, r2], + SQW(r1, r2, _i) => vec![r1, r2], + SHW(r1, r2, _i) => vec![r1, r2], SW(r1, r2, _i) => vec![r1, r2], /* Contract Instructions */ @@ -932,6 +956,8 @@ impl VirtualOp { CFE(sp, _r1) => vec![sp], CFS(sp, _r1) => vec![sp], LB(r1, _r2, _i) => vec![r1], + LHW(r1, _r2, _i) => vec![r1], + LQW(r1, _r2, _i) => vec![r1], LW(r1, _r2, _i) => vec![r1], MCL(_r1, _r2) => vec![], MCLI(_r1, _imm) => vec![], @@ -939,6 +965,8 @@ impl VirtualOp { MCPI(_r1, _r2, _imm) => vec![], MEQ(r1, _r2, _r3, _r4) => vec![r1], SB(_r1, _r2, _i) => vec![], + SQW(_r1, _r2, _i) => vec![], + SHW(_r1, _r2, _i) => vec![], SW(_r1, _r2, _i) => vec![], /* Contract Instructions */ @@ -1244,6 +1272,16 @@ impl VirtualOp { update_reg(reg_to_reg_map, r2), i.clone(), ), + LQW(r1, r2, i) => Self::LQW( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + i.clone(), + ), + LHW(r1, r2, i) => Self::LHW( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + i.clone(), + ), LW(r1, r2, i) => Self::LW( update_reg(reg_to_reg_map, r1), update_reg(reg_to_reg_map, r2), @@ -1275,6 +1313,16 @@ impl VirtualOp { update_reg(reg_to_reg_map, r2), i.clone(), ), + SQW(r1, r2, i) => Self::SQW( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + i.clone(), + ), + SHW(r1, r2, i) => Self::SHW( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + i.clone(), + ), SW(r1, r2, i) => Self::SW( update_reg(reg_to_reg_map, r1), update_reg(reg_to_reg_map, r2), @@ -1462,8 +1510,8 @@ impl VirtualOp { BLOB(i) => Self::BLOB(i.clone()), DataSectionOffsetPlaceholder => Self::DataSectionOffsetPlaceholder, ConfigurablesOffsetPlaceholder => Self::ConfigurablesOffsetPlaceholder, - LoadDataId(r1, i) => Self::LoadDataId(update_reg(reg_to_reg_map, r1), i.clone()), - AddrDataId(r1, i) => Self::AddrDataId(update_reg(reg_to_reg_map, r1), i.clone()), + LoadDataId(r1, i) => Self::LoadDataId(update_reg(reg_to_reg_map, r1), *i), + AddrDataId(r1, i) => Self::AddrDataId(update_reg(reg_to_reg_map, r1), *i), Undefined => Self::Undefined, } } @@ -1757,6 +1805,16 @@ impl VirtualOp { map_reg(&mapping, reg2), imm.clone(), ), + LQW(reg1, reg2, imm) => AllocatedInstruction::LQW( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + imm.clone(), + ), + LHW(reg1, reg2, imm) => AllocatedInstruction::LHW( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + imm.clone(), + ), LW(reg1, reg2, imm) => AllocatedInstruction::LW( map_reg(&mapping, reg1), map_reg(&mapping, reg2), @@ -1787,6 +1845,16 @@ impl VirtualOp { map_reg(&mapping, reg2), imm.clone(), ), + SQW(reg1, reg2, imm) => AllocatedInstruction::SQW( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + imm.clone(), + ), + SHW(reg1, reg2, imm) => AllocatedInstruction::SHW( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + imm.clone(), + ), SW(reg1, reg2, imm) => AllocatedInstruction::SW( map_reg(&mapping, reg1), map_reg(&mapping, reg2), @@ -1967,10 +2035,10 @@ impl VirtualOp { DataSectionOffsetPlaceholder => AllocatedInstruction::DataSectionOffsetPlaceholder, ConfigurablesOffsetPlaceholder => AllocatedInstruction::ConfigurablesOffsetPlaceholder, LoadDataId(reg1, label) => { - AllocatedInstruction::LoadDataId(map_reg(&mapping, reg1), label.clone()) + AllocatedInstruction::LoadDataId(map_reg(&mapping, reg1), *label) } AddrDataId(reg1, label) => { - AllocatedInstruction::AddrDataId(map_reg(&mapping, reg1), label.clone()) + AllocatedInstruction::AddrDataId(map_reg(&mapping, reg1), *label) } Undefined => AllocatedInstruction::Undefined, } diff --git a/sway-ir/src/constant.rs b/sway-ir/src/constant.rs index c91fcf5efbb..0e4028ae4c9 100644 --- a/sway-ir/src/constant.rs +++ b/sway-ir/src/constant.rs @@ -229,8 +229,8 @@ impl ConstantContent { debug_assert!(tag_and_value_with_paddings.len() == 2, "In case of enums, `elements_of_aggregate_with_padding` must return exactly two elements, the tag and the value."); - let tag = tag_and_value_with_paddings[0].clone(); - let value = tag_and_value_with_paddings[1].clone(); + let tag = tag_and_value_with_paddings[0]; + let value = tag_and_value_with_paddings[1]; Some((tag, value)) } diff --git a/sway-ir/src/irtype.rs b/sway-ir/src/irtype.rs index 9457442ff3f..84ddebdb8ab 100644 --- a/sway-ir/src/irtype.rs +++ b/sway-ir/src/irtype.rs @@ -259,6 +259,11 @@ impl Type { matches!(*self.get_content(context), TypeContent::Uint(8)) } + /// Is u16 type + pub fn is_uint16(&self, context: &Context) -> bool { + matches!(*self.get_content(context), TypeContent::Uint(16)) + } + /// Is u32 type pub fn is_uint32(&self, context: &Context) -> bool { matches!(*self.get_content(context), TypeContent::Uint(32)) @@ -574,11 +579,9 @@ impl Type { TypeContent::Uint(8) | TypeContent::Bool | TypeContent::Unit | TypeContent::Never => { TypeSize::new(1) } - // All integers larger than a byte are words since FuelVM only has memory operations on those two units. - TypeContent::Uint(16) - | TypeContent::Uint(32) - | TypeContent::Uint(64) - | TypeContent::Pointer(_) => TypeSize::new(8), + TypeContent::Uint(16) => TypeSize::new(2), + TypeContent::Uint(32) => TypeSize::new(4), + TypeContent::Uint(64) | TypeContent::Pointer(_) => TypeSize::new(8), TypeContent::Uint(256) => TypeSize::new(32), TypeContent::Uint(_) => unreachable!(), TypeContent::Slice => TypeSize::new(16), @@ -663,7 +666,7 @@ impl TypeSize { /// the value in aggregates. E.g., in an array of `u8`, each `u8` is "padded" /// to its size of one byte while as a struct field, it will be right padded /// to 8 bytes. -#[derive(Clone, Debug, serde::Serialize)] +#[derive(Clone, Copy, Debug, serde::Serialize)] pub enum Padding { Left { target_size: usize }, Right { target_size: usize }, @@ -676,6 +679,18 @@ impl Padding { Self::Right { target_size: 1 } } + /// Returns the default [Padding] for `u16`. + pub fn default_for_u16(_value: u16) -> Self { + // Dummy _value is used only to ensure correct usage at the call site. + Self::Right { target_size: 2 } + } + + /// Returns the default [Padding] for `u32`. + pub fn default_for_u32(_value: u32) -> Self { + // Dummy _value is used only to ensure correct usage at the call site. + Self::Right { target_size: 4 } + } + /// Returns the default [Padding] for `u64`. pub fn default_for_u64(_value: u64) -> Self { // Dummy _value is used only to ensure correct usage at the call site. @@ -738,32 +753,26 @@ mod tests { } #[test] - /// `u8`, when not embedded in aggregates, has a size of 1 byte. - fn unsigned_u8() { + /// Aligned size is always 8 bytes, while unaligned is the size of the type. + fn unsigned_u8_u16_u32_u64() { let context = create_context(); let s_u8 = Type::get_uint8(&context).size(&context); - - assert_eq!(s_u8.in_bytes(), 1); - } - - #[test] - /// `u16`, `u32`, and `u64,`, when not embedded in aggregates, have a size of 8 bytes/1 word. - fn unsigned_u16_u32_u64() { - let context = create_context(); - let s_u16 = Type::get_uint16(&context).size(&context); let s_u32 = Type::get_uint32(&context).size(&context); let s_u64 = Type::get_uint64(&context).size(&context); - assert_eq!(s_u16.in_bytes(), 8); - assert_eq!(s_u16.in_bytes(), s_u16.in_bytes_aligned()); + assert_eq!(s_u8.in_bytes(), 1); + assert_eq!(s_u8.in_bytes_aligned(), 8); + + assert_eq!(s_u16.in_bytes(), 2); + assert_eq!(s_u16.in_bytes_aligned(), 8); - assert_eq!(s_u32.in_bytes(), 8); - assert_eq!(s_u32.in_bytes(), s_u32.in_bytes_aligned()); + assert_eq!(s_u32.in_bytes(), 4); + assert_eq!(s_u32.in_bytes_aligned(), 8); assert_eq!(s_u64.in_bytes(), 8); - assert_eq!(s_u64.in_bytes(), s_u64.in_bytes_aligned()); + assert_eq!(s_u64.in_bytes_aligned(), 8); } #[test] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap index 917acd0ea92..00fde4dbd0e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap @@ -182,4 +182,4 @@ warning: Function is deprecated ____ Compiled contract "attributes_deprecated" with 19 warnings. - Finished release [optimized + fuel] target(s) [752 B] in ??? + Finished release [optimized + fuel] target(s) [736 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics/stdout.snap index 026154da3a2..ee27fc1d966 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics/stdout.snap @@ -292,7 +292,7 @@ output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics Compiling library std (sway-lib-std) Compiling script const_generics (test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics) - Finished debug [unoptimized + fuel] target(s) [6.952 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [6.704 KB] in ??? Running 1 test, filtered 0 tests tested -- const_generics diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap index 425ff9f7d8e..e3d2f454ee3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap @@ -71,7 +71,7 @@ output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg Compiling library std (sway-lib-std) Compiling script dbg (test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg) - Finished debug [unoptimized + fuel] target(s) [41.536 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [39.824 KB] in ??? Running 1 test, filtered 0 tests tested -- dbg diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panic_handling_in_unit_tests/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panic_handling_in_unit_tests/stdout.snap index 8ffa778d6dc..d6931dc8f8a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panic_handling_in_unit_tests/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panic_handling_in_unit_tests/stdout.snap @@ -18,7 +18,7 @@ warning: Error message is empty ____ Compiled script "panic_handling_in_unit_tests" with 1 warning. - Finished debug [unoptimized + fuel] target(s) [9.504 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [9.208 KB] in ??? Running 2 tests, filtered 18 tests tested -- panic_handling_in_unit_tests @@ -55,7 +55,7 @@ warning: Error message is empty ____ Compiled script "panic_handling_in_unit_tests" with 1 warning. - Finished debug [unoptimized + fuel] target(s) [9.504 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [9.208 KB] in ??? Running 20 tests, filtered 0 tests tested -- panic_handling_in_unit_tests diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap index 9a314ba012e..0b27461ddc1 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap @@ -8,78 +8,78 @@ output: Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) Compiling contract panicking_contract (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract) - Finished release [optimized + fuel] target(s) [7.936 KB] in ??? + Finished release [optimized + fuel] target(s) [7.656 KB] in ??? Running 11 tests, filtered 0 tests tested -- panicking_contract - test test_directly_panicking_method ... ok (???, 1595 gas) + test test_directly_panicking_method ... ok (???, 1594 gas) revert code: ffffffff00000000 ├─ panic message: Error C. ├─ panic value: C(true) └─ panicked in: panicking_contract@1.2.3, src/main.sw:22:9 decoded log values: C(true), log rb: 5503570629422409978 - test test_nested_panic_inlined ... ok (???, 2913 gas) + test test_nested_panic_inlined ... ok (???, 2912 gas) revert code: ffffffff00000005 ├─ panic message: Error E. ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) └─ panicked in: panicking_lib, src/lib.sw:41:9 decoded log values: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 - test test_nested_panic_inlined_same_revert_code ... ok (???, 2913 gas) + test test_nested_panic_inlined_same_revert_code ... ok (???, 2912 gas) revert code: ffffffff00000005 ├─ panic message: Error E. ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) └─ panicked in: panicking_lib, src/lib.sw:41:9 decoded log values: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 - test test_nested_panic_not_inlined ... ok (???, 3110 gas) + test test_nested_panic_not_inlined ... ok (???, 3109 gas) revert code: ffffffff00000006 ├─ panic message: Error E. ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) └─ panicked in: panicking_lib, src/lib.sw:35:5 decoded log values: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 - test test_nested_panic_not_inlined_same_revert_code ... ok (???, 3110 gas) + test test_nested_panic_not_inlined_same_revert_code ... ok (???, 3109 gas) revert code: ffffffff00000006 ├─ panic message: Error E. ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) └─ panicked in: panicking_lib, src/lib.sw:35:5 decoded log values: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 - test test_generic_panic_with_unit ... ok (???, 2035 gas) + test test_generic_panic_with_unit ... ok (???, 2034 gas) revert code: ffffffff00000004 ├─ panic value: () └─ panicked in: panicking_lib, src/lib.sw:74:5 decoded log values: (), log rb: 3330666440490685604 - test test_generic_panic_with_unit_same_revert_code ... ok (???, 2035 gas) + test test_generic_panic_with_unit_same_revert_code ... ok (???, 2034 gas) revert code: ffffffff00000004 ├─ panic value: () └─ panicked in: panicking_lib, src/lib.sw:74:5 decoded log values: (), log rb: 3330666440490685604 - test test_generic_panic_with_str ... ok (???, 2057 gas) + test test_generic_panic_with_str ... ok (???, 2056 gas) revert code: ffffffff00000002 ├─ panic message: generic panic with string └─ panicked in: panicking_lib, src/lib.sw:74:5 decoded log values: AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 - test test_generic_panic_with_different_str_same_revert_code ... ok (???, 1730 gas) + test test_generic_panic_with_different_str_same_revert_code ... ok (???, 1729 gas) revert code: ffffffff00000002 ├─ panic message: generic panic with different string └─ panicked in: panicking_lib, src/lib.sw:74:5 decoded log values: AsciiString { data: "generic panic with different string" }, log rb: 10098701174489624218 - test test_generic_panic_with_error_type_enum ... ok (???, 1854 gas) + test test_generic_panic_with_error_type_enum ... ok (???, 1853 gas) revert code: ffffffff00000003 ├─ panic message: Error A. ├─ panic value: A └─ panicked in: panicking_lib, src/lib.sw:74:5 decoded log values: A, log rb: 5503570629422409978 - test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 2023 gas) + test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 2022 gas) revert code: ffffffff00000003 ├─ panic message: Error B. ├─ panic value: B(42) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap index db5fd53c34d..2e9a7b39491 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap @@ -7,7 +7,7 @@ output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) - Finished release [optimized + fuel] target(s) [5.68 KB] in ??? + Finished release [optimized + fuel] target(s) [5.648 KB] in ??? Running 18 tests, filtered 0 tests tested -- panicking_lib diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap index eee575f29ec..cb65d9bafa9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap @@ -8,7 +8,7 @@ output: Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) Compiling script panicking_script (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script) - Finished release [optimized + fuel] target(s) [3.712 KB] in ??? + Finished release [optimized + fuel] target(s) [3.68 KB] in ??? Running 11 tests, filtered 0 tests tested -- panicking_script diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index fc75db79229..cdb3ec09f5b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x14ed3cd06c2947248f69d54bfa681fe40d26267be84df7e19e253622b7921bbe; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xf106a79029b4b175cbd3c403328947431c4cc39913d5c03bb88011a190cf7cd1; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0x0e2a44193851f9d58b1fe0b96de2f585831f98fefe82d2cc9fb3611db3a70d30; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw index 307328179f3..ca2dd7931e8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw @@ -9,12 +9,12 @@ use test_fuel_coin_abi::*; #[cfg(experimental_new_encoding = false)] const FUEL_COIN_CONTRACT_ID = 0xec2277ebe007ade87e3d797c3b1e070dcd542d5ef8f038b471f262ef9cebc87c; #[cfg(experimental_new_encoding = true)] -const FUEL_COIN_CONTRACT_ID = 0x8476fc28f7ae3cad8b654176dc9f72417d4ddf0fbb9da24ade268e9ae8b82933; // AUTO-CONTRACT-ID ../../test_contracts/test_fuel_coin_contract --release +const FUEL_COIN_CONTRACT_ID = 0xd32bbc84ccf4377593fa5c65d45c5db8e6985e168eefa406210db89f812a1d4c; // AUTO-CONTRACT-ID ../../test_contracts/test_fuel_coin_contract --release #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0x49460391f59d838a381add127bd3bc47a840c18e78d55df0d332159dfb01acfa; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xd2460efc3154f67c36ef1b15f55b42e079cda8bfa5e0a47dd681206e10061154; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let default_gas = 1_000_000_000_000; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw index 9894df5918f..b6be6f9a459 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw @@ -5,7 +5,7 @@ use balance_test_abi::BalanceTest; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x49460391f59d838a381add127bd3bc47a840c18e78d55df0d332159dfb01acfa; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xd2460efc3154f67c36ef1b15f55b42e079cda8bfa5e0a47dd681206e10061154; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let balance_test_contract = abi(BalanceTest, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw index 93b6083a9a4..6a24fe72325 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw @@ -6,7 +6,7 @@ use abi_with_tuples::{MyContract, Location, Person}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xfdc14550c8aee742cd556d0ab7f378b7be0d3b1e6e086c097352e94590d4ed02; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xa2a538dd3a09bda5ded434a7c4f7b91dd1c7ac8e1a74ef14693224bf210a7474; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0xbefa77c8410c41546d12d69e521284e6ac9c3226c8b68515c94ba3b808d93bd6; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release fn main() -> bool { let the_abi = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw index 4ca06290859..ab34a2fb569 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw @@ -4,7 +4,7 @@ use basic_storage_abi::{BasicStorage, Quad}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x94db39f409a31b9f2ebcadeea44378e419208c20de90f5d8e1e33dc1523754cb; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xcd95389a1c96d7527caf131a0758986c6733375387b222ead91edebc2f8dbbc8; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0xe606cb3dc0cab1a135c91ea8d3ca9716353b2a20fd50aca8b7662e36e02ae765; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release fn main() -> u64 { let addr = abi(BasicStorage, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw index 476cb77a81d..4bdd36eb6e9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x0cbeb6efe3104b460be769bdc4ea101ebf16ccc16f2d7b667ec3e1c7f5ce35b5; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x1f4cb193e171334b5a19715805957e5f2076b1cb8ae2b2579eb8bbce5fce310f; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0xf569be058a703b44320391849a2739081bb6df8aa120a1689cf5785c3f4dd40e; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release fn main() { let caller = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw index 254a6a7538e..02442283e87 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw @@ -6,7 +6,7 @@ use dynamic_contract_call::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xd1b4047af7ef111c023ab71069e01dc2abfde487c0a0ce1268e4f447e6c6e4c2; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xcea7265b9985e45584844a3e473f77396b9d2b19c5e82449b8d0403d6b1bc019; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0xfe4662688024dd97fc3d61ce32ba76a6ba86fb6471c4f713c8ca7ba820acc1da; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release fn main() -> bool { let the_abi = abi(Incrementor, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw index dde53847ab2..be4aa419e54 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw @@ -5,7 +5,7 @@ use storage_enum_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc601d11767195485a6654d566c67774134668863d8c797a8c69e8778fb1f89e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x3223c0382a2ba0ba6a98d9f389776ba7595ef7396e007911fc7ee6c2d1a465d9; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x8a62c72e1a272f34c876380815634100d6e6f483c0a8380c155b4af5da63e7e6; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release fn main() -> u64 { let caller = abi(StorageEnum, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw index 203afd03b22..958875a9495 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw @@ -5,7 +5,7 @@ use auth_testing_abi::AuthTesting; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc2eec20491b53aab7232cbd27c31d15417b4e9daf0b89c74cc242ef1295f681f; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x3c940400fecfb98fb14ade0e76b1f115cdb92a829c7eb0349de88326fb910fa8; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xbf960f601c08a56aa63ee5aff94bde2af2f5a0a941640b67a63458c17f28ebf7; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release // should be false in the case of a script fn main() -> bool { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw index 35c5b895910..e4724fffd28 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw @@ -6,7 +6,7 @@ use context_testing_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x6054c11cda000f5990373a4d61929396165be4dfdd61d5b7bd26da60ab0d8577; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x4b93165110ed4cd9b85b1f5127fa1e6330138baa82cb8fa1fe101678c6e57a78; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x736f038b079e17f7c0baddfc6aba4a943c84e1b3786ec55379387e51a91da30a; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release fn main() -> bool { let gas: u64 = u64::max(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw index 20140f48667..e712a148773 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw @@ -5,7 +5,7 @@ use nested_struct_args_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xe63d33a1b3a6903808b379f6a41a72fa8a370e8b76626775e7d9d2f9c4c5da40; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x8dbe4018418007f05e643cbed3e95e1fce0a83f9dd651fee9ec73924f856c8bb; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0x405e9416f613caab229589ed4997ea15a12775653bcd558b6c75c7354a12bbac; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release fn main() -> bool { let caller = abi(NestedStructArgs, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw index 05d0712a148..7a8881841cc 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x3bc28acd66d327b8c1b9624c1fabfc07e9ffa1b5d71c2832c3bfaaf8f4b805e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x0a882ead5e3f817cfa18d79828117b38a4cb2f3ca82eee2fa7530665bf0f8ace; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0x514ab1a5bd29ce475bf75f70c873ab1d1346c72d09528db6b024650b45695666; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/ir_generation/tests/simple_contract.sw b/test/src/ir_generation/tests/simple_contract.sw index ae79851d32e..6c8ea42de85 100644 --- a/test/src/ir_generation/tests/simple_contract.sw +++ b/test/src/ir_generation/tests/simple_contract.sw @@ -69,6 +69,6 @@ impl Test for Contract { // check: lw $REG $$fp i74 // check: .data: -// check: $get_b256_sel_data .word 1108491158 -// check: $get_s_sel_data .word 4234334249 -// check: $get_u64_sel_data .word 2559618804 +// check: $get_b256_sel_data .halfword 1108491158 +// check: $get_s_sel_data .halfword 4234334249 +// check: $get_u64_sel_data .halfword 2559618804