diff --git a/docs/book/src/reference/compiler_intrinsics.md b/docs/book/src/reference/compiler_intrinsics.md index a8126bec0c4..80de9d623c3 100644 --- a/docs/book/src/reference/compiler_intrinsics.md +++ b/docs/book/src/reference/compiler_intrinsics.md @@ -319,11 +319,9 @@ __not(op: T) -> T ___ ```sway -__jmpb_ssp(offset: u64) +__jmp_mem() ``` -**Description:** Jumps to `$ssp - offset`. When the offset is the growth -of `$ssp` after an `ldc` call, this transfers control to the newly loaded -contract. +**Description:** Jumps to `MEM[$hp]`. -**Constraints:** offset must have type `u64`. +**Constraints:** None. diff --git a/docs/reference/src/code/operations/namespace/src/lib.sw b/docs/reference/src/code/operations/namespace/src/lib.sw index bc807cee588..b6f15db9896 100644 --- a/docs/reference/src/code/operations/namespace/src/lib.sw +++ b/docs/reference/src/code/operations/namespace/src/lib.sw @@ -2,12 +2,12 @@ library; // ANCHOR: address pub struct Address { - value: b256, + bits: b256, } // ANCHOR_END: address // ANCHOR: contract_id pub struct ContractId { - value: b256, + bits: b256, } // ANCHOR_END: contract_id // ANCHOR: identity diff --git a/examples/liquidity_pool/src/main.sw b/examples/liquidity_pool/src/main.sw index a834f2a4e65..e6e26286017 100644 --- a/examples/liquidity_pool/src/main.sw +++ b/examples/liquidity_pool/src/main.sw @@ -19,9 +19,7 @@ abi LiquidityPool { fn withdraw(recipient: Address); } -const BASE_ASSET: AssetId = AssetId { - value: 0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c, -}; +const BASE_ASSET: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c); impl LiquidityPool for Contract { fn deposit(recipient: Address) { diff --git a/examples/signatures/src/main.sw b/examples/signatures/src/main.sw index 3764581ebc1..50f0e6bb88e 100644 --- a/examples/signatures/src/main.sw +++ b/examples/signatures/src/main.sw @@ -15,7 +15,7 @@ fn main() { // A recovered Fuel address. let result_address: Result = ec_recover_address(signature, MSG_HASH); if let Ok(address) = result_address { - log(address.value); + log(address.bits()); } else { revert(0); } diff --git a/sway-ast/src/intrinsics.rs b/sway-ast/src/intrinsics.rs index f2ca2817a63..f7bef855e45 100644 --- a/sway-ast/src/intrinsics.rs +++ b/sway-ast/src/intrinsics.rs @@ -35,7 +35,7 @@ pub enum Intrinsic { PtrSub, Smo, Not, - JmpbSsp, + JmpMem, } impl fmt::Display for Intrinsic { @@ -74,7 +74,7 @@ impl fmt::Display for Intrinsic { Intrinsic::PtrSub => "ptr_sub", Intrinsic::Smo => "smo", Intrinsic::Not => "not", - Intrinsic::JmpbSsp => "jmpb_ssp", + Intrinsic::JmpMem => "jmp_mem", }; write!(f, "{s}") } @@ -117,7 +117,7 @@ impl Intrinsic { "__ptr_sub" => PtrSub, "__smo" => Smo, "__not" => Not, - "__jmpb_ssp" => JmpbSsp, + "__jmp_mem" => JmpMem, _ => return None, }) } 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 13b699a3d92..004f09ef271 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -305,7 +305,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { arg2, arg3, } => self.compile_wide_modular_op(instr_val, op, result, arg1, arg2, arg3), - FuelVmInstruction::JmpbSsp(offset) => self.compile_jmpb_ssp(instr_val, offset), + FuelVmInstruction::JmpMem => self.compile_jmp_mem(instr_val), }, InstOp::GetElemPtr { base, @@ -1452,45 +1452,44 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { Ok(()) } - fn compile_jmpb_ssp(&mut self, instr_val: &Value, offset: &Value) -> Result<(), CompileError> { + fn compile_jmp_mem(&mut self, instr_val: &Value) -> Result<(), CompileError> { let owning_span = self.md_mgr.val_to_span(self.context, *instr_val); - let offset_reg = self.value_to_register(offset)?; - let is_offset_reg = self.reg_seqr.next(); - let prev_ssp_reg = self.reg_seqr.next(); + let target_reg = self.reg_seqr.next(); + let is_target_reg = self.reg_seqr.next(); let by4_reg = self.reg_seqr.next(); self.cur_bytecode.push(Op { owning_span: owning_span.clone(), - opcode: Either::Left(VirtualOp::SUB( - prev_ssp_reg.clone(), - VirtualRegister::Constant(ConstantRegister::StackStartPointer), - offset_reg, + opcode: Either::Left(VirtualOp::LW( + target_reg.clone(), + VirtualRegister::Constant(ConstantRegister::HeapPointer), + VirtualImmediate12::new(0, Span::dummy()).unwrap(), )), - comment: "jmpb_ssp: Compute $ssp - offset".into(), + comment: "jmp_mem: Load MEM[$hp]".into(), }); self.cur_bytecode.push(Op { owning_span: owning_span.clone(), opcode: Either::Left(VirtualOp::SUB( - is_offset_reg.clone(), - prev_ssp_reg, + is_target_reg.clone(), + target_reg, VirtualRegister::Constant(ConstantRegister::InstructionStart), )), - comment: "jmpb_ssp: Subtract $is since $jmp adds it back.".into(), + comment: "jmp_mem: Subtract $is since Jmp adds it back.".into(), }); self.cur_bytecode.push(Op { owning_span: owning_span.clone(), opcode: Either::Left(VirtualOp::DIVI( by4_reg.clone(), - is_offset_reg.clone(), + is_target_reg.clone(), VirtualImmediate12::new(4, Span::dummy()).unwrap(), )), - comment: "jmpb_ssp: Divide by 4 since Jmp multiplies by 4.".into(), + comment: "jmp_mem: Divide by 4 since Jmp multiplies by 4.".into(), }); self.cur_bytecode.push(Op { owning_span, opcode: Either::Left(VirtualOp::JMP(by4_reg)), - comment: "jmpb_ssp: Jump to computed value".into(), + comment: "jmp_mem: Jump to computed value".into(), }); Ok(()) diff --git a/sway-core/src/asm_generation/fuel/functions.rs b/sway-core/src/asm_generation/fuel/functions.rs index 9fa415850f1..08b34efd87b 100644 --- a/sway-core/src/asm_generation/fuel/functions.rs +++ b/sway-core/src/asm_generation/fuel/functions.rs @@ -305,7 +305,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { // Free our stack allocated locals. This is unneeded for entries since they will have // actually returned to the calling context via a VM RET. - self.drop_locals(function); + self.drop_locals(); // Restore $reta. self.cur_bytecode.push(Op::register_move( @@ -946,7 +946,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> { .push((locals_size_bytes, locals_base_reg, max_num_extra_args)); } - fn drop_locals(&mut self, _function: Function) { + pub(super) fn drop_locals(&mut self) { let (locals_size_bytes, max_num_extra_args) = (self.locals_size_bytes(), self.max_num_extra_args()); if locals_size_bytes > compiler_constants::TWENTY_FOUR_BITS { diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index 3a08ce171c5..d0f08a8e8d0 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1111,7 +1111,7 @@ fn const_eval_intrinsic( | Intrinsic::StateStoreQuad | Intrinsic::Log | Intrinsic::Revert - | Intrinsic::JmpbSsp + | Intrinsic::JmpMem | Intrinsic::Smo => Err(ConstEvalError::CannotBeEvaluatedToConst { span: intrinsic.span.clone(), }), diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index e4aa6af1dfe..bd7249b6c63 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -1095,16 +1095,12 @@ impl<'eng> FnCompiler<'eng> { .add_metadatum(context, span_md_idx); Ok(TerminatorValue::new(val, context)) } - Intrinsic::JmpbSsp => { - let offset_val = return_on_termination_or_extract!( - self.compile_expression_to_value(context, md_mgr, &arguments[0])? - ); - + Intrinsic::JmpMem => { let span_md_idx = md_mgr.span_to_md(context, &span); let val = self .current_block .append(context) - .jmpb_ssp(offset_val) + .jmp_mem() .add_metadatum(context, span_md_idx); Ok(TerminatorValue::new(val, context)) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs index e042ee746fa..46296ef9927 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs @@ -83,8 +83,8 @@ impl ty::TyIntrinsicFunctionKind { } Intrinsic::Smo => type_check_smo(handler, ctx, kind, arguments, type_arguments, span), Intrinsic::Not => type_check_not(handler, ctx, kind, arguments, type_arguments, span), - Intrinsic::JmpbSsp => { - type_check_jmpb_ssp(handler, ctx, kind, arguments, type_arguments, span) + Intrinsic::JmpMem => { + type_check_jmp_mem(handler, ctx, kind, arguments, type_arguments, span) } } } @@ -1173,12 +1173,11 @@ fn type_check_revert( )) } -/// Signature: `__jmpb_ssp(offset: u64) -> !` -/// Description: Jumps to `$ssp - offset`. -/// Constraints: offset has type `u64`. -fn type_check_jmpb_ssp( +/// Signature: `__jmp_mem() -> !` +/// Description: Jumps to `MEM[$hp]`. +fn type_check_jmp_mem( handler: &Handler, - mut ctx: TypeCheckContext, + ctx: TypeCheckContext, kind: sway_ast::Intrinsic, arguments: Vec, type_arguments: Vec, @@ -1187,7 +1186,7 @@ fn type_check_jmpb_ssp( let type_engine = ctx.engines.te(); let engines = ctx.engines(); - if arguments.len() != 1 { + if !arguments.is_empty() { return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { name: kind.to_string(), expected: 0, @@ -1203,18 +1202,10 @@ fn type_check_jmpb_ssp( })); } - // Type check the argument which is the jmpb_ssp offset - let mut ctx = ctx.by_ref().with_type_annotation(type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - )); - let offset = ty::TyExpression::type_check(handler, ctx.by_ref(), arguments[0].clone())?; - Ok(( ty::TyIntrinsicFunctionKind { kind, - arguments: vec![offset], + arguments: vec![], type_arguments: vec![], span, }, diff --git a/sway-core/src/semantic_analysis/cei_pattern_analysis.rs b/sway-core/src/semantic_analysis/cei_pattern_analysis.rs index 459fc922a3e..61e6fb5fc5e 100644 --- a/sway-core/src/semantic_analysis/cei_pattern_analysis.rs +++ b/sway-core/src/semantic_analysis/cei_pattern_analysis.rs @@ -608,7 +608,7 @@ fn effects_of_intrinsic(intr: &sway_ast::Intrinsic) -> HashSet { StateClear | StateStoreWord | StateStoreQuad => HashSet::from([Effect::StorageWrite]), StateLoadWord | StateLoadQuad => HashSet::from([Effect::StorageRead]), Smo => HashSet::from([Effect::OutputMessage]), - Revert | JmpbSsp | IsReferenceType | IsStrArray | SizeOfType | SizeOfVal | SizeOfStr + Revert | JmpMem | IsReferenceType | IsStrArray | SizeOfType | SizeOfVal | SizeOfStr | AssertIsStrArray | ToStrArray | Eq | Gt | Lt | Gtf | AddrOf | Log | Add | Sub | Mul | Div | And | Or | Xor | Mod | Rsh | Lsh | PtrAdd | PtrSub | Not => HashSet::new(), } diff --git a/sway-ir/src/analysis/memory_utils.rs b/sway-ir/src/analysis/memory_utils.rs index d75ac184984..dfc8829bf95 100644 --- a/sway-ir/src/analysis/memory_utils.rs +++ b/sway-ir/src/analysis/memory_utils.rs @@ -201,7 +201,7 @@ pub fn get_loaded_ptr_values(context: &Context, val: Value) -> Vec { InstOp::Store { dst_val_ptr: _, .. } => vec![], InstOp::FuelVm(FuelVmInstruction::Gtf { .. }) | InstOp::FuelVm(FuelVmInstruction::ReadRegister(_)) - | InstOp::FuelVm(FuelVmInstruction::Revert(_) | FuelVmInstruction::JmpbSsp(_)) => vec![], + | InstOp::FuelVm(FuelVmInstruction::Revert(_) | FuelVmInstruction::JmpMem) => vec![], InstOp::FuelVm(FuelVmInstruction::WideUnaryOp { arg, .. }) => vec![*arg], InstOp::FuelVm(FuelVmInstruction::WideBinaryOp { arg1, arg2, .. }) | InstOp::FuelVm(FuelVmInstruction::WideCmpOp { arg1, arg2, .. }) => { @@ -252,7 +252,7 @@ pub fn get_stored_ptr_values(context: &Context, val: Value) -> Vec { | FuelVmInstruction::Log { .. } | FuelVmInstruction::ReadRegister(_) | FuelVmInstruction::Revert(_) - | FuelVmInstruction::JmpbSsp(_) + | FuelVmInstruction::JmpMem | FuelVmInstruction::Smo { .. } | FuelVmInstruction::StateClear { .. } => vec![], FuelVmInstruction::StateLoadQuadWord { load_val, .. } => vec![*load_val], diff --git a/sway-ir/src/block.rs b/sway-ir/src/block.rs index 2417bbe56ee..a92b60a5c45 100644 --- a/sway-ir/src/block.rs +++ b/sway-ir/src/block.rs @@ -369,9 +369,7 @@ impl Block { i, Instruction { op: InstOp::Ret(..) - | InstOp::FuelVm( - FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpbSsp(..) - ), + | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem), .. } ) diff --git a/sway-ir/src/instruction.rs b/sway-ir/src/instruction.rs index 208e2490346..de9b316b858 100644 --- a/sway-ir/src/instruction.rs +++ b/sway-ir/src/instruction.rs @@ -194,7 +194,7 @@ pub enum FuelVmInstruction { arg1: Value, arg2: Value, }, - JmpbSsp(Value), + JmpMem, } /// Comparison operations. @@ -299,7 +299,7 @@ impl InstOp { // These are all terminators which don't return, essentially. No type. InstOp::Branch(_) | InstOp::ConditionalBranch { .. } - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpbSsp(..)) + | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem) | InstOp::Ret(..) => None, // No-op is also no-type. @@ -408,7 +408,8 @@ impl InstOp { log_val, log_id, .. } => vec![*log_val, *log_id], FuelVmInstruction::ReadRegister(_) => vec![], - FuelVmInstruction::Revert(v) | FuelVmInstruction::JmpbSsp(v) => vec![*v], + FuelVmInstruction::Revert(v) => vec![*v], + FuelVmInstruction::JmpMem => vec![], FuelVmInstruction::Smo { recipient, message, @@ -545,7 +546,7 @@ impl InstOp { } FuelVmInstruction::ReadRegister { .. } => (), FuelVmInstruction::Revert(revert_val) => replace(revert_val), - FuelVmInstruction::JmpbSsp(contr_id) => replace(contr_id), + FuelVmInstruction::JmpMem => (), FuelVmInstruction::Smo { recipient, message, @@ -631,7 +632,7 @@ impl InstOp { | InstOp::FuelVm(FuelVmInstruction::StateLoadQuadWord { .. }) | InstOp::FuelVm(FuelVmInstruction::StateStoreQuadWord { .. }) | InstOp::FuelVm(FuelVmInstruction::StateStoreWord { .. }) - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpbSsp(..)) + | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem) | InstOp::MemCopyBytes { .. } | InstOp::MemCopyVal { .. } | InstOp::Store { .. } @@ -666,7 +667,7 @@ impl InstOp { InstOp::Branch(_) | InstOp::ConditionalBranch { .. } | InstOp::Ret(..) - | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpbSsp(..)) + | InstOp::FuelVm(FuelVmInstruction::Revert(..) | FuelVmInstruction::JmpMem) ) } } @@ -1074,11 +1075,11 @@ impl<'a, 'eng> InstructionInserter<'a, 'eng> { revert_val } - pub fn jmpb_ssp(self, offset: Value) -> Value { + pub fn jmp_mem(self) -> Value { let ldc_exec = Value::new_instruction( self.context, self.block, - InstOp::FuelVm(FuelVmInstruction::JmpbSsp(offset)), + InstOp::FuelVm(FuelVmInstruction::JmpMem), ); self.context.blocks[self.block.0] .instructions diff --git a/sway-ir/src/optimize/fn_dedup.rs b/sway-ir/src/optimize/fn_dedup.rs index 25c0085a0c5..35608886944 100644 --- a/sway-ir/src/optimize/fn_dedup.rs +++ b/sway-ir/src/optimize/fn_dedup.rs @@ -154,7 +154,7 @@ fn hash_fn(context: &Context, function: Function, eq_class: &mut EqClass) -> u64 crate::FuelVmInstruction::Log { log_ty, .. } => log_ty.hash(state), crate::FuelVmInstruction::ReadRegister(reg) => reg.hash(state), crate::FuelVmInstruction::Revert(_) - | crate::FuelVmInstruction::JmpbSsp(_) + | crate::FuelVmInstruction::JmpMem | crate::FuelVmInstruction::Smo { .. } | crate::FuelVmInstruction::StateClear { .. } | crate::FuelVmInstruction::StateLoadQuadWord { .. } diff --git a/sway-ir/src/optimize/inline.rs b/sway-ir/src/optimize/inline.rs index 50402b62d50..29c97517a3a 100644 --- a/sway-ir/src/optimize/inline.rs +++ b/sway-ir/src/optimize/inline.rs @@ -535,9 +535,7 @@ fn inline_instruction( new_block.append(context).read_register(reg) } FuelVmInstruction::Revert(val) => new_block.append(context).revert(map_value(val)), - FuelVmInstruction::JmpbSsp(offset) => { - new_block.append(context).jmpb_ssp(map_value(offset)) - } + FuelVmInstruction::JmpMem => new_block.append(context).jmp_mem(), FuelVmInstruction::Smo { recipient, message, diff --git a/sway-ir/src/parser.rs b/sway-ir/src/parser.rs index 526898f559f..703c3ca2aa5 100644 --- a/sway-ir/src/parser.rs +++ b/sway-ir/src/parser.rs @@ -203,7 +203,7 @@ mod ir_builder { / op_read_register() / op_ret() / op_revert() - / op_jmpb_ssp() + / op_jmp_mem() / op_smo() / op_state_load_quad_word() / op_state_load_word() @@ -363,9 +363,9 @@ mod ir_builder { IrAstOperation::Revert(vn) } - rule op_jmpb_ssp() -> IrAstOperation - = "jmpb_ssp" _ vn:id() { - IrAstOperation::JmpbSsp(vn) + rule op_jmp_mem() -> IrAstOperation + = "jmp_mem" _ { + IrAstOperation::JmpMem } rule op_smo() -> IrAstOperation @@ -728,7 +728,7 @@ mod ir_builder { ReadRegister(String), Ret(IrAstTy, String), Revert(String), - JmpbSsp(String), + JmpMem, Smo(String, String, String, String), StateClear(String, String), StateLoadQuadWord(String, String, String), @@ -1351,9 +1351,9 @@ mod ir_builder { .append(context) .revert(*val_map.get(&ret_val_name).unwrap()) .add_metadatum(context, opt_metadata), - IrAstOperation::JmpbSsp(offset_name) => block + IrAstOperation::JmpMem => block .append(context) - .jmpb_ssp(*val_map.get(&offset_name).unwrap()) + .jmp_mem() .add_metadatum(context, opt_metadata), IrAstOperation::Smo(recipient, message, message_size, coins) => block .append(context) diff --git a/sway-ir/src/printer.rs b/sway-ir/src/printer.rs index 48a4b75f089..285b22dd6e7 100644 --- a/sway-ir/src/printer.rs +++ b/sway-ir/src/printer.rs @@ -656,12 +656,10 @@ fn instruction_to_doc<'a>( Doc::text(format!("revert {}", namer.name(context, v),)) .append(md_namer.md_idx_to_doc(context, metadata)), )), - FuelVmInstruction::JmpbSsp(offset) => { - maybe_constant_to_doc(context, md_namer, namer, offset).append(Doc::line( - Doc::text(format!("jmpb_ssp {}", namer.name(context, offset),)) - .append(md_namer.md_idx_to_doc(context, metadata)), - )) - } + FuelVmInstruction::JmpMem => Doc::line( + Doc::text("jmp_mem".to_string()) + .append(md_namer.md_idx_to_doc(context, metadata)), + ), FuelVmInstruction::Smo { recipient, message, diff --git a/sway-ir/src/value.rs b/sway-ir/src/value.rs index 63f5be75f48..3f87325da22 100644 --- a/sway-ir/src/value.rs +++ b/sway-ir/src/value.rs @@ -122,7 +122,7 @@ impl Value { InstOp::Branch(_) | InstOp::ConditionalBranch { .. } | InstOp::Ret(_, _) - | InstOp::FuelVm(FuelVmInstruction::Revert(_) | FuelVmInstruction::JmpbSsp(_)) + | InstOp::FuelVm(FuelVmInstruction::Revert(_) | FuelVmInstruction::JmpMem) ), ValueDatum::Argument(..) | ValueDatum::Configurable(..) | ValueDatum::Constant(..) => { false diff --git a/sway-ir/src/verify.rs b/sway-ir/src/verify.rs index 30942dddda1..7c8e08384c3 100644 --- a/sway-ir/src/verify.rs +++ b/sway-ir/src/verify.rs @@ -230,7 +230,7 @@ impl<'a, 'eng> InstructionVerifier<'a, 'eng> { log_id, } => self.verify_log(log_val, log_ty, log_id)?, FuelVmInstruction::ReadRegister(_) => (), - FuelVmInstruction::JmpbSsp(_) => (), + FuelVmInstruction::JmpMem => (), FuelVmInstruction::Revert(val) => self.verify_revert(val)?, FuelVmInstruction::Smo { recipient, diff --git a/sway-lib-core/src/storage.sw b/sway-lib-core/src/storage.sw index 488487bc944..4ae9519c580 100644 --- a/sway-lib-core/src/storage.sw +++ b/sway-lib-core/src/storage.sw @@ -12,9 +12,107 @@ library; /// represent different storage constructs. pub struct StorageKey { /// The assigned location in storage. - pub slot: b256, + slot: b256, /// The assigned offset based on the data structure `T`. - pub offset: u64, + offset: u64, /// A unique identifier. - pub field_id: b256, + field_id: b256, +} + +impl StorageKey { + /// Create a new `StorageKey`. + /// + /// # Arguments + /// + /// * `slot`: [b256] - The assigned location in storage for the new `StorageKey`. + /// * `offset`: [u64] - The assigned offset based on the data structure `T` for the new `StorageKey`. + /// * `field_id`: [b256] - A unique identifier for the new `StorageKey`. + /// + /// # Returns + /// + /// * [StorageKey] - The newly create `StorageKey`. + /// + /// # Examples + /// + /// ```sway + /// use std::{constants::ZERO_B256, hash::sha256}; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(ZERO_B256, 0, sha256(ZERO_B256)); + /// assert(my_key.slot() == ZERO_B256); + /// } + /// ``` + pub fn new(slot: b256, offset: u64, field_id: b256) -> Self { + Self { + slot, + offset, + field_id, + } + } + + /// Returns the storage slot address. + /// + /// # Returns + /// + /// * [b256] - The address in storage that this storage slot points to. + /// + /// # Examples + /// + /// ```sway + /// use std::{constants::ZERO_B256, hash::sha256}; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(ZERO_B256, 0, sha256(ZERO_B256)); + /// assert(my_key.slot() == ZERO_B256); + /// } + /// ``` + pub fn slot(self) -> b256 { + self.slot + } + + /// Returns the offset on the storage slot. + /// + /// # Returns + /// + /// * [u64] - The offset in storage that this storage slot points to. + /// + /// # Examples + /// + /// ```sway + /// use std::{constants::ZERO_B256, hash::sha256}; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(ZERO_B256, 0, sha256(ZERO_B256)); + /// assert(my_key.offset() == 0); + /// } + /// ``` + pub fn offset(self) -> u64 { + self.offset + } + + /// Returns the storage slot field id. + /// + /// # Additional Information + /// + /// The field id is a unique identifier for the storage field being referred to, it is different even + /// for multiple zero sized fields that might live at the same location but + /// represent different storage constructs. + /// + /// # Returns + /// + /// * [b256] - The field id for this storage slot. + /// + /// # Examples + /// + /// ```sway + /// use std::{constants::ZERO_B256, hash::sha256}; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(ZERO_B256, 0, sha256(ZERO_B256)); + /// assert(my_key.field_id() == sha256(ZERO_B256)); + /// } + /// ``` + pub fn field_id(self) -> b256 { + self.field_id + } } diff --git a/sway-lib-std/src/address.sw b/sway-lib-std/src/address.sw index 16db8eef4f6..1252852b1b2 100644 --- a/sway-lib-std/src/address.sw +++ b/sway-lib-std/src/address.sw @@ -7,12 +7,34 @@ use ::hash::{Hash, Hasher}; /// The `Address` type, a struct wrapper around the inner `b256` value. pub struct Address { /// The underlying raw `b256` data of the address. - pub value: b256, + bits: b256, +} + +impl Address { + /// Returns the underlying raw `b256` data of the address. + /// + /// # Returns + /// + /// * [b256] - The raw data of the address. + /// + /// # Examples + /// + /// ```sway + /// use std::constants::ZERO_B256; + /// + /// fn foo() -> { + /// let my_address = Address::from(ZERO_B256); + /// assert(my_address.bits() == ZERO_B256); + /// } + /// ``` + pub fn bits(self) -> b256 { + self.bits + } } impl core::ops::Eq for Address { fn eq(self, other: Self) -> bool { - self.value == other.value + self.bits == other.bits } } @@ -38,7 +60,7 @@ impl From for Address { /// } /// ``` fn from(bits: b256) -> Self { - Self { value: bits } + Self { bits } } } @@ -60,14 +82,14 @@ impl From
for b256 { /// assert(b256_data == ZERO_B256); /// } /// ``` - fn from(address: Address) -> b256 { - address.value + fn from(address: Address) -> Self { + address.bits() } } impl Hash for Address { fn hash(self, ref mut state: Hasher) { - let Address { value } = self; - value.hash(state); + let Address { bits } = self; + bits.hash(state); } } diff --git a/sway-lib-std/src/asset.sw b/sway-lib-std/src/asset.sw index bdb80eb8196..eb421dbf143 100644 --- a/sway-lib-std/src/asset.sw +++ b/sway-lib-std/src/asset.sw @@ -218,7 +218,7 @@ pub fn transfer(to: Identity, asset_id: AssetId, amount: u64) { /// } /// ``` pub fn force_transfer_to_contract(to: ContractId, asset_id: AssetId, amount: u64) { - asm(r1: amount, r2: asset_id, r3: to.value) { + asm(r1: amount, r2: asset_id, r3: to.bits()) { tr r3 r1 r2; } } @@ -259,7 +259,7 @@ pub fn transfer_to_address(to: Address, asset_id: AssetId, amount: u64) { while index < number_of_outputs { if let Output::Variable = output_type(index) { if output_amount(index) == 0 { - asm(r1: to.value, r2: index, r3: amount, r4: asset_id) { + asm(r1: to.bits(), r2: index, r3: amount, r4: asset_id) { tro r1 r2 r3 r4; }; return; diff --git a/sway-lib-std/src/asset_id.sw b/sway-lib-std/src/asset_id.sw index 17c49c1119d..758621eb2f4 100644 --- a/sway-lib-std/src/asset_id.sw +++ b/sway-lib-std/src/asset_id.sw @@ -16,19 +16,19 @@ use ::hash::{Hash, Hasher}; /// /// The SubId is used to differentiate between different assets that are created by the same contract. pub struct AssetId { - pub value: b256, + bits: b256, } impl Hash for AssetId { fn hash(self, ref mut state: Hasher) { - let Self { value } = self; - value.hash(state); + let Self { bits } = self; + bits.hash(state); } } impl core::ops::Eq for AssetId { fn eq(self, other: Self) -> bool { - self.value == other.value + self.bits == other.bits } } @@ -53,30 +53,7 @@ impl From for AssetId { /// } /// ``` fn from(bits: b256) -> Self { - Self { value: bits } - } -} - -impl From for b256 { - /// Casts an `AssetId` to raw `b256` data. - /// - /// # Returns - /// - /// * [b256] - The underlying raw `b256` data of the `AssetId`. - /// - /// # Examples - /// - /// ```sway - /// use std::constants::ZERO_B256; - /// - /// fn foo() { - /// let asset_id = AssetId::from(ZERO_B256); - /// let b256_data = asset_id.into(); - /// assert(b256_data == ZERO_B256); - /// } - /// ``` - fn from(id: AssetId) -> b256 { - id.value + Self { bits } } } @@ -115,7 +92,7 @@ impl AssetId { }; Self { - value: result_buffer, + bits: result_buffer, } } @@ -152,7 +129,7 @@ impl AssetId { }; Self { - value: result_buffer, + bits: result_buffer, } } @@ -180,9 +157,52 @@ impl AssetId { /// ``` pub fn base_asset_id() -> Self { Self { - value: 0x0000000000000000000000000000000000000000000000000000000000000000, + bits: 0x0000000000000000000000000000000000000000000000000000000000000000, } } + + /// Returns the underlying raw `b256` data of the asset id. + /// + /// # Returns + /// + /// * [b256] - The raw data of the asset id. + /// + /// # Examples + /// + /// ```sway + /// use std::constants::ZERO_B256; + /// + /// fn foo() -> { + /// let my_asset = AssetId::from(ZERO_B256); + /// assert(my_asset.bits() == ZERO_B256); + /// } + /// ``` + pub fn bits(self) -> b256 { + self.bits + } +} + +impl From for b256 { + /// Casts an `AssetId` to raw `b256` data. + /// + /// # Returns + /// + /// * [b256] - The underlying raw `b256` data of the `AssetId`. + /// + /// # Examples + /// + /// ```sway + /// use std::constants::ZERO_B256; + /// + /// fn foo() { + /// let asset_id = AssetId::from(ZERO_B256); + /// let b256_data = asset_id.into(); + /// assert(b256_data == ZERO_B256); + /// } + /// ``` + fn from(id: AssetId) -> Self { + id.bits() + } } #[test()] diff --git a/sway-lib-std/src/b512.sw b/sway-lib-std/src/b512.sw index c62765d9c33..b5669c89a61 100644 --- a/sway-lib-std/src/b512.sw +++ b/sway-lib-std/src/b512.sw @@ -9,12 +9,12 @@ use ::convert::From; /// Guaranteed to be contiguous for use with ec-recover: `std::ecr::ec_recover`. pub struct B512 { /// The two `b256`s that make up the `B512`. - pub bytes: [b256; 2], + bits: [b256; 2], } impl core::ops::Eq for B512 { fn eq(self, other: Self) -> bool { - (self.bytes)[0] == (other.bytes)[0] && (self.bytes)[1] == (other.bytes)[1] + (self.bits)[0] == (other.bits)[0] && (self.bits)[1] == (other.bits)[1] } } @@ -22,14 +22,14 @@ impl core::ops::Eq for B512 { impl From<(b256, b256)> for B512 { fn from(components: (b256, b256)) -> Self { Self { - bytes: [components.0, components.1], + bits: [components.0, components.1], } } } impl From for (b256, b256) { fn from(val: B512) -> (b256, b256) { - ((val.bytes)[0], (val.bytes)[1]) + ((val.bits)[0], (val.bits)[1]) } } @@ -52,7 +52,27 @@ impl B512 { /// ``` pub fn new() -> Self { Self { - bytes: [ZERO_B256, ZERO_B256], + bits: [ZERO_B256, ZERO_B256], } } + + /// Returns the underlying bits for the B512 type. + /// + /// # Returns + /// + /// * [[b256; 2]] - The two `b256`s that make up the `B512`. + /// + /// # Examples + /// + /// ```sway + /// use std::{b512::B512, constants::ZERO_B256); + /// + /// fn foo() { + /// let zero = B512::new(); + /// assert(zero.bits() == [ZERO_B256, ZERO_B256]); + /// } + /// ``` + pub fn bits(self) -> [b256; 2] { + self.bits + } } diff --git a/sway-lib-std/src/bytes.sw b/sway-lib-std/src/bytes.sw index ac9cd92d681..720ff610014 100644 --- a/sway-lib-std/src/bytes.sw +++ b/sway-lib-std/src/bytes.sw @@ -8,7 +8,7 @@ use ::option::Option::{self, *}; use ::convert::{From, Into, *}; struct RawBytes { - pub ptr: raw_ptr, + ptr: raw_ptr, cap: u64, } @@ -50,12 +50,42 @@ impl RawBytes { } } +impl From for RawBytes { + /// Creates a `RawBytes` from a `raw_slice`. + /// + /// ### Examples + /// + /// ```sway + /// use std:bytes::RawBytes; + /// + /// let mut vec = Vec::new(); + /// let a = 5u8; + /// let b = 7u8; + /// let c = 9u8 + /// + /// vec.push(a); + /// vec.push(b); + /// vec.push(c); + /// + /// let vec_as_raw_slice = vec.as_raw_slice(); + /// let raw_bytes = RawBytes::from(vec_as_raw_slice); + /// + /// assert(raw_bytes.capacity == 3); + /// ``` + fn from(slice: raw_slice) -> Self { + Self { + ptr: slice.ptr(), + cap: slice.number_of_bytes(), + } + } +} + /// A type used to represent raw bytes. pub struct Bytes { /// A barebones struct for the bytes. - pub buf: RawBytes, + buf: RawBytes, /// The number of bytes being stored. - pub len: u64, + len: u64, } impl Bytes { @@ -111,7 +141,7 @@ impl Bytes { /// use std::bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::with_capacity(2); + /// let mut bytes = Bytes::with_capacity(2); /// // does not allocate /// bytes.push(5); /// // does not re-allocate @@ -175,7 +205,7 @@ impl Bytes { /// use std::bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// /// let res = bytes.pop(); /// assert(res.is_none()); @@ -214,7 +244,7 @@ impl Bytes { /// use std::bytes::Byte; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// bytes.push(5u8); /// bytes.push(10u8); /// bytes.push(15u8); @@ -252,7 +282,7 @@ impl Bytes { /// use std::bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// let a = 5u8; /// let b = 7u8; /// let c = 9u8; @@ -296,7 +326,7 @@ impl Bytes { /// use std::bytes::Byte; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// let a = 11u8; /// let b = 11u8; /// let c = 11u8; @@ -316,7 +346,7 @@ impl Bytes { assert(index <= self.len); // If there is insufficient capacity, grow the buffer. - if self.len == self.buf.cap { + if self.len == self.buf.capacity() { self.buf.grow(); } @@ -362,7 +392,7 @@ impl Bytes { /// use std::bytes::Byte; /// /// fn foo() { - /// let bytes = Byte::new(); + /// let mut bytes = Byte::new(); /// bytes.push(5); /// bytes.push(10); /// bytes.push(15); @@ -413,7 +443,7 @@ impl Bytes { /// use std::bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// let a = 5u8; /// let b = 7u8; /// let c = 9u8; @@ -464,7 +494,7 @@ impl Bytes { /// } /// ``` pub fn capacity(self) -> u64 { - self.buf.cap + self.buf.capacity() } /// Gets the length of the `Bytes`. @@ -479,7 +509,7 @@ impl Bytes { /// use std::bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// assert(bytes.len() == 0); /// bytes.push(5); /// assert(bytes.len() == 1); @@ -502,16 +532,15 @@ impl Bytes { /// use std:bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// bytes.push(5); /// bytes.clear() /// assert(bytes.is_empty()); /// } /// ``` pub fn clear(ref mut self) { - self.buf.ptr = alloc_bytes(0); + self.buf = RawBytes::new(); self.len = 0; - self.buf.cap = 0; } /// Returns `true` if the type contains no elements. @@ -526,7 +555,7 @@ impl Bytes { /// use std:bytes::Bytes; /// /// fn foo() { - /// let bytes = Bytes::new(); + /// let mut bytes = Bytes::new(); /// assert(bytes.is_empty()); /// bytes.push(5); /// assert(!bytes.is_empty()); @@ -537,6 +566,26 @@ impl Bytes { pub fn is_empty(self) -> bool { self.len == 0 } + + /// Gets the pointer of the allocation. + /// + /// # Returns + /// + /// [raw_ptr] - The location in memory that the allocated bytes live. + /// + /// # Examples + /// + /// ```sway + /// use std::bytes::Bytes; + /// + /// fn foo() { + /// let bytes = Bytes::new(); + /// assert(!bytes.ptr().is_null()); + /// } + /// ``` + pub fn ptr(self) -> raw_ptr { + self.buf.ptr() + } } // Need to use separate impl blocks for now: https://github.com/FuelLabs/sway/issues/1548 @@ -592,13 +641,13 @@ impl Bytes { }; if mid > 0 { - self.buf.ptr().copy_bytes_to(left_bytes.buf.ptr(), left_len); + self.buf.ptr().copy_bytes_to(left_bytes.ptr(), left_len); }; if mid != self.len { self.buf .ptr() .add_uint_offset(mid) - .copy_bytes_to(right_bytes.buf.ptr(), right_len); + .copy_bytes_to(right_bytes.ptr(), right_len); }; left_bytes.len = left_len; @@ -641,7 +690,8 @@ impl Bytes { /// } /// ``` pub fn append(ref mut self, ref mut other: self) { - if other.len == 0 { + let other_len = other.len(); + if other_len == 0 { return }; @@ -652,23 +702,22 @@ impl Bytes { return; }; - let both_len = self.len + other.len; + let both_len = self.len + other_len; let other_start = self.len; // reallocate with combined capacity, write `other`, set buffer capacity - self.buf.ptr = realloc_bytes(self.buf.ptr(), self.buf.capacity(), both_len); - - let mut i = 0; - while i < other.len { - let new_ptr = self.buf.ptr().add_uint_offset(other_start); - new_ptr - .add_uint_offset(i) - .write_byte(other.buf.ptr.add_uint_offset(i).read_byte()); - i += 1; + if self.buf.capacity() < both_len { + let new_slice = raw_slice::from_parts::( + realloc_bytes(self.buf.ptr(), self.buf.capacity(), both_len), + both_len, + ); + self.buf = RawBytes::from(new_slice); } + let new_ptr = self.buf.ptr().add_uint_offset(other_start); + other.ptr().copy_bytes_to(new_ptr, other_len); + // set capacity and length - self.buf.cap = both_len; self.len = both_len; // clear `other` @@ -678,11 +727,11 @@ impl Bytes { impl core::ops::Eq for Bytes { fn eq(self, other: Self) -> bool { - if self.len != other.len { + if self.len != other.len() { return false; } - asm(result, r2: self.buf.ptr, r3: other.buf.ptr, r4: self.len) { + asm(result, r2: self.buf.ptr(), r3: other.ptr(), r4: self.len) { meq result r2 r3 r4; result: bool } @@ -705,7 +754,7 @@ impl From for Bytes { let mut bytes = Self::with_capacity(32); bytes.len = 32; // Copy bytes from contract_id into the buffer of the target bytes - __addr_of(b).copy_bytes_to(bytes.buf.ptr, 32); + __addr_of(b).copy_bytes_to(bytes.buf.ptr(), 32); bytes } @@ -751,13 +800,9 @@ impl From for Bytes { /// assert(bytes.get(2).unwrap() == c); /// ``` fn from(slice: raw_slice) -> Self { - let number_of_bytes = slice.number_of_bytes(); Self { - buf: RawBytes { - ptr: slice.ptr(), - cap: number_of_bytes, - }, - len: number_of_bytes, + buf: RawBytes::from(slice), + len: slice.number_of_bytes(), } } } diff --git a/sway-lib-std/src/bytes_conversions/u16.sw b/sway-lib-std/src/bytes_conversions/u16.sw index 6af78bfd709..63bdb281dc8 100644 --- a/sway-lib-std/src/bytes_conversions/u16.sw +++ b/sway-lib-std/src/bytes_conversions/u16.sw @@ -70,7 +70,7 @@ impl u16 { /// ``` pub fn from_le_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 2); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let a = ptr.read_byte(); let b = (ptr.add_uint_offset(1)).read_byte(); let i = 0x8; @@ -147,7 +147,7 @@ impl u16 { /// ``` pub fn from_be_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 2); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let a = ptr.read_byte(); let b = (ptr.add_uint_offset(1)).read_byte(); diff --git a/sway-lib-std/src/bytes_conversions/u32.sw b/sway-lib-std/src/bytes_conversions/u32.sw index fe7c4a18064..25267bce425 100644 --- a/sway-lib-std/src/bytes_conversions/u32.sw +++ b/sway-lib-std/src/bytes_conversions/u32.sw @@ -94,7 +94,7 @@ impl u32 { /// ``` pub fn from_le_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 4); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let a = ptr.read_byte(); let b = (ptr.add_uint_offset(1)).read_byte(); let c = (ptr.add_uint_offset(2)).read_byte(); @@ -199,7 +199,7 @@ impl u32 { /// ``` pub fn from_be_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 4); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let a = ptr.read_byte(); let b = (ptr.add_uint_offset(1)).read_byte(); let c = (ptr.add_uint_offset(2)).read_byte(); diff --git a/sway-lib-std/src/bytes_conversions/u64.sw b/sway-lib-std/src/bytes_conversions/u64.sw index bf573914550..f8957eb42b0 100644 --- a/sway-lib-std/src/bytes_conversions/u64.sw +++ b/sway-lib-std/src/bytes_conversions/u64.sw @@ -122,7 +122,7 @@ impl u64 { /// ``` pub fn from_le_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 8); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let a = ptr.read_byte(); let b = (ptr.add_uint_offset(1)).read_byte(); let c = (ptr.add_uint_offset(2)).read_byte(); @@ -271,7 +271,7 @@ impl u64 { /// ``` pub fn from_be_bytes(bytes: Bytes) -> Self { assert(bytes.len() == 8); - let ptr = bytes.buf.ptr(); + let ptr = bytes.ptr(); let h = ptr.read_byte(); let g = (ptr.add_uint_offset(1)).read_byte(); let f = (ptr.add_uint_offset(2)).read_byte(); diff --git a/sway-lib-std/src/call_frames.sw b/sway-lib-std/src/call_frames.sw index 6869a3ef524..65df5646a5b 100644 --- a/sway-lib-std/src/call_frames.sw +++ b/sway-lib-std/src/call_frames.sw @@ -65,12 +65,10 @@ pub fn contract_id() -> ContractId { /// } /// ``` pub fn msg_asset_id() -> AssetId { - AssetId { - value: { asm(asset_id) { - addi asset_id fp i32; - asset_id: b256 - } }, - } + AssetId::from(asm(asset_id) { + addi asset_id fp i32; + asset_id: b256 + }) } /// Get the code size in bytes (padded to word alignment) from the current call frame. diff --git a/sway-lib-std/src/context.sw b/sway-lib-std/src/context.sw index eda5fe4a67f..61e6a9c17e0 100644 --- a/sway-lib-std/src/context.sw +++ b/sway-lib-std/src/context.sw @@ -54,7 +54,7 @@ pub fn this_balance(asset_id: AssetId) -> u64 { /// } /// ``` pub fn balance_of(target: ContractId, asset_id: AssetId) -> u64 { - asm(balance, asset: asset_id.value, id: target.value) { + asm(balance, asset: asset_id.bits(), id: target.bits()) { bal balance asset id; balance: u64 } diff --git a/sway-lib-std/src/contract_id.sw b/sway-lib-std/src/contract_id.sw index e9f52213d71..e02e6d4909d 100644 --- a/sway-lib-std/src/contract_id.sw +++ b/sway-lib-std/src/contract_id.sw @@ -7,12 +7,34 @@ use ::hash::{Hash, Hasher}; /// The `ContractId` type, a struct wrapper around the inner `b256` value. pub struct ContractId { /// The underlying raw `b256` data of the contract id. - pub value: b256, + bits: b256, +} + +impl ContractId { + /// Returns the underlying raw `b256` data of the contract id. + /// + /// # Returns + /// + /// * [b256] - The raw data of the contract id. + /// + /// # Examples + /// + /// ```sway + /// use std::constants::ZERO_B256; + /// + /// fn foo() -> { + /// let my_contract = ContractId::from(ZERO_B256); + /// assert(my_contract.bits() == ZERO_B256); + /// } + /// ``` + pub fn bits(self) -> b256 { + self.bits + } } impl core::ops::Eq for ContractId { fn eq(self, other: Self) -> bool { - self.value == other.value + self.bits == other.bits } } @@ -38,7 +60,7 @@ impl From for ContractId { /// } /// ``` fn from(bits: b256) -> Self { - Self { value: bits } + Self { bits } } } @@ -60,15 +82,15 @@ impl From for b256 { /// assert(b256_data == ZERO_B256); /// } /// ``` - fn from(id: ContractId) -> b256 { - id.value + fn from(id: ContractId) -> Self { + id.bits() } } impl Hash for ContractId { fn hash(self, ref mut state: Hasher) { - let Self { value } = self; - value.hash(state); + let Self { bits } = self; + bits.hash(state); } } diff --git a/sway-lib-std/src/ecr.sw b/sway-lib-std/src/ecr.sw index 81d59a9e761..1b4acaa293d 100644 --- a/sway-lib-std/src/ecr.sw +++ b/sway-lib-std/src/ecr.sw @@ -44,15 +44,15 @@ pub enum EcRecoverError { /// // A recovered public key pair. /// let public_key = ec_recover(signature, msg_hash).unwrap(); /// -/// assert(public_key.bytes[0] == pub_hi); -/// assert(public_key.bytes[1] == pub_lo); +/// assert(public_key.bits()[0] == pub_hi); +/// assert(public_key.bits()[1] == pub_lo); /// } /// ``` pub fn ec_recover(signature: B512, msg_hash: b256) -> Result { let public_key = B512::new(); let was_error = asm( - buffer: public_key.bytes, - sig: signature.bytes, + buffer: __addr_of(public_key), + sig: __addr_of(signature), hash: msg_hash, ) { eck1 buffer sig hash; @@ -97,15 +97,15 @@ pub fn ec_recover(signature: B512, msg_hash: b256) -> Result Result { let public_key = B512::new(); let was_error = asm( - buffer: public_key.bytes, - sig: signature.bytes, + buffer: __addr_of(public_key), + sig: __addr_of(signature), hash: msg_hash, ) { ecr1 buffer sig hash; @@ -159,7 +159,11 @@ pub fn ed_verify( signature: B512, msg_hash: b256, ) -> Result { - let was_error = asm(buffer: public_key, sig: signature.bytes, hash: msg_hash) { + let was_error = asm( + buffer: public_key, + sig: __addr_of(signature), + hash: msg_hash, + ) { ed19 buffer sig hash; err }; @@ -211,7 +215,7 @@ pub fn ec_recover_address(signature: B512, msg_hash: b256) -> Result Result b256 { let root: b256 = ZERO_B256; - asm(root_addr: root, target: contract_id.value) { + asm(root_addr: root, target: contract_id.bits()) { croo root_addr target; root_addr: b256 } diff --git a/sway-lib-std/src/hash.sw b/sway-lib-std/src/hash.sw index 5ba9d272c62..a5d1ced1dca 100644 --- a/sway-lib-std/src/hash.sw +++ b/sway-lib-std/src/hash.sw @@ -1,6 +1,7 @@ //! Utility functions for cryptographic hashing. library; +use ::alloc::alloc_bytes; use ::bytes::*; pub struct Hasher { @@ -23,8 +24,8 @@ impl Hasher { let mut result_buffer = b256::min(); asm( hash: result_buffer, - ptr: self.bytes.buf.ptr, - bytes: self.bytes.len, + ptr: self.bytes.ptr(), + bytes: self.bytes.len(), ) { s256 hash ptr bytes; hash: b256 @@ -35,8 +36,8 @@ impl Hasher { let mut result_buffer = b256::min(); asm( hash: result_buffer, - ptr: self.bytes.buf.ptr, - bytes: self.bytes.len, + ptr: self.bytes.ptr(), + bytes: self.bytes.len(), ) { k256 hash ptr bytes; hash: b256 @@ -50,11 +51,7 @@ impl Hasher { let str_size = s.len(); let str_ptr = s.as_ptr(); - let mut bytes = Bytes::with_capacity(str_size); - bytes.len = str_size; - - str_ptr.copy_bytes_to(bytes.buf.ptr(), str_size); - self.write(bytes); + self.write(Bytes::from(raw_slice::from_parts::(str_ptr, str_size))); } #[inline(never)] @@ -63,12 +60,7 @@ impl Hasher { let str_size = __size_of_str_array::(); let str_ptr = __addr_of(s); - let mut bytes = Bytes::with_capacity(str_size); - bytes.len = str_size; - - str_ptr.copy_bytes_to(bytes.buf.ptr(), str_size); - - self.write(bytes); + self.write(Bytes::from(raw_slice::from_parts::(str_ptr, str_size))); } } @@ -86,56 +78,48 @@ impl Hash for u8 { impl Hash for u16 { fn hash(self, ref mut state: Hasher) { - let mut bytes = Bytes::with_capacity(8); // one word capacity - bytes.len = 2; - - asm(ptr: bytes.buf.ptr(), val: self, r1) { + let ptr = alloc_bytes(8); // one word capacity + asm(ptr: ptr, val: self, r1) { slli r1 val i48; sw ptr r1 i0; }; - state.write(bytes); + state.write(Bytes::from(raw_slice::from_parts::(ptr, 2))); } } impl Hash for u32 { fn hash(self, ref mut state: Hasher) { - let mut bytes = Bytes::with_capacity(8); // one word capacity - bytes.len = 4; - - asm(ptr: bytes.buf.ptr(), val: self, r1) { + let ptr = alloc_bytes(8); // one word capacity + asm(ptr: ptr, val: self, r1) { slli r1 val i32; sw ptr r1 i0; }; - state.write(bytes); + state.write(Bytes::from(raw_slice::from_parts::(ptr, 4))); } } impl Hash for u64 { fn hash(self, ref mut state: Hasher) { - let mut bytes = Bytes::with_capacity(8); // one word capacity - bytes.len = 8; - - asm(ptr: bytes.buf.ptr(), val: self) { + let ptr = alloc_bytes(8); // one word capacity + asm(ptr: ptr, val: self) { sw ptr val i0; }; - state.write(bytes); + state.write(Bytes::from(raw_slice::from_parts::(ptr, 8))); } } impl Hash for b256 { fn hash(self, ref mut state: Hasher) { - let mut bytes = Bytes::with_capacity(32); // four word capacity - bytes.len = 32; - + let ptr = alloc_bytes(32); // four word capacity let (word_1, word_2, word_3, word_4) = asm(r1: self) { r1: (u64, u64, u64, u64) }; asm( - ptr: bytes.buf.ptr(), + ptr: ptr, val_1: word_1, val_2: word_2, val_3: word_3, @@ -147,21 +131,19 @@ impl Hash for b256 { sw ptr val_4 i3; }; - state.write(bytes); + state.write(Bytes::from(raw_slice::from_parts::(ptr, 32))); } } impl Hash for u256 { fn hash(self, ref mut state: Hasher) { - let mut bytes = Bytes::with_capacity(32); // four word capacity - bytes.len = 32; - + let ptr = alloc_bytes(32); // four word capacity let (word_1, word_2, word_3, word_4) = asm(r1: self) { r1: (u64, u64, u64, u64) }; asm( - ptr: bytes.buf.ptr(), + ptr: ptr, val_1: word_1, val_2: word_2, val_3: word_3, @@ -173,7 +155,7 @@ impl Hash for u256 { sw ptr val_4 i3; }; - state.write(bytes); + state.write(Bytes::from(raw_slice::from_parts::(ptr, 32))); } } @@ -442,13 +424,11 @@ pub fn sha256_str_array(param: S) -> b256 { let str_size = __size_of_str_array::(); let str_ptr = __addr_of(param); - let mut bytes = Bytes::with_capacity(str_size); - bytes.len = str_size; - - str_ptr.copy_bytes_to(bytes.buf.ptr(), str_size); + let ptr = alloc_bytes(str_size); + str_ptr.copy_bytes_to(ptr, str_size); let mut hasher = Hasher::new(); - hasher.write(bytes); + hasher.write(Bytes::from(raw_slice::from_parts::(ptr, str_size))); hasher.sha256() } diff --git a/sway-lib-std/src/identity.sw b/sway-lib-std/src/identity.sw index ee8bc13fa96..b800b0faa05 100644 --- a/sway-lib-std/src/identity.sw +++ b/sway-lib-std/src/identity.sw @@ -124,6 +124,29 @@ impl Identity { Self::ContractId(_) => true, } } + + /// Returns the underlying raw `b256` data of the identity. + /// + /// # Returns + /// + /// * [b256] - The raw data of the identity. + /// + /// # Examples + /// + /// ```sway + /// use std::constants::ZERO_B256; + /// + /// fn foo() -> { + /// let my_identity = Identity::Address(Address::from(ZERO_B256)); + /// assert(my_identity.bits() == ZERO_B256); + /// } + /// ``` + pub fn bits(self) -> b256 { + match self { + Self::Address(address) => address.bits(), + Self::ContractId(contract_id) => contract_id.bits(), + } + } } impl Hash for Identity { @@ -157,6 +180,6 @@ fn test_contract_id() { let identity = Identity::ContractId(ContractId::from(ZERO_B256)); assert(!identity.is_address()); assert(identity.is_contract_id()); - assert(identity.as_contract_id().unwrap().value == id); + assert(identity.as_contract_id().unwrap().bits() == id); assert(identity.as_address().is_none()); } diff --git a/sway-lib-std/src/inputs.sw b/sway-lib-std/src/inputs.sw index 5358e301c23..831307d0907 100644 --- a/sway-lib-std/src/inputs.sw +++ b/sway-lib-std/src/inputs.sw @@ -3,6 +3,7 @@ library; use ::address::Address; +use ::alloc::alloc_bytes; use ::assert::assert; use ::asset_id::AssetId; use ::bytes::Bytes; @@ -411,12 +412,11 @@ pub fn input_predicate(index: u64) -> Bytes { revert(0); }; let length = wrapped.unwrap().as_u64(); - let mut data_bytes = Bytes::with_capacity(length); + let new_ptr = alloc_bytes(length); match input_predicate_pointer(index) { Some(d) => { - data_bytes.len = length; - d.copy_bytes_to(data_bytes.buf.ptr, length); - data_bytes + d.copy_bytes_to(new_ptr, length); + Bytes::from(raw_slice::from_parts::(new_ptr, length)) }, None => revert(0), } @@ -610,10 +610,10 @@ pub fn input_message_data(index: u64, offset: u64) -> Bytes { let data = __gtf::(index, GTF_INPUT_MESSAGE_DATA); let data_with_offset = data.add_uint_offset(offset); let length = input_message_data_length(index).as_u64(); - let mut data_bytes = Bytes::with_capacity(length); - data_bytes.len = length; - data_with_offset.copy_bytes_to(data_bytes.buf.ptr, length); - data_bytes + let new_ptr = alloc_bytes(length); + + data_with_offset.copy_bytes_to(new_ptr, length); + Bytes::from(raw_slice::from_parts::(new_ptr, length)) } fn valid_input_type(index: u64, expected_type: Input) -> bool { diff --git a/sway-lib-std/src/low_level_call.sw b/sway-lib-std/src/low_level_call.sw index 353edc3c453..a8b0549cf71 100644 --- a/sway-lib-std/src/low_level_call.sw +++ b/sway-lib-std/src/low_level_call.sw @@ -1,6 +1,7 @@ //! Utilities to help with low level calls. library; +use ::alloc::alloc_bytes; use ::assert::assert; use ::asset_id::AssetId; use ::bytes::Bytes; @@ -62,13 +63,11 @@ pub struct CallParams { /// } /// ``` fn contract_id_to_bytes(contract_id: ContractId) -> Bytes { - let mut target_bytes = Bytes::with_capacity(32); - target_bytes.len = 32; + let target_ptr = alloc_bytes(32); - __addr_of(contract_id) - .copy_bytes_to(target_bytes.buf.ptr, 32); + __addr_of(contract_id).copy_bytes_to(target_ptr, 32); - target_bytes + Bytes::from(raw_slice::from_parts::(target_ptr, 32)) } /// Represent a raw pointer as a `Bytes`, so it can be concatenated with a payload. @@ -100,15 +99,14 @@ fn contract_id_to_bytes(contract_id: ContractId) -> Bytes { /// } /// ``` fn ptr_as_bytes(ptr: raw_ptr) -> Bytes { - let mut bytes = Bytes::with_capacity(8); - bytes.len = 8; + let target_ptr = alloc_bytes(8); // Need to copy pointer to heap so it has an address and can be copied onto the bytes buffer let mut ptr_on_heap = Vec::new(); ptr_on_heap.push(ptr); - ptr_on_heap.buf.ptr.copy_bytes_to(bytes.buf.ptr, 8); + ptr_on_heap.ptr().copy_bytes_to(target_ptr, 8); - bytes + Bytes::from(raw_slice::from_parts::(target_ptr, 8)) } /// Call a target contract with an already-encoded payload. @@ -145,7 +143,7 @@ fn ptr_as_bytes(ptr: raw_ptr) -> Bytes { /// ``` fn call_with_raw_payload(payload: Bytes, call_params: CallParams) { asm( - r1: payload.buf.ptr, + r1: payload.ptr(), r2: call_params.coins, r3: call_params.asset_id, r4: call_params.gas, @@ -210,7 +208,7 @@ fn create_payload( if (single_value_type_arg) { payload.append(calldata); // When calldata is copy type, just pass calldata } else { - payload.append(ptr_as_bytes(calldata.buf.ptr)); // When calldata is reference type, need to get pointer as bytes + payload.append(ptr_as_bytes(calldata.ptr())); // When calldata is reference type, need to get pointer as bytes }; payload diff --git a/sway-lib-std/src/message.sw b/sway-lib-std/src/message.sw index 9dcb15386d7..0d70bcac129 100644 --- a/sway-lib-std/src/message.sw +++ b/sway-lib-std/src/message.sw @@ -38,7 +38,7 @@ pub fn send_message(recipient: b256, msg_data: Bytes, coins: u64) { // If msg_data is empty, we just ignore it and pass `smo` a pointer to the inner value of recipient. if !msg_data.is_empty() { size = msg_data.len(); - msg_data_pointer = msg_data.buf.ptr; + msg_data_pointer = msg_data.ptr(); } asm( diff --git a/sway-lib-std/src/primitive_conversions/b256.sw b/sway-lib-std/src/primitive_conversions/b256.sw index 19da87cc854..de4625cd3e1 100644 --- a/sway-lib-std/src/primitive_conversions/b256.sw +++ b/sway-lib-std/src/primitive_conversions/b256.sw @@ -11,7 +11,7 @@ impl TryFrom for b256 { } else { let mut val = 0x0000000000000000000000000000000000000000000000000000000000000000; let ptr = __addr_of(val); - b.buf.ptr().copy_to::(ptr, 1); + b.ptr().copy_to::(ptr, 1); Some(val) } } diff --git a/sway-lib-std/src/storage/storage_bytes.sw b/sway-lib-std/src/storage/storage_bytes.sw index 14a00e3c770..7b6ea5db9aa 100644 --- a/sway-lib-std/src/storage/storage_bytes.sw +++ b/sway-lib-std/src/storage/storage_bytes.sw @@ -39,7 +39,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read, write)] fn write_slice(self, bytes: Bytes) { - write_slice(self.field_id, bytes.as_raw_slice()); + write_slice(self.field_id(), bytes.as_raw_slice()); } /// Constructs a `Bytes` type from a collection of tightly packed bytes in storage. @@ -75,7 +75,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read)] fn read_slice(self) -> Option { - match read_slice(self.field_id) { + match read_slice(self.field_id()) { Some(slice) => { Some(Bytes::from(slice)) }, @@ -119,7 +119,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read, write)] fn clear(self) -> bool { - clear_slice(self.field_id) + clear_slice(self.field_id()) } /// Returns the length of tightly packed bytes in storage. @@ -154,6 +154,6 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read)] fn len(self) -> u64 { - read::(self.field_id, 0).unwrap_or(0) + read::(self.field_id(), 0).unwrap_or(0) } } diff --git a/sway-lib-std/src/storage/storage_key.sw b/sway-lib-std/src/storage/storage_key.sw index f623c9dd65c..9735a0c7037 100644 --- a/sway-lib-std/src/storage/storage_key.sw +++ b/sway-lib-std/src/storage/storage_key.sw @@ -32,7 +32,7 @@ impl StorageKey { /// ``` #[storage(read)] pub fn read(self) -> T { - read::(self.slot, self.offset).unwrap() + read::(self.slot(), self.offset()).unwrap() } /// Reads a value of type `T` starting at the location specified by `self`. If the value @@ -63,7 +63,7 @@ impl StorageKey { /// ``` #[storage(read)] pub fn try_read(self) -> Option { - read(self.slot, self.offset) + read(self.slot(), self.offset()) } /// Writes a value of type `T` starting at the location specified by `self`. If the value @@ -95,7 +95,7 @@ impl StorageKey { /// ``` #[storage(read, write)] pub fn write(self, value: T) { - write(self.slot, self.offset, value); + write(self.slot(), self.offset(), value); } /// Clears the value at `self`. @@ -125,39 +125,9 @@ impl StorageKey { // If the generic doesn't have a size, this is an empty struct and nothing can be stored at the slot. // This clears the length value for StorageVec, StorageString, and StorageBytes // or any other Storage type. - clear::(self.field_id, 0) + clear::(self.field_id(), 0) } else { - clear::(self.slot, self.offset) - } - } - - /// Create a new `StorageKey`. - /// - /// # Arguments - /// - /// * `slot`: [b256] - The assigned location in storage for the new `StorageKey`. - /// * `offset`: [u64] - The assigned offset based on the data structure `T` for the new `StorageKey`. - /// * `field_id`: [b256] - A unique identifier for the new `StorageKey`. - /// - /// # Returns - /// - /// * [StorageKey] - The newly create `StorageKey`. - /// - /// # Examples - /// - /// ```sway - /// use std::{constants::ZERO_B256, hash::sha256}; - /// - /// fn foo() { - /// let my_key = StorageKey::::new(ZERO_B256, 0, sha256(ZERO_B256)); - /// assert(my_key.slot == ZERO_B256); - /// } - /// ``` - pub fn new(slot: b256, offset: u64, field_id: b256) -> Self { - Self { - slot, - offset, - field_id, + clear::(self.slot(), self.offset()) } } } @@ -168,7 +138,7 @@ fn test_storage_key_new() { use ::assert::assert; let key = StorageKey::::new(ZERO_B256, 0, ZERO_B256); - assert(key.slot == ZERO_B256); - assert(key.offset == 0); - assert(key.field_id == ZERO_B256); + assert(key.slot() == ZERO_B256); + assert(key.offset() == 0); + assert(key.field_id() == ZERO_B256); } diff --git a/sway-lib-std/src/storage/storage_map.sw b/sway-lib-std/src/storage/storage_map.sw index 0ef9ce402a3..feaa0b3d901 100644 --- a/sway-lib-std/src/storage/storage_map.sw +++ b/sway-lib-std/src/storage/storage_map.sw @@ -54,7 +54,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id)); + let key = sha256((key, self.field_id())); write::(key, 0, value); } @@ -89,9 +89,9 @@ where K: Hash, { StorageKey::::new( - sha256((key, self.field_id)), + sha256((key, self.field_id())), 0, - sha256((key, self.field_id)), + sha256((key, self.field_id())), ) } @@ -130,7 +130,7 @@ where where K: Hash, { - let key = sha256((key, self.slot)); + let key = sha256((key, self.slot())); clear::(key, 0) } @@ -181,7 +181,7 @@ where where K: Hash, { - let key = sha256((key, self.field_id)); + let key = sha256((key, self.field_id())); let val = read::(key, 0); diff --git a/sway-lib-std/src/storage/storage_string.sw b/sway-lib-std/src/storage/storage_string.sw index 48e7eb56f80..a2dc41b52ff 100644 --- a/sway-lib-std/src/storage/storage_string.sw +++ b/sway-lib-std/src/storage/storage_string.sw @@ -40,7 +40,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read, write)] fn write_slice(self, string: String) { - write_slice(self.slot, string.as_raw_slice()); + write_slice(self.slot(), string.as_raw_slice()); } /// Constructs a `String` type from storage. @@ -77,7 +77,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read)] fn read_slice(self) -> Option { - match read_slice(self.slot) { + match read_slice(self.slot()) { Some(slice) => { Some(String::from(slice)) }, @@ -123,7 +123,7 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read, write)] fn clear(self) -> bool { - clear_slice(self.slot) + clear_slice(self.slot()) } /// Returns the length of `String` in storage. @@ -159,6 +159,6 @@ impl StorableSlice for StorageKey { /// ``` #[storage(read)] fn len(self) -> u64 { - read::(self.slot, 0).unwrap_or(0) + read::(self.slot(), 0).unwrap_or(0) } } diff --git a/sway-lib-std/src/storage/storage_vec.sw b/sway-lib-std/src/storage/storage_vec.sw index 660aa895b92..967eef8a9d0 100644 --- a/sway-lib-std/src/storage/storage_vec.sw +++ b/sway-lib-std/src/storage/storage_vec.sw @@ -40,15 +40,15 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn push(self, value: V) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // Storing the value at the current length index (if this is the first item, starts off at 0) - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let offset = offset_calculator::(len); write::(key, offset, value); // Incrementing the length - write(self.field_id, 0, len + 1); + write(self.field_id(), 0, len + 1); } /// Removes the last element of the vector and returns it, `None` if empty. @@ -82,7 +82,7 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn pop(self) -> Option { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the length is 0, there is no item to pop from the vec if len == 0 { @@ -90,9 +90,9 @@ impl StorageKey> { } // reduces len by 1, effectively removing the last item in the vec - write(self.field_id, 0, len - 1); + write(self.field_id(), 0, len - 1); - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let offset = offset_calculator::(len - 1); read::(key, offset) } @@ -130,14 +130,14 @@ impl StorageKey> { /// ``` #[storage(read)] pub fn get(self, index: u64) -> Option> { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the index is larger or equal to len, there is no item to return if len <= index { return None; } - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let offset = offset_calculator::(index); // This StorageKey can be read by the standard storage api. // Field Id must be unique such that nested storage vecs work as they have a @@ -189,13 +189,13 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn remove(self, index: u64) -> V { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the index is larger or equal to len, there is no item to remove assert(index < len); // gets the element before removing it, so it can be returned - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let removed_offset = offset_calculator::(index); let removed_element = read::(key, removed_offset).unwrap(); @@ -213,7 +213,7 @@ impl StorageKey> { } // decrements len by 1 - write(self.field_id, 0, len - 1); + write(self.field_id(), 0, len - 1); removed_element } @@ -259,12 +259,12 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn swap_remove(self, index: u64) -> V { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the index is larger or equal to len, there is no item to remove assert(index < len); - let key = sha256(self.field_id); + let key = sha256(self.field_id()); // gets the element before removing it, so it can be returned let element_offset = offset_calculator::(index); let element_to_be_removed = read::(key, element_offset).unwrap(); @@ -275,7 +275,7 @@ impl StorageKey> { write::(key, element_offset, last_element); // decrements len by 1 - write(self.field_id, 0, len - 1); + write(self.field_id(), 0, len - 1); element_to_be_removed } @@ -317,12 +317,12 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn set(self, index: u64, value: V) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the index is higher than or equal len, there is no element to set assert(index < len); - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let offset = offset_calculator::(index); write::(key, offset, value); } @@ -370,19 +370,19 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn insert(self, index: u64, value: V) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); // if the index is larger than len, there is no space to insert assert(index <= len); // if len is 0, index must also be 0 due to above check - let key = sha256(self.field_id); + let key = sha256(self.field_id()); if len == index { let offset = offset_calculator::(index); write::(key, offset, value); // increments len by 1 - write(self.field_id, 0, len + 1); + write(self.field_id(), 0, len + 1); return; } @@ -408,7 +408,7 @@ impl StorageKey> { write::(key, offset, value); // increments len by 1 - write(self.field_id, 0, len + 1); + write(self.field_id(), 0, len + 1); } /// Returns the length of the vector. @@ -440,7 +440,7 @@ impl StorageKey> { /// ``` #[storage(read)] pub fn len(self) -> u64 { - read::(self.field_id, 0).unwrap_or(0) + read::(self.field_id(), 0).unwrap_or(0) } /// Checks whether the len is zero or not. @@ -476,7 +476,7 @@ impl StorageKey> { /// ``` #[storage(read)] pub fn is_empty(self) -> bool { - read::(self.field_id, 0).unwrap_or(0) == 0 + read::(self.field_id(), 0).unwrap_or(0) == 0 } /// Swaps two elements. @@ -516,7 +516,7 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn swap(self, element1_index: u64, element2_index: u64) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); assert(element1_index < len); assert(element2_index < len); @@ -524,7 +524,7 @@ impl StorageKey> { return; } - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let element1_offset = offset_calculator::(element1_index); let element2_offset = offset_calculator::(element2_index); @@ -567,8 +567,8 @@ impl StorageKey> { /// ``` #[storage(read)] pub fn first(self) -> Option> { - let key = sha256(self.field_id); - match read::(self.field_id, 0).unwrap_or(0) { + let key = sha256(self.field_id()); + match read::(self.field_id(), 0).unwrap_or(0) { 0 => None, _ => Some(StorageKey::::new(key, 0, sha256((0, key)))), } @@ -603,8 +603,8 @@ impl StorageKey> { /// ``` #[storage(read)] pub fn last(self) -> Option> { - let key = sha256(self.field_id); - match read::(self.field_id, 0).unwrap_or(0) { + let key = sha256(self.field_id()); + match read::(self.field_id(), 0).unwrap_or(0) { 0 => None, len => { let offset = offset_calculator::(len - 1); @@ -640,13 +640,13 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn reverse(self) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); if len < 2 { return; } - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let mid = len / 2; let mut i = 0; while i < mid { @@ -693,9 +693,9 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn fill(self, value: V) { - let len = read::(self.field_id, 0).unwrap_or(0); + let len = read::(self.field_id(), 0).unwrap_or(0); - let key = sha256(self.field_id); + let key = sha256(self.field_id()); let mut i = 0; while i < len { let offset = offset_calculator::(i); @@ -749,14 +749,14 @@ impl StorageKey> { /// ``` #[storage(read, write)] pub fn resize(self, new_len: u64, value: V) { - let mut len = read::(self.field_id, 0).unwrap_or(0); - let key = sha256(self.field_id); + let mut len = read::(self.field_id(), 0).unwrap_or(0); + let key = sha256(self.field_id()); while len < new_len { let offset = offset_calculator::(len); write::(key, offset, value); len += 1; } - write::(self.field_id, 0, new_len); + write::(self.field_id(), 0, new_len); } // TODO: This should be moved into the vec.sw file and `From> for Vec` @@ -820,11 +820,11 @@ impl StorageKey> { ptr = realloc_bytes(ptr, number_of_bytes, number_of_slots * 32); // Store `number_of_slots * 32` bytes starting at storage slot `key`. - let _ = __state_store_quad(sha256(self.field_id), ptr, number_of_slots); + let _ = __state_store_quad(sha256(self.field_id()), ptr, number_of_slots); // Store the length, NOT the bytes. // This differs from the existing `write_slice()` function to be compatible with `StorageVec`. - write::(self.field_id, 0, number_of_bytes / __size_of::()); + write::(self.field_id(), 0, number_of_bytes / __size_of::()); } /// Load a `Vec` from the `StorageVec`. @@ -861,7 +861,7 @@ impl StorageKey> { #[storage(read)] pub fn load_vec(self) -> Vec { // Get the length of the slice that is stored. - match read::(self.field_id, 0).unwrap_or(0) { + match read::(self.field_id(), 0).unwrap_or(0) { 0 => Vec::new(), len => { // Get the number of storage slots needed based on the size. @@ -869,7 +869,7 @@ impl StorageKey> { let number_of_slots = (bytes + 31) >> 5; let ptr = alloc_bytes(number_of_slots * 32); // Load the stored slice into the pointer. - let _ = __state_load_quad(sha256(self.field_id), ptr, number_of_slots); + let _ = __state_load_quad(sha256(self.field_id()), ptr, number_of_slots); Vec::from(asm(ptr: (ptr, bytes)) { ptr: raw_slice }) diff --git a/sway-lib-std/src/string.sw b/sway-lib-std/src/string.sw index 84ee30dd071..719a3233ca0 100644 --- a/sway-lib-std/src/string.sw +++ b/sway-lib-std/src/string.sw @@ -1,7 +1,7 @@ library; use ::assert::assert; -use ::bytes::Bytes; +use ::bytes::*; use ::convert::*; use ::hash::{Hash, Hasher}; use ::option::Option; @@ -15,7 +15,7 @@ use ::option::Option; /// implemented, codepoints are *not* guaranteed to fall on byte boundaries pub struct String { /// The bytes representing the characters of the string. - pub bytes: Bytes, + bytes: Bytes, } impl String { @@ -138,12 +138,9 @@ impl String { let str_size = s.len(); let str_ptr = s.as_ptr(); - let mut bytes = Bytes::with_capacity(str_size); - bytes.len = str_size; - - str_ptr.copy_bytes_to(bytes.buf.ptr(), str_size); - - Self { bytes } + Self { + bytes: Bytes::from(raw_slice::from_parts::(str_ptr, str_size)), + } } /// Returns a `bool` indicating whether the `String` is empty. @@ -216,28 +213,42 @@ impl String { bytes: Bytes::with_capacity(capacity), } } + + /// Gets the pointer of the allocation. + /// + /// # Returns + /// + /// [raw_ptr] - The location in memory that the allocated string lives. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let string = String::new(); + /// assert(!string.ptr().is_null()); + /// } + /// ``` + pub fn ptr(self) -> raw_ptr { + self.bytes.ptr() + } } impl From for String { fn from(b: Bytes) -> Self { - let mut string = Self::new(); - string.bytes = b; - string + Self { bytes: b } } } impl From for Bytes { fn from(s: String) -> Bytes { - s.bytes + s.as_bytes() } } impl AsRawSlice for String { /// Returns a raw slice to all of the elements in the string. fn as_raw_slice(self) -> raw_slice { - asm(ptr: (self.bytes.buf.ptr(), self.bytes.len)) { - ptr: raw_slice - } + self.bytes.as_raw_slice() } } @@ -251,15 +262,13 @@ impl From for String { impl From for raw_slice { fn from(s: String) -> raw_slice { - asm(ptr: (s.bytes.buf.ptr(), s.bytes.len)) { - ptr: raw_slice - } + raw_slice::from(s.as_bytes()) } } impl Eq for String { fn eq(self, other: Self) -> bool { - self.bytes == other.bytes + self.bytes == other.as_bytes() } } diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index e30ea4b04eb..47deb45dbd8 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -14,9 +14,9 @@ use ::result::Result::{self, *}; /// Represented as two 64-bit components: `(upper, lower)`, where `value = (upper << 64) + lower`. pub struct U128 { /// The most significant 64 bits of the `U128`. - pub upper: u64, + upper: u64, /// The least significant 64 bits of the `U128`. - pub lower: u64, + lower: u64, } /// The error type used for `U128` type errors. @@ -84,7 +84,7 @@ impl u64 { /// let y = u64::max(); /// let z = x.overflowing_add(y); /// - /// assert(z == U128 { upper: 1, lower: 18446744073709551614 }); + /// assert(z == U128::from(1, 18446744073709551614)); /// } /// ``` pub fn overflowing_add(self, right: Self) -> U128 { @@ -131,7 +131,7 @@ impl u64 { /// let y = u64::max(); /// let z = x.overflowing_mul(y); /// - /// assert(z == U128 { upper: 18446744073709551615, lower: 1 }); + /// assert(z == U128::from(18446744073709551615, 1)); /// } /// ``` pub fn overflowing_mul(self, right: Self) -> U128 { @@ -175,7 +175,7 @@ impl U128 { /// /// fn foo() { /// let new_u128 = U128::new(); - /// let zero_u128 = U128 { upper: 0, lower: 0 }; + /// let zero_u128 = U128::from(0, 0); /// /// assert(new_u128 == zero_u128); /// } @@ -203,7 +203,7 @@ impl U128 { /// use std::u128::{U128, U128Error}; /// /// fn foo() { - /// let zero_u128 = U128 { upper: 0, lower: 0 }; + /// let zero_u128 = U128::from(0, 0); /// let zero_u64 = zero_u128.as_u64().unwrap(); /// /// assert(zero_u64 == 0); @@ -234,7 +234,7 @@ impl U128 { /// /// fn foo() { /// let min_u128 = U128::min(); - /// let zero_u128 = U128 { upper: 0, lower: 0 }; + /// let zero_u128 = U128::from(0, 0); /// /// assert(min_u128 == zero_u128); /// } @@ -259,7 +259,7 @@ impl U128 { /// /// fn foo() { /// let max_u128 = U128::max(); - /// let maxed_u128 = U128 { upper: u64::max(), lower: u64::max() }; + /// let maxed_u128 = U128::from(u64::max(), u64::max()); /// /// assert(max_u128 == maxed_u128); /// } @@ -291,6 +291,48 @@ impl U128 { pub fn bits() -> u32 { 128 } + + /// Returns the underlying upper u64 representing the most significant 64 bits of the `U128`. + /// + /// # Returns + /// + /// * [u64] - The most significant 64 bits of the `U128`. + /// + /// # Examples + /// + /// ```sway + /// use std::u128::U128; + /// + /// fn foo() { + /// let maxed_u128 = U128::from(u64::max(), u64::min()); + /// + /// assert(maxed_u128.upper() == u64::max()); + /// } + /// ``` + pub fn upper(self) -> u64 { + self.upper + } + + /// Returns the underlying lower u64 representing the least significant 64 bits of the `U128`. + /// + /// # Returns + /// + /// * [u64] - The least significant 64 bits of the `U128`. + /// + /// # Examples + /// + /// ```sway + /// use std::u128::U128; + /// + /// fn foo() { + /// let maxed_u128 = U128::from(u64::max(), u64::min()); + /// + /// assert(maxed_u128.lower() == u64::min()); + /// } + /// ``` + pub fn lower(self) -> u64 { + self.lower + } } impl core::ops::BitwiseAnd for U128 { diff --git a/sway-lib-std/src/u256.sw b/sway-lib-std/src/u256.sw index 5d5d5bc97f9..59e1f4dadf6 100644 --- a/sway-lib-std/src/u256.sw +++ b/sway-lib-std/src/u256.sw @@ -198,7 +198,7 @@ impl U256 { /// let zero_u256 = U256 { a: 0, b: 0, c: 0, d: 0 }; /// let zero_u128 = zero_u256.as_u128().unwrap(); /// - /// assert(zero_u128 == U128 { upper: 0, lower: 0 }); + /// assert(zero_u128 == U128::from(0, 0)); /// /// let max_u256 = U256::max(); /// let result = U256.as_u64(); @@ -462,21 +462,21 @@ impl core::ops::Add for U256 { let mut overflow = 0; let mut local_res = U128::from((0, word_4)) + U128::from((0, other_word_4)); - let result_d = local_res.lower; - overflow = local_res.upper; + let result_d = local_res.lower(); + overflow = local_res.upper(); local_res = U128::from((0, word_3)) + U128::from((0, other_word_3)) + U128::from((0, overflow)); - let result_c = local_res.lower; - overflow = local_res.upper; + let result_c = local_res.lower(); + overflow = local_res.upper(); local_res = U128::from((0, word_2)) + U128::from((0, other_word_2)) + U128::from((0, overflow)); - let result_b = local_res.lower; - overflow = local_res.upper; + let result_b = local_res.lower(); + overflow = local_res.upper(); local_res = U128::from((0, word_1)) + U128::from((0, other_word_1)) + U128::from((0, overflow)); - let result_a = local_res.lower; + let result_a = local_res.lower(); // panic on overflow - assert(local_res.upper == 0); + assert(local_res.upper() == 0); Self::from((result_a, result_b, result_c, result_d)) } } @@ -573,20 +573,20 @@ impl core::ops::Multiply for U256 { let result_d_c = self.d.overflowing_mul(other.c); let result_d_d = self.d.overflowing_mul(other.d); - let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper.overflowing_add(result_c_d.lower).into(); - let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower).into(); + let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper().overflowing_add(result_c_d.lower()).into(); + let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower()).into(); let (overflow_of_b_to_a_0, overflow_of_c_to_b_2): (u64, u64) = overflow_of_c_to_b_1.overflowing_add(overflow_of_c_to_b_2).into(); - let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_b_d.lower.overflowing_add(result_c_d.upper).into(); - let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper).into(); + let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_b_d.lower().overflowing_add(result_c_d.upper()).into(); + let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper()).into(); let (overflow_of_b_to_a_3, b): (u64, u64) = b.overflowing_add(overflow_of_c_to_b_2).into(); Self::from(( - self.b * other.c + result_b_d.upper + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, + self.b * other.c + result_b_d.upper() + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, b, c, - result_d_d.lower, + result_d_d.lower(), )) } else if other.b != 0 { // If `other.b` is nonzero, `self.b` has to be zero. Otherwise, overflow is @@ -598,20 +598,20 @@ impl core::ops::Multiply for U256 { let result_d_c = other.d.overflowing_mul(self.c); let result_d_d = other.d.overflowing_mul(self.d); - let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper.overflowing_add(result_c_d.lower).into(); - let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower).into(); + let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper().overflowing_add(result_c_d.lower()).into(); + let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower()).into(); let (overflow_of_b_to_a_0, overflow_of_c_to_b_2): (u64, u64) = overflow_of_c_to_b_1.overflowing_add(overflow_of_c_to_b_2).into(); - let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_b_d.lower.overflowing_add(result_c_d.upper).into(); - let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper).into(); + let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_b_d.lower().overflowing_add(result_c_d.upper()).into(); + let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper()).into(); let (overflow_of_b_to_a_3, b): (u64, u64) = b.overflowing_add(overflow_of_c_to_b_2).into(); Self::from(( - other.b * self.c + result_b_d.upper + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, + other.b * self.c + result_b_d.upper() + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, b, c, - result_d_d.lower, + result_d_d.lower(), )) } else { // note, that `self.a`, `self.b`, `other.a`, `other.b` are all equal to 0 @@ -620,22 +620,22 @@ impl core::ops::Multiply for U256 { let result_d_c = self.d.overflowing_mul(other.c); let result_d_d = self.d.overflowing_mul(other.d); - let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper.overflowing_add(result_c_d.lower).into(); + let (overflow_of_c_to_b_1, mut c): (u64, u64) = result_d_d.upper().overflowing_add(result_c_d.lower()).into(); - let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower).into(); + let (mut overflow_of_c_to_b_2, c): (u64, u64) = c.overflowing_add(result_d_c.lower()).into(); let (overflow_of_b_to_a_0, overflow_of_c_to_b_2): (u64, u64) = overflow_of_c_to_b_1.overflowing_add(overflow_of_c_to_b_2).into(); - let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_c_c.lower.overflowing_add(result_c_d.upper).into(); - let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper).into(); + let (overflow_of_b_to_a_1, mut b): (u64, u64) = result_c_c.lower().overflowing_add(result_c_d.upper()).into(); + let (overflow_of_b_to_a_2, b): (u64, u64) = b.overflowing_add(result_d_c.upper()).into(); let (overflow_of_b_to_a_3, b): (u64, u64) = b.overflowing_add(overflow_of_c_to_b_2).into(); Self::from(( // as overflow for a means overflow for the whole number, we are adding as is, not using `overflowing_add` - result_c_c.upper + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, + result_c_c.upper() + overflow_of_b_to_a_3 + overflow_of_b_to_a_2 + overflow_of_b_to_a_1 + overflow_of_b_to_a_0, b, c, - result_d_d.lower, + result_d_d.lower(), )) } } @@ -657,7 +657,7 @@ impl core::ops::Divide for U256 { && divisor.b == 0 { let res = U128::from((self.c, self.d)) / U128::from((divisor.c, divisor.d)); - return Self::from((0, 0, res.upper, res.lower)); + return Self::from((0, 0, res.upper(), res.lower())); } let mut quotient = Self::from((0, 0, 0, 0)); diff --git a/sway-lib-std/src/vec.sw b/sway-lib-std/src/vec.sw index 31b46f049c8..53d8dde9906 100644 --- a/sway-lib-std/src/vec.sw +++ b/sway-lib-std/src/vec.sw @@ -8,7 +8,7 @@ use ::convert::From; use ::iterator::*; struct RawVec { - pub ptr: raw_ptr, + ptr: raw_ptr, cap: u64, } @@ -129,9 +129,18 @@ impl RawVec { } } +impl From for RawVec { + fn from(slice: raw_slice) -> Self { + Self { + ptr: slice.ptr(), + cap: slice.len::(), + } + } +} + /// A contiguous growable array type, written as `Vec`, short for 'vector'. pub struct Vec { - pub buf: RawVec, + buf: RawVec, len: u64, } @@ -257,7 +266,7 @@ impl Vec { /// } /// ``` pub fn capacity(self) -> u64 { - self.buf.cap + self.buf.capacity() } /// Clears the vector, removing all values. @@ -456,7 +465,7 @@ impl Vec { assert(index <= self.len); // If there is insufficient capacity, grow the buffer. - if self.len == self.buf.cap { + if self.len == self.buf.capacity() { self.buf.grow(); } @@ -595,6 +604,24 @@ impl Vec { index: 0, } } + + /// Gets the pointer of the allocation. + /// + /// # Returns + /// + /// [raw_ptr] - The location in memory that the allocated vec lives. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let vec = Vec::new(); + /// assert(!vec.ptr().is_null()); + /// } + /// ``` + pub fn ptr(self) -> raw_ptr { + self.buf.ptr() + } } impl AsRawSlice for Vec { @@ -605,20 +632,16 @@ impl AsRawSlice for Vec { impl From for Vec { fn from(slice: raw_slice) -> Self { - let buf = RawVec { - ptr: slice.ptr(), - cap: slice.len::(), - }; Self { - buf, - len: buf.cap, + buf: RawVec::from(slice), + len: slice.len::(), } } } impl From> for raw_slice { fn from(vec: Vec) -> Self { - asm(ptr: (vec.buf.ptr(), vec.len)) { + asm(ptr: (vec.ptr(), vec.len())) { ptr: raw_slice } } diff --git a/sway-lib-std/src/vm/evm/ecr.sw b/sway-lib-std/src/vm/evm/ecr.sw index 2a1bb375afa..09bbd65a45c 100644 --- a/sway-lib-std/src/vm/evm/ecr.sw +++ b/sway-lib-std/src/vm/evm/ecr.sw @@ -47,7 +47,7 @@ pub fn ec_recover_evm_address( _ => { let pub_key = pub_key_result.unwrap(); // Note that EVM addresses are derived from the Keccak256 hash of the pubkey (not sha256) - let pubkey_hash = keccak256(((pub_key.bytes)[0], (pub_key.bytes)[1])); + let pubkey_hash = keccak256(((pub_key.bits())[0], (pub_key.bits())[1])); Ok(EvmAddress::from(pubkey_hash)) } } diff --git a/sway-lib-std/src/vm/evm/evm_address.sw b/sway-lib-std/src/vm/evm/evm_address.sw index dac6d23a57b..a14ad1eedc3 100644 --- a/sway-lib-std/src/vm/evm/evm_address.sw +++ b/sway-lib-std/src/vm/evm/evm_address.sw @@ -8,12 +8,34 @@ use ::hash::*; /// The `EvmAddress` type, a struct wrapper around the inner `b256` value. pub struct EvmAddress { /// The underlying evm address data. - value: b256, + bits: b256, +} + +impl EvmAddress { + /// Returns the underlying bits for the EvmAddress type. + /// + /// # Returns + /// + /// * [b256] - The `b256` that make up the EvmAddress. + /// + /// # Examples + /// + /// ```sway + /// use std::{evm::EvmAddress, constants::ZERO_B256); + /// + /// fn foo() { + /// let evm_address = EvmAddress::from(ZERO_B256); + /// assert(evm_address.bits() == ZERO_B256); + /// } + /// ``` + pub fn bits(self) -> b256 { + self.bits + } } impl core::ops::Eq for EvmAddress { fn eq(self, other: Self) -> bool { - self.value == other.value + self.bits == other.bits } } @@ -28,20 +50,20 @@ impl From for EvmAddress { }; Self { - value: local_bits, + bits: local_bits, } } } impl From for b256 { fn from(addr: EvmAddress) -> b256 { - addr.value + addr.bits } } impl Hash for EvmAddress { fn hash(self, ref mut state: Hasher) { - let Address { value } = self; - value.hash(state); + let Address { bits } = self; + bits.hash(state); } } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/src/main.sw index db330ca0c15..df405990c00 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/generics_in_contract/src/main.sw @@ -9,12 +9,12 @@ impl StorageKey> where K: Hash { // annotated with `Vec`. #[storage(read)] fn to_vec1(self, key: K) -> Vec { - let k = sha256((key, self.slot)); + let k = sha256((key, self.slot())); let len = read::(k, 0).unwrap_or(0); let mut i = 0; let mut vec: Vec = Vec::new(); while len > i { - let k = sha256((key, i, self.slot)); + let k = sha256((key, i, self.slot())); let item = read::(k, 0).unwrap(); vec.push(item); // <----- i += 1; @@ -26,12 +26,12 @@ impl StorageKey> where K: Hash { // the type of `vec` (`Vec`) is taken from the `vec.push` statement. #[storage(read)] fn to_vec2(self, key: K) -> Vec { - let k = sha256((key, self.slot)); + let k = sha256((key, self.slot())); let len = read::(k, 0).unwrap_or(0); let mut i = 0; let mut vec/*: Vec*/ = Vec::new(); while len > i { - let k = sha256((key, i, self.slot)); + let k = sha256((key, i, self.slot())); let item = read::(k, 0).unwrap(); vec.push(item); // <----- i += 1; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/complex_cfg/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/complex_cfg/src/main.sw index d004bd15fee..decd05e37a9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/complex_cfg/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/complex_cfg/src/main.sw @@ -7,10 +7,7 @@ pub enum Error { } fn main() { - let x = U128 { - upper: 0, - lower: 0, - }; + let x = U128::from((0, 0)); let cond = false; require(cond || (x < U128::from((1, 1)) || x == U128::from((1, 1))), Error::Overflow); } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json index c8861f60a71..877e58079fd 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json @@ -7,7 +7,7 @@ "typeArguments": null }, "name": "C0", - "offset": 4284 + "offset": 4476 }, { "configurableType": { @@ -16,7 +16,7 @@ "typeArguments": null }, "name": "C1", - "offset": 4300 + "offset": 4492 }, { "configurableType": { @@ -25,7 +25,7 @@ "typeArguments": null }, "name": "C2", - "offset": 4316 + "offset": 4508 }, { "configurableType": { @@ -34,7 +34,7 @@ "typeArguments": [] }, "name": "C3", - "offset": 4348 + "offset": 4540 }, { "configurableType": { @@ -43,7 +43,7 @@ "typeArguments": [] }, "name": "C4", - "offset": 4364 + "offset": 4556 }, { "configurableType": { @@ -52,7 +52,7 @@ "typeArguments": [] }, "name": "C5", - "offset": 4380 + "offset": 4572 }, { "configurableType": { @@ -61,7 +61,7 @@ "typeArguments": null }, "name": "C6", - "offset": 4396 + "offset": 4588 }, { "configurableType": { @@ -70,7 +70,7 @@ "typeArguments": null }, "name": "C7", - "offset": 4412 + "offset": 4604 }, { "configurableType": { @@ -79,7 +79,7 @@ "typeArguments": null }, "name": "C7_2", - "offset": 4516 + "offset": 4708 }, { "configurableType": { @@ -88,7 +88,7 @@ "typeArguments": null }, "name": "C9", - "offset": 4460 + "offset": 4652 } ], "functions": [ diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_inits/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_inits/src/main.sw index 231de9bbd14..f24142fe576 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_inits/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_inits/src/main.sw @@ -70,7 +70,7 @@ const EN1a = En1::Int(101); const EN1b = En1::Arr(ARR2); const EN1c = En1::NoVal; -const ETH_ID0_VALUE = ETH_ID0.value; +const ETH_ID0_VALUE = ETH_ID0.bits(); const TUP1_idx2 = TUP1.2; const INT1 = 1; @@ -145,7 +145,7 @@ fn main() -> u64 { } // Struct and enum field access. - assert(ETH_ID0.value == ETH_ID0_VALUE); + assert(ETH_ID0.bits() == ETH_ID0_VALUE); assert(TUP1_idx2 == TUP1.2); assert(XPY == 2); assert(SO == __size_of::()); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_caller_as_ret/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_caller_as_ret/src/main.sw index d54a24f8a2c..99243841d0a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_caller_as_ret/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/contract_caller_as_ret/src/main.sw @@ -11,5 +11,5 @@ impl MyContract for Contract { } fn caller(address: ContractId) -> ContractCaller<_> { - abi(MyContract, address.value) + abi(MyContract, address.bits()) } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/empty_method_initializer/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/empty_method_initializer/src/main.sw index f0a332e5e96..579a1caca9b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/empty_method_initializer/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/empty_method_initializer/src/main.sw @@ -8,5 +8,5 @@ fn main() -> bool { let b = B512::from((hi_bits, lo_bits)); let other_b = B512::new(); - ((b.bytes)[0] != (other_b.bytes)[0]) && ((b.bytes)[1] == (other_b.bytes)[1]) + ((b.bits())[0] != (other_b.bits())[0]) && ((b.bits())[1] == (other_b.bits())[1]) } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/enum_if_let/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/enum_if_let/src/main.sw index 0098e356e58..bb92fabb834 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/enum_if_let/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/enum_if_let/src/main.sw @@ -1,8 +1,6 @@ script; -const B1 = Address { - value: 0x0100000000000000000000000000000000000000000000000000000000000010 -}; +const B1 = Address::from(0x0100000000000000000000000000000000000000000000000000000000000010); fn main() -> u64 { let a = Result::Ok::(100); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/raw_ptr/raw_ptr_ret/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/raw_ptr/raw_ptr_ret/src/main.sw index 644d59074dd..2dd2273f0ac 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/raw_ptr/raw_ptr_ret/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/raw_ptr/raw_ptr_ret/src/main.sw @@ -5,5 +5,5 @@ use std::vec::Vec; fn main() -> raw_ptr { let mut a : Vec = Vec::new(); a.push(1234); - a.buf.ptr + a.ptr() } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias/src/main.sw index 2078be83e30..c141e60547f 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias/src/main.sw @@ -131,31 +131,29 @@ impl core::ops::Eq for MyEnumTypeAlias2 { } fn enum_tests() { - let x = ContractId { - value: 0x0000000000000000000000000000000000000000000000000000000000000001, - }; + let x = ContractId::from(0x0000000000000000000000000000000000000000000000000000000000000001); let z: SubId = 0x0000000000000000000000000000000000000000000000000000000000000001; let o = Some(x); - if let Some(ContractId { value }) = o { - assert(value == z); + if let Some(value) = o { + assert(value.bits() == z); } let value = match o { - Some(value) => value.value, + Some(value) => value.bits(), None => revert(42), }; let id1 = lib::MyIdentity::ContractId(x); let id2 = lib::MyIdentity::ContractId(x); match id1 { - lib::MyIdentity::ContractId(ContractId { value }) => assert(value == 0x0000000000000000000000000000000000000000000000000000000000000001), + lib::MyIdentity::ContractId(id) => assert(id.bits() == 0x0000000000000000000000000000000000000000000000000000000000000001), _ => revert(42), } assert(id1 == id2); // test trait `Eq` let id3 = lib::MyIdentity::Address(Address::from(0x1111111111111111111111111111111111111111111111111111111111111111)); let id4 = lib::MyIdentity::Address(Address::from(0x1111111111111111111111111111111111111111111111111111111111111111)); match id3 { - lib::MyIdentity::Address(Address { value }) => assert(value == 0x1111111111111111111111111111111111111111111111111111111111111111), + lib::MyIdentity::Address(id) => assert(id.bits() == 0x1111111111111111111111111111111111111111111111111111111111111111), _ => revert(42), } assert(id3 == id4); 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 c8878041b82..3052b722be6 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 @@ -10,7 +10,7 @@ fn main() -> bool { let default_gas = 1_000_000_000_000; // the deployed fuel_coin Contract_Id: - let fuelcoin_id = ContractId::from(0x5d10689c7eecb405937a3f35fab7baf05a3f6189f9a2993ee70e21ccc1212460); + let fuelcoin_id = ContractId::from(0x542c6e67e5e8768a2c119a80ddcbd1f8d01110ced16fda37e4aa77ebb6d6cdb9); let fuelcoin_asset_id = AssetId::new(fuelcoin_id, DEFAULT_SUB_ID); // contract ID for sway/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/balance_test_contract/ 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 867475b9ac9..0105fae4e0a 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 @@ -2,7 +2,7 @@ script; use basic_storage_abi::{BasicStorage, Quad}; fn main() -> u64 { - let addr = abi(BasicStorage, 0xa4174c9ff114dc3a99eee9d8f43e417276852a6ba41b8ea469b54385a6596db4); + let addr = abi(BasicStorage, 0xd956f6bb7ee577561325f16f51534c001061342972a0bef9c2dcfc6d83919491); let key = 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; let value = 4242; 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 ff71b5c178a..5b619767541 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 @@ -3,7 +3,7 @@ script; use storage_enum_abi::*; fn main() -> u64 { - let contract_id = 0x4c01b41e6f7fc88c88a7799c43d9f695e22ee01eed90478b99fe3bfa935e3e07; + let contract_id = 0x039f59a5f7ab74f3c75eedaedeabdbff9b8bc5310f44ff10b0344fc316026e7d; let caller = abi(StorageEnum, contract_id); let res = caller.read_write_enums(); 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 d3e9edee03b..ef9d8ef7049 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 @@ -16,7 +16,7 @@ fn main() -> bool { let returned_contract_id = test_contract.get_id { gas: gas, coins: 0, - asset_id: BASE_ASSET_ID.value, + asset_id: BASE_ASSET_ID.bits(), }(); let returned_contract_id_b256: b256 = returned_contract_id.into(); assert(returned_contract_id_b256 == other_contract_id_b256); @@ -26,7 +26,7 @@ fn main() -> bool { let returned_this_balance = test_contract.get_this_balance { gas: gas, coins: 0, - asset_id: BASE_ASSET_ID.value, + asset_id: BASE_ASSET_ID.bits(), }(base_asset_id); assert(returned_this_balance == 0); @@ -34,7 +34,7 @@ fn main() -> bool { let returned_contract_balance = test_contract.get_balance_of_contract { gas: gas, coins: 0, - asset_id: BASE_ASSET_ID.value, + asset_id: BASE_ASSET_ID.bits(), }(base_asset_id, other_contract_id); assert(returned_contract_balance == 0); 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 021fb71d3f1..e4170911cf1 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 @@ -4,7 +4,7 @@ use storage_access_abi::*; use std::hash::*; fn main() -> bool { - let contract_id = 0xed4bbc1286211512f6894d6eded69eb27a8eaf551de44f10d2efb93088d9db82; + let contract_id = 0xcd976bf8d7f3a9b54416c215ee0c732cbae4f9221e281fbc6c6aa8f428f03eb1; let caller = abi(StorageAccess, contract_id); caller.set_boolean(true); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/return_into/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/return_into/src/main.sw index 3ea105ff406..d3b94c7b327 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/return_into/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/return_into/src/main.sw @@ -1,6 +1,6 @@ script; -use std::bytes::Bytes; +use std::{alloc::alloc_bytes, bytes::Bytes}; pub trait MyFrom { fn my_from(b: T) -> Self; @@ -10,18 +10,18 @@ pub trait MyFrom { impl MyFrom for Bytes { fn my_from(b: b256) -> Self { // Artificially create bytes with capacity and len - let mut bytes = Self::with_capacity(32); - bytes.len = 32; + let new_ptr = alloc_bytes(32); + // Copy bytes from contract_id into the buffer of the target bytes - __addr_of(b).copy_bytes_to(bytes.buf.ptr, 32); + __addr_of(b).copy_bytes_to(new_ptr, 32); - bytes + Bytes::from(raw_slice::from_parts::(new_ptr, 32)) } fn my_into(self) -> b256 { let mut value = 0x0000000000000000000000000000000000000000000000000000000000000000; let ptr = __addr_of(value); - self.buf.ptr().copy_to::(ptr, 1); + self.ptr().copy_to::(ptr, 1); value } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/address_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/address_test/src/main.sw index 22abbd66866..4cc5310a0b4 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/address_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/address_test/src/main.sw @@ -8,7 +8,7 @@ fn main() -> bool { // test from() let addr = Address::from(bits); - assert(addr.value == bits); + assert(addr.bits() == bits); // test into() let new_bits:b256 = addr.into(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_eq/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_eq/json_abi_oracle.json index 83d510920fc..57d2aa0915a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_eq/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_eq/json_abi_oracle.json @@ -242,7 +242,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } @@ -254,7 +254,7 @@ { "components": [ { - "name": "bytes", + "name": "bits", "type": 0, "typeArguments": null } @@ -300,7 +300,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_ne/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_ne/json_abi_oracle.json index 83d510920fc..57d2aa0915a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_ne/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/assert_ne/json_abi_oracle.json @@ -242,7 +242,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } @@ -254,7 +254,7 @@ { "components": [ { - "name": "bytes", + "name": "bits", "type": 0, "typeArguments": null } @@ -300,7 +300,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_struct_alignment/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_struct_alignment/src/main.sw index 0d2e9f4f1bd..166e87c430e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_struct_alignment/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_struct_alignment/src/main.sw @@ -8,5 +8,5 @@ fn main() -> bool { let b: B512 = B512::from((hi_bits, lo_bits)); - (b.bytes)[1] == lo_bits && (b.bytes)[0] == hi_bits + (b.bits())[1] == lo_bits && (b.bits())[0] == hi_bits } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_test/src/main.sw index 983ffe97be9..f759e2d56cf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/b512_test/src/main.sw @@ -4,7 +4,7 @@ use std::b512::*; // helper to prove contiguity of memory in B512 type's hi & lo fields. fn are_fields_contiguous(big_value: B512) -> bool { - asm(r1: (big_value.bytes)[0], r2: (big_value.bytes)[1], r3, r4, r5, r6) { + asm(r1: (big_value.bits())[0], r2: (big_value.bits())[1], r3, r4, r5, r6) { move r3 sp; // Save a copy of SP in R3. cfei i64; // Reserve 512 bits of stack space. SP is now R3+64. mcpi r3 r1 i64; // Copy 64 bytes *starting at* big_value.hi (includes big_value.lo) @@ -24,23 +24,14 @@ fn main() -> bool { // it allows creation of new empty type: let mut a = B512::new(); - assert(((a.bytes)[0] == zero) && ((a.bytes)[1] == zero)); - - // it allows reassignment of fields: - a.bytes = [hi_bits, lo_bits]; - assert(((a.bytes)[0] == hi_bits) && ((a.bytes)[1] == lo_bits)); + assert(((a.bits())[0] == zero) && ((a.bits())[1] == zero)); // it allows building from 2 b256's: let mut b = B512::from((hi_bits, lo_bits)); - assert(((b.bytes)[0] == hi_bits) && ((b.bytes)[1] == lo_bits)); - - // it allows reassignment of fields: - b.bytes = [modified, modified]; - assert(((b.bytes)[0] == modified) && ((b.bytes)[1] == modified)); + assert(((b.bits())[0] == hi_bits) && ((b.bits())[1] == lo_bits)); // it guarantees memory contiguity: - let mut c = B512::new(); - c.bytes = [hi_bits, lo_bits]; + let mut c = B512::from((hi_bits, lo_bits)); assert(are_fields_contiguous(c)); // it allows direct comparison of equality: diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/contract_id_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/contract_id_test/src/main.sw index 5e5e3194b74..68c35677f93 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/contract_id_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/contract_id_test/src/main.sw @@ -5,7 +5,7 @@ fn main() -> bool { // test from() let id = ContractId::from(bits); - assert(id.value == bits); + assert(id.bits() == bits); // test into() let new_bits:b256 = id.into(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_div_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_div_test/src/main.sw index 8de5e5c6bcb..b5ee4d61e1c 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_div_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_div_test/src/main.sw @@ -10,14 +10,14 @@ fn main() -> bool { let _one_upper = U128::from((1, 0)); let div_max_two = max_u64 / two; - assert(div_max_two.upper == 0); - assert(div_max_two.lower == u64::max() >> 1); + assert(div_max_two.upper() == 0); + assert(div_max_two.lower() == u64::max() >> 1); // Product of u64::MAX and u64::MAX. let dividend = U128::from((u64::max() - 1, 1)); let div_max_max = dividend / max_u64; - assert(div_max_max.upper == 0); - assert(div_max_max.lower == u64::max()); + assert(div_max_max.upper() == 0); + assert(div_max_max.lower() == u64::max()); true } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_mul_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_mul_test/src/main.sw index fff890c96ea..f86aadcb759 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_mul_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_mul_test/src/main.sw @@ -9,16 +9,16 @@ fn main() -> bool { let _one_upper = U128::from((1, 0)); let mul_128_of_two = max_u64 * two; - assert(mul_128_of_two.upper == 1); - assert(mul_128_of_two.lower == u64::max() - 1); + assert(mul_128_of_two.upper() == 1); + assert(mul_128_of_two.lower() == u64::max() - 1); let mul_128_of_four = mul_128_of_two * two; - assert(mul_128_of_four.upper == 3); - assert(mul_128_of_four.lower == u64::max() - 3); + assert(mul_128_of_four.upper() == 3); + assert(mul_128_of_four.lower() == u64::max() - 3); let mul_128_max = max_u64 * max_u64; - assert(mul_128_max.upper == u64::max() - 1); - assert(mul_128_max.lower == 1); + assert(mul_128_max.upper() == u64::max() - 1); + assert(mul_128_max.lower() == 1); true } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_test/src/main.sw index 4f6f4fd351a..39bb7d8fadf 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_test/src/main.sw @@ -8,85 +8,85 @@ fn main() -> bool { let max_u64 = U128::from((0, u64::max())); let one = first + second; - assert(one.upper == 0); - assert(one.lower == 1); + assert(one.upper() == 0); + assert(one.lower() == 1); let two = one + one; - assert(two.upper == 0); - assert(two.lower == 2); + assert(two.upper() == 0); + assert(two.lower() == 2); let add_of_one = max_u64 + one; - assert(add_of_one.upper == 1); - assert(add_of_one.lower == 0); + assert(add_of_one.upper() == 1); + assert(add_of_one.lower() == 0); let add_of_two = max_u64 + two; - assert(add_of_two.upper == 1); - assert(add_of_two.lower == 1); + assert(add_of_two.upper() == 1); + assert(add_of_two.lower() == 1); let add_max = max_u64 + max_u64; - assert(add_max.upper == 1); - assert(add_max.lower == u64::max() - 1); + assert(add_max.upper() == 1); + assert(add_max.lower() == u64::max() - 1); let sub_one = second - first; - assert(sub_one.upper == 0); - assert(sub_one.lower == 1); + assert(sub_one.upper() == 0); + assert(sub_one.lower() == 1); let sub_zero = first - first; - assert(sub_zero.upper == 0); - assert(sub_zero.lower == 0); + assert(sub_zero.upper() == 0); + assert(sub_zero.lower() == 0); let sub_max_again = add_of_two - two; - assert(sub_max_again.upper == 0); - assert(sub_max_again.lower == u64::max()); + assert(sub_max_again.upper() == 0); + assert(sub_max_again.lower() == u64::max()); let mul_four = 2.overflowing_mul(2); - assert(mul_four.upper == 0); - assert(mul_four.lower == 4); + assert(mul_four.upper() == 0); + assert(mul_four.lower() == 4); let mul_eight = 4.overflowing_mul(2); - assert(mul_eight.upper == 0); - assert(mul_eight.lower == 8); + assert(mul_eight.upper() == 0); + assert(mul_eight.lower() == 8); let mul_of_two = u64::max().overflowing_mul(2); - assert(mul_of_two.upper == 1); - assert(mul_of_two.lower == u64::max() - 1); + assert(mul_of_two.upper() == 1); + assert(mul_of_two.lower() == u64::max() - 1); let mul_of_four = u64::max().overflowing_mul(4); - assert(mul_of_four.upper == 3); - assert(mul_of_four.lower == u64::max() - 3); + assert(mul_of_four.upper() == 3); + assert(mul_of_four.lower() == u64::max() - 3); let mul_max = u64::max().overflowing_mul(u64::max()); - assert(mul_max.upper == u64::max() - 1); - assert(mul_max.lower == 1); + assert(mul_max.upper() == u64::max() - 1); + assert(mul_max.lower() == 1); let one_upper = U128::from((1, 0)); let right_shift_one_upper = one_upper >> 1; - assert(right_shift_one_upper.upper == 0); - assert(right_shift_one_upper.lower == (1 << 63)); + assert(right_shift_one_upper.upper() == 0); + assert(right_shift_one_upper.lower() == (1 << 63)); let left_shift_one_upper_right_shift = right_shift_one_upper << 1; assert(left_shift_one_upper_right_shift == one_upper); let one_left_shift_64 = one << 64; - assert(one_left_shift_64.upper == 1); - assert(one_left_shift_64.lower == 0); + assert(one_left_shift_64.upper() == 1); + assert(one_left_shift_64.lower() == 0); let three_left_shift_one = U128::from((0, 3)) << 1; - assert(three_left_shift_one.upper == 0); - assert(three_left_shift_one.lower == 6); + assert(three_left_shift_one.upper() == 0); + assert(three_left_shift_one.lower() == 6); let not_0_3 = !U128::from((0, 3)); - assert(not_0_3.upper == u64::max()); - assert(not_0_3.lower == u64::max() - 3); + assert(not_0_3.upper() == u64::max()); + assert(not_0_3.lower() == u64::max() - 3); let not_3_3 = !U128::from((3, 3)); - assert(not_3_3.upper == u64::max() - 3); - assert(not_3_3.lower == u64::max() - 3); + assert(not_3_3.upper() == u64::max() - 3); + assert(not_3_3.lower() == u64::max() - 3); let not_3_0 = !U128::from((3, 0)); - assert(not_3_0.upper == u64::max() - 3); - assert(not_3_0.lower == u64::max()); + assert(not_3_0.upper() == u64::max() - 3); + assert(not_3_0.lower() == u64::max()); // test as_u64() let eleven = U128::from((0, 11)); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw index 95c91f09b13..ae5b63dcc70 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/basic_storage/src/main.sw @@ -59,13 +59,13 @@ impl BasicStorage for Contract { i += 1; } - let _ = __state_load_quad(key, values.buf.ptr(), slots); + let _ = __state_load_quad(key, values.ptr(), slots); values } #[storage(write)] fn intrinsic_store_quad(key: b256, values: Vec) { - let _ = __state_store_quad(key, values.buf.ptr(), values.len()); + let _ = __state_store_quad(key, values.ptr(), values.len()); } #[storage(read, write)] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/context_testing_contract/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/context_testing_contract/json_abi_oracle.json index b7ddefcc8ca..b179477d0c3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/context_testing_contract/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/context_testing_contract/json_abi_oracle.json @@ -101,7 +101,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 0, "typeArguments": null } @@ -113,7 +113,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 0, "typeArguments": null } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/contract_with_type_aliases/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/contract_with_type_aliases/json_abi_oracle.json index 9a3c0399604..e6c373b9140 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/contract_with_type_aliases/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/contract_with_type_aliases/json_abi_oracle.json @@ -188,7 +188,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 3, "typeArguments": null } @@ -200,7 +200,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 3, "typeArguments": null } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_configurable/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_configurable/json_abi_oracle.json index 339d2094534..55836889991 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_configurable/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_configurable/json_abi_oracle.json @@ -78,7 +78,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } @@ -90,7 +90,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/src/main.sw index 40702ce6c4f..6091131ef11 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/storage_namespace/src/main.sw @@ -60,13 +60,13 @@ impl BasicStorage for Contract { i += 1; } - let _ = __state_load_quad(key, values.buf.ptr(), slots); + let _ = __state_load_quad(key, values.ptr(), slots); values } #[storage(write)] fn intrinsic_store_quad(key: b256, values: Vec) { - let _ = __state_store_quad(key, values.buf.ptr(), values.len()); + let _ = __state_store_quad(key, values.ptr(), values.len()); } #[storage(read, write)] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/test_fuel_coin_contract/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/test_fuel_coin_contract/json_abi_oracle.json index 0248c09a08d..6e7758bb866 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/test_fuel_coin_contract/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/test_fuel_coin_contract/json_abi_oracle.json @@ -78,7 +78,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } @@ -90,7 +90,7 @@ { "components": [ { - "name": "value", + "name": "bits", "type": 1, "typeArguments": null } diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 815ef8a7aa2..b1e83fa5a1b 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -367,6 +367,7 @@ pub(super) async fn run( let _ = pass_mgr.run(&mut ir, &group); let ir_output = sway_ir::printer::to_string(&ir); + println!("{}", ir_output); match checker.explain(&ir_output, filecheck::NO_VARIABLES) { diff --git a/test/src/ir_generation/tests/jmp_mem.sw b/test/src/ir_generation/tests/jmp_mem.sw new file mode 100644 index 00000000000..24267ed4301 --- /dev/null +++ b/test/src/ir_generation/tests/jmp_mem.sw @@ -0,0 +1,55 @@ +// target-fuelvm + +contract; + +pub struct ContractId { + /// The underlying raw `b256` data of the contract id. + pub value: b256, +} + +abi MyContract { + fn test_function(code_id: ContractId); +} + +impl MyContract for Contract { + fn test_function(code_id_p: ContractId) { + asm(code_id, word, length, ssp_saved) { + lw code_id fp i74; + // Load the entire contract with LDC + csiz length code_id; + // Save the old ssp + move ssp_saved ssp; + ldc code_id zero length; + // Store the old ssp to MEM[$hp] so that we can jump to it. + // allocate a word the stack + addi word zero i64; + aloc word; + sw hp ssp_saved i0; + } + __jmp_mem() + } +} + +// ::check-ir:: + +// check: pub entry fn test_function<72a09f5b> + +// ::check-ir-optimized:: +// pass: o1 + +// check: pub entry fn test_function +// not: local +// check: csiz length code_id +// check: ldc code_id zero length, +// check: jmp_mem + +// ::check-asm:: + +// regex: REG=.r\d+\b + +// check: csiz $(len=$REG) $REG +// check: ldc $REG $$zero $len +// check: lw $(target=$REG) $$hp i0 ; jmp_mem: Load MEM[$$hp] +// check: sub $(jmp_target_4=$REG) $target $$is ; jmp_mem: Subtract $$is since Jmp adds it back +// check: divi $(jmp_target=$REG) $jmp_target_4 i4 ; jmp_mem: Divide by 4 since Jmp multiplies by 4 +// check: jmp $jmp_target ; jmp_mem: Jump to computed value diff --git a/test/src/ir_generation/tests/jmpb_ssp.sw b/test/src/ir_generation/tests/jmpb_ssp.sw deleted file mode 100644 index 55969c622b2..00000000000 --- a/test/src/ir_generation/tests/jmpb_ssp.sw +++ /dev/null @@ -1,62 +0,0 @@ -// target-fuelvm - -contract; - -pub struct ContractId { - /// The underlying raw `b256` data of the contract id. - pub value: b256, -} - -abi MyContract { - fn test_function(code_id: ContractId); -} - -impl MyContract for Contract { - fn test_function(code_id_p: ContractId) { - let length = asm(code_id, length, word, ssp_saved) { - // Allocate 32 bytes on the heap (we can't use the stack) - addi word zero i32; - aloc word; - - lw code_id fp i74; - - // Log the ContractID for debugging - logd zero zero code_id word; - - // Load the entire contract with LDC - csiz length code_id; - // Save the old ssp - move ssp_saved ssp; - ldc code_id zero length; - // return the ssp difference, to feed __jmpb_ssp. - // This need not always be equal to `length` as `ldc` pads the `length`. - sub length ssp ssp_saved; - length: u64 - }; - __jmpb_ssp(length) - } -} - -// ::check-ir:: - -// check: pub entry fn test_function<72a09f5b> - -// ::check-ir-optimized:: -// pass: o1 - -// check: pub entry fn test_function -// not: local -// check: csiz length code_id, !7 -// check: ldc code_id zero length, -// check: jmpb_ssp - -// ::check-asm:: - -// regex: REG=.r\d+\b - -// check: csiz $(len=$REG) $REG -// check: ldc $REG $$zero $len -// check: sub $(old_ssp=$REG) $$ssp $REG ; jmpb_ssp: Compute $$ssp - offset -// sub $(jmp_target_4=$REG) $old_ssp $$is ; jmpb_ssp: Subtract $$is since $$jmp adds it back -// divi $(jmp_target=$REG) $jmp_target_4 i4 ; jmpb_ssp: Divide by 4 since Jmp multiplies by 4 -// jmp $jmp_target ; jmpb_ssp: Jump to computed value diff --git a/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw b/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw index c0808d09100..2dd03df4d9c 100644 --- a/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw @@ -16,7 +16,7 @@ abi ContextCaller { impl ContextCaller for Contract { fn call_get_this_balance_with_coins(send_amount: u64, target: ContractId) -> u64 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); let asset_id_b256: b256 = asset_id.into(); @@ -29,7 +29,7 @@ impl ContextCaller for Contract { } fn call_get_balance_of_contract_with_coins(send_amount: u64, target: ContractId) -> u64 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); let asset_id_b256: b256 = asset_id.into(); @@ -42,7 +42,7 @@ impl ContextCaller for Contract { } fn call_get_amount_with_coins(send_amount: u64, target: ContractId) -> u64 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); @@ -54,7 +54,7 @@ impl ContextCaller for Contract { } fn call_get_asset_id_with_coins(send_amount: u64, target: ContractId) -> b256 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); @@ -66,7 +66,7 @@ impl ContextCaller for Contract { } fn call_get_gas_with_coins(send_amount: u64, target: ContractId) -> u64 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); @@ -78,7 +78,7 @@ impl ContextCaller for Contract { } fn call_get_global_gas_with_coins(send_amount: u64, target: ContractId) -> u64 { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); @@ -90,7 +90,7 @@ impl ContextCaller for Contract { } fn call_receive_coins(send_amount: u64, target: ContractId) { - let id = target.value; + let id = target.bits(); let context_contract = abi(ContextTesting, id); let asset_id = AssetId::default(); diff --git a/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw b/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw index 3d0779c0162..e2dc0765e8c 100644 --- a/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/tx_output_predicate/src/main.sw @@ -7,7 +7,7 @@ fn main(index: u64, asset_id: b256, to: b256) -> bool { let tx_asset_id = output_asset_id(index); let tx_to = output_asset_to(index); - assert(tx_asset_id.is_some() && tx_asset_id.unwrap().value == asset_id); + assert(tx_asset_id.is_some() && tx_asset_id.unwrap().bits() == asset_id); assert(tx_to.is_some() && tx_to.unwrap() == to); true diff --git a/test/src/sdk-harness/test_projects/asset_ops/src/main.sw b/test/src/sdk-harness/test_projects/asset_ops/src/main.sw index 11b29c73ec7..8e82076cc86 100644 --- a/test/src/sdk-harness/test_projects/asset_ops/src/main.sw +++ b/test/src/sdk-harness/test_projects/asset_ops/src/main.sw @@ -25,17 +25,17 @@ impl TestFuelCoin for Contract { } fn force_transfer_coins(coins: u64, asset_id: b256, target: ContractId) { - let asset_id = AssetId { value: asset_id }; + let asset_id = AssetId::from(asset_id); force_transfer_to_contract(target, asset_id, coins); } fn transfer_coins_to_address(coins: u64, asset_id: b256, to: Address) { - let asset_id = AssetId { value: asset_id }; + let asset_id = AssetId::from(asset_id); transfer_to_address(to, asset_id, coins); } fn get_balance(asset_id: b256, target: ContractId) -> u64 { - let asset_id = AssetId { value: asset_id }; + let asset_id = AssetId::from(asset_id); balance_of(target, asset_id) } @@ -52,7 +52,7 @@ impl TestFuelCoin for Contract { } fn generic_transfer(amount: u64, asset_id: b256, to: Identity) { - let asset_id = AssetId { value: asset_id }; + let asset_id = AssetId::from(asset_id); transfer(to, asset_id, amount) } diff --git a/test/src/sdk-harness/test_projects/configurables_in_contract/mod.rs b/test/src/sdk-harness/test_projects/configurables_in_contract/mod.rs index 685f1584ed6..5b925710d6e 100644 --- a/test/src/sdk-harness/test_projects/configurables_in_contract/mod.rs +++ b/test/src/sdk-harness/test_projects/configurables_in_contract/mod.rs @@ -36,6 +36,8 @@ async fn contract_uses_default_configurables() -> Result<()> { field_2: 16, }, EnumWithGeneric::VariantOne(true), + Address::new([0u8; 32]), + ContractId::new([0u8; 32]), ); assert_eq!(response.value, expected_value); @@ -59,11 +61,15 @@ async fn contract_configurables() -> Result<()> { field_2: 32, }; let new_enum = EnumWithGeneric::VariantTwo; + let new_address = Address::new([1u8; 32]); + let new_contract_id = ContractId::new([1u8; 32]); let configurables = MyContractConfigurables::new() .with_STR_4(new_str.clone()) .with_STRUCT(new_struct.clone()) - .with_ENUM(new_enum.clone()); + .with_ENUM(new_enum.clone()) + .with_ADDRESS(new_address.clone()) + .with_CONTRACT_ID(new_contract_id.clone()); let contract_id = Contract::load_from( "test_projects/configurables_in_contract/out/release/configurables_in_contract.bin", @@ -87,6 +93,8 @@ async fn contract_configurables() -> Result<()> { new_str, new_struct, new_enum, + new_address, + new_contract_id ); assert_eq!(response.value, expected_value); diff --git a/test/src/sdk-harness/test_projects/configurables_in_contract/src/main.sw b/test/src/sdk-harness/test_projects/configurables_in_contract/src/main.sw index 6e4dc97f8f2..ce488f87318 100644 --- a/test/src/sdk-harness/test_projects/configurables_in_contract/src/main.sw +++ b/test/src/sdk-harness/test_projects/configurables_in_contract/src/main.sw @@ -1,5 +1,7 @@ contract; +use std::constants::ZERO_B256; + enum EnumWithGeneric { VariantOne: D, VariantTwo: (), @@ -20,14 +22,16 @@ configurable { field_2: 16, }, ENUM: EnumWithGeneric = EnumWithGeneric::VariantOne(true), + ADDRESS: Address = Address::from(ZERO_B256), + CONTRACT_ID: ContractId = ContractId::from(ZERO_B256), } abi TestContract { - fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric, EnumWithGeneric); + fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric, EnumWithGeneric, Address, ContractId); } impl TestContract for Contract { - fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric, EnumWithGeneric) { - (U8, BOOL, ARRAY, STR_4, STRUCT, ENUM) + fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric, EnumWithGeneric, Address, ContractId) { + (U8, BOOL, ARRAY, STR_4, STRUCT, ENUM, ADDRESS, CONTRACT_ID) } } diff --git a/test/src/sdk-harness/test_projects/context/src/main.sw b/test/src/sdk-harness/test_projects/context/src/main.sw index 365c5ca2b09..be2d1d791b3 100644 --- a/test/src/sdk-harness/test_projects/context/src/main.sw +++ b/test/src/sdk-harness/test_projects/context/src/main.sw @@ -6,13 +6,13 @@ use context_testing_abi::*; impl ContextTesting for Contract { #[payable] fn get_this_balance(asset: b256) -> u64 { - let asset = AssetId { value: asset }; + let asset = AssetId::from(asset); this_balance(asset) } #[payable] fn get_balance_of_contract(asset: b256, r#contract: ContractId) -> u64 { - let asset = AssetId { value: asset }; + let asset = AssetId::from(asset); balance_of(r#contract, asset) } @@ -23,7 +23,7 @@ impl ContextTesting for Contract { #[payable] fn get_asset_id() -> b256 { - msg_asset_id().value + msg_asset_id().bits() } #[payable] diff --git a/test/src/sdk-harness/test_projects/ec_recover_and_match_predicate/src/main.sw b/test/src/sdk-harness/test_projects/ec_recover_and_match_predicate/src/main.sw index 9574f5482c5..53565baf11b 100644 --- a/test/src/sdk-harness/test_projects/ec_recover_and_match_predicate/src/main.sw +++ b/test/src/sdk-harness/test_projects/ec_recover_and_match_predicate/src/main.sw @@ -5,7 +5,7 @@ use std::{b512::B512, constants::ZERO_B256, ecr::ec_recover_address, inputs::inp fn extract_public_key_and_match(signature: B512, expected_public_key: b256) -> u64 { if let Ok(pub_key_sig) = ec_recover_address(signature, ZERO_B256) { - if pub_key_sig.value == expected_public_key { + if pub_key_sig.bits() == expected_public_key { return 1; } } diff --git a/test/src/sdk-harness/test_projects/parsing_logs/mod.rs b/test/src/sdk-harness/test_projects/parsing_logs/mod.rs index 52102b3d273..ccd0f001fef 100644 --- a/test/src/sdk-harness/test_projects/parsing_logs/mod.rs +++ b/test/src/sdk-harness/test_projects/parsing_logs/mod.rs @@ -49,6 +49,29 @@ async fn test_parse_logged_varibles() -> Result<()> { Ok(()) } +#[tokio::test] +async fn test_parse_logged_private_structs() -> Result<()> { + let (instance, _id) = get_parsing_logs_instance().await; + + let contract_methods = instance.methods(); + let response = contract_methods.produce_logs_private_structs().call().await?; + + let log_address = response.decode_logs_with_type::
().unwrap().pop().unwrap(); + let log_contract_id = response.decode_logs_with_type::().unwrap().pop().unwrap(); + let log_asset_id = response.decode_logs_with_type::().unwrap().pop().unwrap(); + + let expected_bits256 = [ + 239, 134, 175, 169, 105, 108, 240, 220, 99, 133, 226, 196, 7, 166, 225, 89, 161, 16, 60, + 239, 183, 226, 174, 6, 54, 251, 51, 211, 203, 42, 158, 74, + ]; + + assert_eq!(log_address, Address::new(expected_bits256)); + assert_eq!(log_contract_id, ContractId::new(expected_bits256)); + assert_eq!(log_asset_id, AssetId::new(expected_bits256)); + + Ok(()) +} + #[tokio::test] async fn test_parse_logs_values() -> Result<()> { let (instance, _id) = get_parsing_logs_instance().await; diff --git a/test/src/sdk-harness/test_projects/parsing_logs/src/main.sw b/test/src/sdk-harness/test_projects/parsing_logs/src/main.sw index bd6a03dfb00..92b50793ff9 100644 --- a/test/src/sdk-harness/test_projects/parsing_logs/src/main.sw +++ b/test/src/sdk-harness/test_projects/parsing_logs/src/main.sw @@ -37,6 +37,7 @@ abi TestContract { fn produce_logs_custom_types() -> (); fn produce_logs_generic_types() -> (); fn produce_multiple_logs() -> (); + fn produce_logs_private_structs() -> (); } impl TestContract for Contract { @@ -59,6 +60,16 @@ impl TestContract for Contract { log(l); } + fn produce_logs_private_structs() -> () { + let f: Address = Address::from(0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a); + let u: ContractId = ContractId::from(0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a); + let e: AssetId = AssetId::from(0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a); + + log(f); + log(u); + log(e); + } + fn produce_logs_custom_types() -> () { let f: u64 = 64; let u: b256 = 0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a; diff --git a/test/src/sdk-harness/test_projects/storage_string/src/main.sw b/test/src/sdk-harness/test_projects/storage_string/src/main.sw index dc797b8717f..2b1c9a478ff 100644 --- a/test/src/sdk-harness/test_projects/storage_string/src/main.sw +++ b/test/src/sdk-harness/test_projects/storage_string/src/main.sw @@ -29,7 +29,7 @@ impl MyContract for Contract { fn get_string() -> Bytes { match storage.stored_string.read_slice() { Option::Some(string) => { - string.bytes + string.as_bytes() }, Option::None => Bytes::new(), }