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