From da47b75b44b3684c2ad1fd577e79869c59979d1e Mon Sep 17 00:00:00 2001 From: Toby Hutton Date: Wed, 13 Apr 2022 20:18:36 +1000 Subject: [PATCH] Fix contract call args handling. Re-introduce the special case where if there's a single argument to a function call it is embedded directly in the call frame rather than being a pointer to the args elsewhere. --- sway-core/src/asm_generation/from_ir.rs | 227 ++++++++++-------- sway-core/src/optimize.rs | 142 +++++++---- .../ir_to_asm/nested_single_word_struct.asm | 2 - sway-core/tests/ir_to_asm/simple_contract.asm | 24 +- .../tests/sway_to_ir/simple_contract_call.ir | 112 +++++---- .../tests/test_projects/context/mod.rs | 40 ++- .../tests/test_projects/token_ops/mod.rs | 52 ++-- .../tests/test_projects/tx_fields/mod.rs | 141 ++++++----- .../call_basic_storage/src/main.sw | 2 +- .../call_increment_contract/src/main.sw | 2 +- .../caller_context_test/src/main.sw | 2 +- .../token_ops_test/src/main.sw | 2 +- 12 files changed, 400 insertions(+), 348 deletions(-) diff --git a/sway-core/src/asm_generation/from_ir.rs b/sway-core/src/asm_generation/from_ir.rs index d55b8a6536c..9413baa7632 100644 --- a/sway-core/src/asm_generation/from_ir.rs +++ b/sway-core/src/asm_generation/from_ir.rs @@ -11,7 +11,7 @@ use std::collections::HashMap; use crate::{ asm_generation::{ - build_contract_abi_switch, build_preamble, finalized_asm::FinalizedAsm, + build_contract_abi_switch, build_preamble, compiler_constants, finalized_asm::FinalizedAsm, register_sequencer::RegisterSequencer, AbstractInstructionSet, DataId, DataSection, SwayAsmSet, }, @@ -227,16 +227,101 @@ impl<'ir> AsmBuilder<'ir> { return; } - // Nothing to do if there are no arguments - if function.args_iter(self.context).next().is_none() { - return; + match function.args_iter(self.context).count() { + // Nothing to do if there are no arguments + 0 => (), + + // A special case for when there's only a single arg, its value (or address) is placed + // directly in the base register. + 1 => { + let (_, val) = function.args_iter(self.context).next().unwrap(); + let single_arg_reg = self.value_to_register(val); + self.read_args_value_from_frame(&single_arg_reg); + } + + // Otherwise, the args are bundled together and pointed to by the base register. + _ => { + let args_base_reg = self.reg_seqr.next(); + self.read_args_value_from_frame(&args_base_reg); + + // Successively load each argument. The asm generated depends on the arg type size + // and whether the offset fits in a 12-bit immediate. + let mut arg_word_offset = 0; + for (name, val) in function.args_iter(self.context) { + let current_arg_reg = self.value_to_register(val); + let arg_type = val.get_type(self.context).unwrap(); + let arg_type_size_bytes = ir_type_size_in_bytes(self.context, &arg_type); + if arg_type.is_copy_type() { + if arg_word_offset > compiler_constants::TWELVE_BITS { + let offs_reg = self.reg_seqr.next(); + self.bytecode.push(Op { + opcode: Either::Left(VirtualOp::ADD( + args_base_reg.clone(), + args_base_reg.clone(), + offs_reg.clone(), + )), + comment: format!("Get offset for arg {}", name), + owning_span: None, + }); + self.bytecode.push(Op { + opcode: Either::Left(VirtualOp::LW( + current_arg_reg.clone(), + offs_reg, + VirtualImmediate12 { value: 0 }, + )), + comment: format!("Get arg {}", name), + owning_span: None, + }); + } else { + self.bytecode.push(Op { + opcode: Either::Left(VirtualOp::LW( + current_arg_reg.clone(), + args_base_reg.clone(), + VirtualImmediate12 { + value: arg_word_offset as u16, + }, + )), + comment: format!("Get arg {}", name), + owning_span: None, + }); + } + } else if arg_word_offset * 8 > compiler_constants::TWELVE_BITS { + let offs_reg = self.reg_seqr.next(); + self.number_to_reg(arg_word_offset * 8, &offs_reg, None); + self.bytecode.push(Op { + opcode: either::Either::Left(VirtualOp::ADD( + current_arg_reg.clone(), + args_base_reg.clone(), + offs_reg, + )), + comment: format!("Get offset or arg {}", name), + owning_span: None, + }); + } else { + self.bytecode.push(Op { + opcode: either::Either::Left(VirtualOp::ADDI( + current_arg_reg.clone(), + args_base_reg.clone(), + VirtualImmediate12 { + value: (arg_word_offset * 8) as u16, + }, + )), + comment: format!("Get address for arg {}", name), + owning_span: None, + }); + } + + arg_word_offset += size_bytes_in_words!(arg_type_size_bytes); + } + } } + } - // Base pointer for the arumgnets using the $fp register - let args_base_reg = self.reg_seqr.next(); + // Read the argument(s) base from the call frame. + fn read_args_value_from_frame(&mut self, reg: &VirtualRegister) { self.bytecode.push(Op { opcode: Either::Left(VirtualOp::LW( - args_base_reg.clone(), + reg.clone(), VirtualRegister::Constant(ConstantRegister::FramePointer), // see https://github.com/FuelLabs/fuel-specs/pull/193#issuecomment-876496372 VirtualImmediate12 { value: 74 }, @@ -244,76 +329,6 @@ impl<'ir> AsmBuilder<'ir> { comment: "Base register for method parameter".into(), owning_span: None, }); - - // Successively load each argument. The asm generated depends on the arg type size and - // whether the offset fits in a 12-bit immediate. - let mut arg_word_offset = 0; - for (name, val) in function.args_iter(self.context) { - let current_arg_reg = self.value_to_register(val); - let arg_type = val.get_type(self.context).unwrap(); - let arg_type_size_bytes = ir_type_size_in_bytes(self.context, &arg_type); - if arg_type.is_copy_type() { - if arg_word_offset > crate::asm_generation::compiler_constants::TWELVE_BITS { - let offs_reg = self.reg_seqr.next(); - self.bytecode.push(Op { - opcode: Either::Left(VirtualOp::ADD( - args_base_reg.clone(), - args_base_reg.clone(), - offs_reg.clone(), - )), - comment: format!("Get offset for arg {}", name), - owning_span: None, - }); - self.bytecode.push(Op { - opcode: Either::Left(VirtualOp::LW( - current_arg_reg.clone(), - offs_reg, - VirtualImmediate12 { value: 0 }, - )), - comment: format!("Get arg {}", name), - owning_span: None, - }); - } else { - self.bytecode.push(Op { - opcode: Either::Left(VirtualOp::LW( - current_arg_reg.clone(), - args_base_reg.clone(), - VirtualImmediate12 { - value: arg_word_offset as u16, - }, - )), - comment: format!("Get arg {}", name), - owning_span: None, - }); - } - } else if arg_word_offset * 8 > crate::asm_generation::compiler_constants::TWELVE_BITS { - let offs_reg = self.reg_seqr.next(); - self.number_to_reg(arg_word_offset * 8, &offs_reg, None); - self.bytecode.push(Op { - opcode: either::Either::Left(VirtualOp::ADD( - current_arg_reg.clone(), - args_base_reg.clone(), - offs_reg, - )), - comment: format!("Get offset or arg {}", name), - owning_span: None, - }); - } else { - self.bytecode.push(Op { - opcode: either::Either::Left(VirtualOp::ADDI( - current_arg_reg.clone(), - args_base_reg.clone(), - VirtualImmediate12 { - value: (arg_word_offset * 8) as u16, - }, - )), - comment: format!("Get address for arg {}", name), - owning_span: None, - }); - } - - arg_word_offset += arg_type_size_bytes / 8; - } } fn add_locals(&mut self, function: Function) { @@ -371,7 +386,7 @@ impl<'ir> AsmBuilder<'ir> { // It's possible (though undesirable) to have empty local data structures only. if stack_base != 0 { - if stack_base * 8 > crate::asm_generation::compiler_constants::TWENTY_FOUR_BITS { + if stack_base * 8 > compiler_constants::TWENTY_FOUR_BITS { todo!("Enormous stack usage for locals."); } let mut alloc_op = Op::unowned_stack_allocate_memory(VirtualImmediate24 { @@ -407,6 +422,20 @@ impl<'ir> AsmBuilder<'ir> { } fn compile_function(&mut self, function: Function) -> CompileResult<()> { + if function.has_selector(self.context) { + // Add a comment noting that this is a named contract method. + self.bytecode.push(Op::new_comment(format!( + "contract method: {}, selector: 0x{}", + function.get_name(self.context), + function + .get_selector(self.context) + .unwrap() + .into_iter() + .map(|b| format!("{b:02x}")) + .collect::() + ))); + } + // Compile instructions. self.add_locals(function); self.compile_fn_args(function); @@ -835,7 +864,7 @@ impl<'ir> AsmBuilder<'ir> { }); } else { // Value too big for a register, so we return the memory offset. - if elem_size > crate::asm_generation::compiler_constants::TWELVE_BITS { + if elem_size > compiler_constants::TWELVE_BITS { let size_data_id = self .data_section .insert_data_value(&Literal::U64(elem_size)); @@ -888,7 +917,7 @@ impl<'ir> AsmBuilder<'ir> { let instr_reg = self.reg_seqr.next(); if field_type.is_copy_type() { - if extract_offset > crate::asm_generation::compiler_constants::TWELVE_BITS { + if extract_offset > compiler_constants::TWELVE_BITS { let offset_reg = self.reg_seqr.next(); self.number_to_reg( extract_offset, @@ -942,7 +971,7 @@ impl<'ir> AsmBuilder<'ir> { } } else { // Value too big for a register, so we return the memory offset. - if extract_offset * 8 > crate::asm_generation::compiler_constants::TWELVE_BITS { + if extract_offset * 8 > compiler_constants::TWELVE_BITS { let offset_reg = self.reg_seqr.next(); self.number_to_reg( extract_offset * 8, @@ -996,7 +1025,7 @@ impl<'ir> AsmBuilder<'ir> { let offset_in_bytes = word_offs * 8 + ptr_ty_size_in_bytes * offset; let instr_reg = self.reg_seqr.next(); - if offset_in_bytes > crate::asm_generation::compiler_constants::TWELVE_BITS { + if offset_in_bytes > compiler_constants::TWELVE_BITS { self.number_to_reg( offset_in_bytes, &instr_reg, @@ -1069,7 +1098,7 @@ impl<'ir> AsmBuilder<'ir> { }); } else { // Element size is larger than 8; we switch to bytewise offsets and sizes and use MCP. - if elem_size > crate::asm_generation::compiler_constants::TWELVE_BITS { + if elem_size > compiler_constants::TWELVE_BITS { todo!("array element size bigger than 4k") } else { let elem_index_offs_reg = self.reg_seqr.next(); @@ -1135,7 +1164,7 @@ impl<'ir> AsmBuilder<'ir> { .collect::>() .join(","); if value.get_type(self.context).unwrap().is_copy_type() { - if insert_offs > crate::asm_generation::compiler_constants::TWELVE_BITS { + if insert_offs > compiler_constants::TWELVE_BITS { let insert_offs_reg = self.reg_seqr.next(); self.number_to_reg( insert_offs, @@ -1175,7 +1204,7 @@ impl<'ir> AsmBuilder<'ir> { } } else { let offs_reg = self.reg_seqr.next(); - if insert_offs * 8 > crate::asm_generation::compiler_constants::TWELVE_BITS { + if insert_offs * 8 > compiler_constants::TWELVE_BITS { self.number_to_reg(insert_offs * 8, &offs_reg, instr_val.get_span(self.context)); } else { self.bytecode.push(Op { @@ -1190,7 +1219,7 @@ impl<'ir> AsmBuilder<'ir> { owning_span: instr_val.get_span(self.context), }); } - if value_size > crate::asm_generation::compiler_constants::TWELVE_BITS { + if value_size > compiler_constants::TWELVE_BITS { let size_reg = self.reg_seqr.next(); self.number_to_reg(value_size, &size_reg, instr_val.get_span(self.context)); self.bytecode.push(Op { @@ -1244,7 +1273,7 @@ impl<'ir> AsmBuilder<'ir> { // XXX Need to check for zero sized types? if load_size_in_words == 1 { // Value can fit in a register, so we load the value. - if word_offs > crate::asm_generation::compiler_constants::TWELVE_BITS { + if word_offs > compiler_constants::TWELVE_BITS { let offs_reg = self.reg_seqr.next(); self.bytecode.push(Op { opcode: Either::Left(VirtualOp::ADD( @@ -1281,7 +1310,7 @@ impl<'ir> AsmBuilder<'ir> { // Value too big for a register, so we return the memory offset. This is // what LW to the data section does, via LWDataId. let word_offs = word_offs * 8; - if word_offs > crate::asm_generation::compiler_constants::TWELVE_BITS { + if word_offs > compiler_constants::TWELVE_BITS { let offs_reg = self.reg_seqr.next(); self.number_to_reg( word_offs, @@ -1399,7 +1428,7 @@ impl<'ir> AsmBuilder<'ir> { span: Option, ) -> VirtualRegister { let offset_reg = self.reg_seqr.next(); - if offset_in_bytes > crate::asm_generation::compiler_constants::TWELVE_BITS { + if offset_in_bytes > compiler_constants::TWELVE_BITS { let offs_reg = self.reg_seqr.next(); self.number_to_reg(offset_in_bytes, &offs_reg, span.clone()); self.bytecode.push(Op { @@ -1628,7 +1657,7 @@ impl<'ir> AsmBuilder<'ir> { }); tmp_reg }; - if word_offs > crate::asm_generation::compiler_constants::TWELVE_BITS { + if word_offs > compiler_constants::TWELVE_BITS { let offs_reg = self.reg_seqr.next(); self.number_to_reg( word_offs, @@ -1672,9 +1701,7 @@ impl<'ir> AsmBuilder<'ir> { // Bigger than 1 word needs a MCPI. XXX Or MCP if it's huge. let dest_offs_reg = self.reg_seqr.next(); - if word_offs * 8 - > crate::asm_generation::compiler_constants::TWELVE_BITS - { + if word_offs * 8 > compiler_constants::TWELVE_BITS { self.number_to_reg( word_offs * 8, &dest_offs_reg, @@ -1703,9 +1730,7 @@ impl<'ir> AsmBuilder<'ir> { }); } - if store_size_in_words * 8 - > crate::asm_generation::compiler_constants::TWELVE_BITS - { + if store_size_in_words * 8 > compiler_constants::TWELVE_BITS { let size_reg = self.reg_seqr.next(); self.number_to_reg( store_size_in_words * 8, @@ -1778,9 +1803,7 @@ impl<'ir> AsmBuilder<'ir> { let total_size = size_bytes_round_up_to_word_alignment!( self.constant_size_in_bytes(constant) ); - if total_size - > crate::asm_generation::compiler_constants::TWENTY_FOUR_BITS - { + if total_size > compiler_constants::TWENTY_FOUR_BITS { todo!("Enormous stack usage for locals."); } @@ -1878,7 +1901,7 @@ impl<'ir> AsmBuilder<'ir> { } fn number_to_reg(&mut self, offset: u64, offset_reg: &VirtualRegister, span: Option) { - if offset > crate::asm_generation::compiler_constants::TWENTY_FOUR_BITS { + if offset > compiler_constants::TWENTY_FOUR_BITS { todo!("Absolutely giant arrays."); } @@ -1971,7 +1994,7 @@ impl<'ir> AsmBuilder<'ir> { // needs to use a MCP instruction. if matches!(lit, Literal::B256(_)) { let offs_reg = self.reg_seqr.next(); - if offs_in_words * 8 > crate::asm_generation::compiler_constants::TWELVE_BITS { + if offs_in_words * 8 > compiler_constants::TWELVE_BITS { self.number_to_reg(offs_in_words * 8, &offs_reg, span.clone()); self.bytecode.push(Op { opcode: either::Either::Left(VirtualOp::ADD( @@ -2007,7 +2030,7 @@ impl<'ir> AsmBuilder<'ir> { 4 // 32 bytes is 4 words. } else { - if offs_in_words > crate::asm_generation::compiler_constants::TWELVE_BITS { + if offs_in_words > compiler_constants::TWELVE_BITS { let offs_reg = self.reg_seqr.next(); self.number_to_reg(offs_in_words, &offs_reg, span.clone()); self.bytecode.push(Op { diff --git a/sway-core/src/optimize.rs b/sway-core/src/optimize.rs index d9542a28dc3..bbd2db945ff 100644 --- a/sway-core/src/optimize.rs +++ b/sway-core/src/optimize.rs @@ -822,46 +822,103 @@ impl FnCompiler { .map(|(_, expr)| self.compile_expression(context, expr)) .collect::, CompileError>>()?; - // New struct type to hold the user arguments - let field_types = compiled_args - .iter() - .map(|val| val.get_type(context).unwrap()) - .collect::>(); - let user_args_struct_aggregate = Aggregate::new_struct(context, field_types); + let user_args_val = match compiled_args.len() { + 0 => Constant::get_unit(context, None), + 1 => { + // The single arg doesn't need to be put into a struct. + let arg0 = compiled_args[0]; + + // We're still undecided as to whether this should be decided by type or size. + // Going with type for now. + let arg0_type = arg0.get_type(context).unwrap(); + if arg0_type.is_copy_type() { + arg0 + } else { + // Copy this value to a new location. This is quite inefficient but we need to + // pass by reference rather than by value. Optimisation passes can remove all + // the unnecessary copying eventually, though it feels like we're jumping + // through a bunch of hoops here (employing the single arg optimisation) for + // minimal returns. + let by_reference_arg_name = self + .lexical_map + .insert(format!("{}{}", "arg_for_", ast_name)); + let by_reference_arg = self + .function + .new_local_ptr(context, by_reference_arg_name, arg0_type, false, None) + .map_err(|ir_error| { + CompileError::InternalOwned(ir_error.to_string(), Span::empty()) + })?; + + let arg0_ptr = self.current_block.ins(context).get_ptr( + by_reference_arg, + arg0_type, + 0, + None, + ); + self.current_block.ins(context).store(arg0_ptr, arg0, None); + + // NOTE: Here we're fetching the original stack pointer, cast to u64. + self.current_block.ins(context).get_ptr( + by_reference_arg, + Type::Uint(64), + 0, + span_md_idx, + ) + } + } + _ => { + // New struct type to hold the user arguments bundled together. + let field_types = compiled_args + .iter() + .map(|val| val.get_type(context).unwrap()) + .collect::>(); + let user_args_struct_aggregate = Aggregate::new_struct(context, field_types); + + // New local pointer for the struct to hold all user arguments + let user_args_struct_local_name = self + .lexical_map + .insert(format!("{}{}", "args_struct_for_", ast_name)); + let user_args_struct_ptr = self + .function + .new_local_ptr( + context, + user_args_struct_local_name, + Type::Struct(user_args_struct_aggregate), + true, + None, + ) + .map_err(|ir_error| { + CompileError::InternalOwned(ir_error.to_string(), Span::empty()) + })?; - // New local pointer for the struct to hold all user arguments - let alias_user_args_struct_local_name = self - .lexical_map - .insert(format!("{}{}", "args_struct_for_", ast_name)); - let user_args_struct_ptr = self - .function - .new_local_ptr( - context, - alias_user_args_struct_local_name, - Type::Struct(user_args_struct_aggregate), - true, - None, - ) - .map_err(|ir_error| CompileError::InternalOwned(ir_error.to_string(), Span::empty()))?; + // Initialise each of the fields in the user args struct. + compiled_args.into_iter().enumerate().fold( + self.current_block.ins(context).get_ptr( + user_args_struct_ptr, + Type::Struct(user_args_struct_aggregate), + 0, + span_md_idx, + ), + |user_args_struct_ptr_val, (insert_idx, insert_val)| { + self.current_block.ins(context).insert_value( + user_args_struct_ptr_val, + user_args_struct_aggregate, + insert_val, + vec![insert_idx as u64], + span_md_idx, + ) + }, + ); - // Initialise each of the fields in the user args struct. - compiled_args.into_iter().enumerate().fold( - self.current_block.ins(context).get_ptr( - user_args_struct_ptr, - Type::Struct(user_args_struct_aggregate), - 0, - span_md_idx, - ), - |user_args_struct_ptr_val, (insert_idx, insert_val)| { - self.current_block.ins(context).insert_value( - user_args_struct_ptr_val, - user_args_struct_aggregate, - insert_val, - vec![insert_idx as u64], + // NOTE: Here we're fetching the original stack pointer, cast to u64. + self.current_block.ins(context).get_ptr( + user_args_struct_ptr, + Type::Uint(64), + 0, span_md_idx, ) - }, - ); + } + }; // Now handle the contract address and the selector. The contract address is just // as B256 while the selector is a [u8; 4] which we have to convert to a U64. @@ -900,19 +957,12 @@ impl FnCompiler { span_md_idx, ); - // Insert the pointer to the user args struct. - // - // NOTE: Here we're inserting the original stack pointer, cast to u64. - let user_args_struct_addr_val = self.current_block.ins(context).get_ptr( - user_args_struct_ptr, - Type::Uint(64), - 0, - span_md_idx, - ); + // Insert the user args value. + ra_struct_val = self.current_block.ins(context).insert_value( ra_struct_val, ra_struct_aggregate, - user_args_struct_addr_val, + user_args_val, vec![2], span_md_idx, ); diff --git a/sway-core/tests/ir_to_asm/nested_single_word_struct.asm b/sway-core/tests/ir_to_asm/nested_single_word_struct.asm index eb82731d6d3..bbe8b022469 100644 --- a/sway-core/tests/ir_to_asm/nested_single_word_struct.asm +++ b/sway-core/tests/ir_to_asm/nested_single_word_struct.asm @@ -11,10 +11,8 @@ eq $r0 $r1 $r0 ; function selector comparison jnei $zero $r0 i11 ; jump to selected function rvrt $zero ; revert if no selectors matched lw $r0 $fp i74 ; Base register for method parameter -addi $r0 $r0 i0 ; Get address for arg input1 addi $r0 $r0 i0 ; extract address lw $r0 $r0 i0 ; extract_value @ 0 ret $r0 -noop ; word-alignment of data section .data: data_0 .u32 0x495d4a23 diff --git a/sway-core/tests/ir_to_asm/simple_contract.asm b/sway-core/tests/ir_to_asm/simple_contract.asm index 39b832186be..6403a33b81b 100644 --- a/sway-core/tests/ir_to_asm/simple_contract.asm +++ b/sway-core/tests/ir_to_asm/simple_contract.asm @@ -5,22 +5,20 @@ DATA_SECTION_OFFSET[0..32] DATA_SECTION_OFFSET[32..64] lw $ds $is 1 add $$ds $$ds $is -lw $r1 $fp i73 ; load input function selector -lw $r0 data_2 ; load fn selector for comparison -eq $r0 $r1 $r0 ; function selector comparison -jnei $zero $r0 i17 ; jump to selected function -lw $r0 data_3 ; load fn selector for comparison -eq $r0 $r1 $r0 ; function selector comparison -jnei $zero $r0 i20 ; jump to selected function -lw $r0 data_4 ; load fn selector for comparison -eq $r0 $r1 $r0 ; function selector comparison -jnei $zero $r0 i24 ; jump to selected function +lw $r0 $fp i73 ; load input function selector +lw $r1 data_2 ; load fn selector for comparison +eq $r1 $r0 $r1 ; function selector comparison +jnei $zero $r1 i17 ; jump to selected function +lw $r1 data_3 ; load fn selector for comparison +eq $r1 $r0 $r1 ; function selector comparison +jnei $zero $r1 i19 ; jump to selected function +lw $r1 data_4 ; load fn selector for comparison +eq $r0 $r0 $r1 ; function selector comparison +jnei $zero $r0 i22 ; jump to selected function rvrt $zero ; revert if no selectors matched lw $r0 $fp i74 ; Base register for method parameter -lw $r0 $r0 i0 ; Get arg val ret $r0 -lw $r0 $fp i74 ; Base register for method parameter -addi $r1 $r0 i0 ; Get address for arg val +lw $r1 $fp i74 ; Base register for method parameter lw $r0 data_0 ; loading size for RETD retd $r1 $r0 lw $r1 $fp i74 ; Base register for method parameter diff --git a/sway-core/tests/sway_to_ir/simple_contract_call.ir b/sway-core/tests/sway_to_ir/simple_contract_call.ir index cc36a0fb71a..4a03a51a625 100644 --- a/sway-core/tests/sway_to_ir/simple_contract_call.ir +++ b/sway-core/tests/sway_to_ir/simple_contract_call.ir @@ -1,78 +1,74 @@ script { fn main() -> u64 { local ptr u64 a - local mut ptr { b256 } args_struct_for_get_b256 + local ptr b256 arg_for_get_b256 local mut ptr { u64, b256 } args_struct_for_get_s - local mut ptr { u64 } args_struct_for_get_u64 local ptr b256 b local ptr { u64, b256 } s entry: - v0 = get_ptr mut ptr { u64 } args_struct_for_get_u64, ptr { u64 }, 0, !1 - v1 = const u64 1111, !2 - v2 = insert_value v0, { u64 }, v1, 0, !1 - v3 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !1 - v4 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !3 - v5 = insert_value v3, { b256, u64, u64 }, v4, 0, !1 - v6 = const u64 2559618804, !1 - v7 = insert_value v5, { b256, u64, u64 }, v6, 1, !1 - v8 = get_ptr mut ptr { u64 } args_struct_for_get_u64, ptr u64, 0, !1 - v9 = insert_value v7, { b256, u64, u64 }, v8, 2, !1 - v10 = const u64 0, !4 - v11 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !5 - v12 = const u64 10000, !6 - v13 = contract_call u64 get_u64 v9, v10, v11, v12, !1 - v14 = get_ptr ptr u64 a, ptr u64, 0, !7 - store v13, ptr v14, !7 - v15 = get_ptr mut ptr { b256 } args_struct_for_get_b256, ptr { b256 }, 0, !8 - v16 = const b256 0x3333333333333333333333333333333333333333333333333333333333333333, !9 - v17 = insert_value v15, { b256 }, v16, 0, !8 - v18 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !8 - v19 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !10 - v20 = insert_value v18, { b256, u64, u64 }, v19, 0, !8 - v21 = const u64 1108491158, !8 - v22 = insert_value v20, { b256, u64, u64 }, v21, 1, !8 - v23 = get_ptr mut ptr { b256 } args_struct_for_get_b256, ptr u64, 0, !8 - v24 = insert_value v22, { b256, u64, u64 }, v23, 2, !8 - v25 = const u64 0, !11 - v26 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !12 - v27 = const u64 20000, !13 - v28 = contract_call b256 get_b256 v24, v25, v26, v27, !8 - v29 = get_ptr ptr b256 b, ptr b256, 0, !14 - store v28, ptr v29, !14 - v30 = get_ptr mut ptr { u64, b256 } args_struct_for_get_s, ptr { u64, b256 }, 0, !15 - v31 = const u64 5555, !16 - v32 = insert_value v30, { u64, b256 }, v31, 0, !15 - v33 = const b256 0x5555555555555555555555555555555555555555555555555555555555555555, !17 - v34 = insert_value v32, { u64, b256 }, v33, 1, !15 - v35 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !15 - v36 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !18 - v37 = insert_value v35, { b256, u64, u64 }, v36, 0, !15 - v38 = const u64 4234334249, !15 - v39 = insert_value v37, { b256, u64, u64 }, v38, 1, !15 - v40 = get_ptr mut ptr { u64, b256 } args_struct_for_get_s, ptr u64, 0, !15 - v41 = insert_value v39, { b256, u64, u64 }, v40, 2, !15 - v42 = read_register cgas, !15 - v43 = const u64 0, !19 - v44 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !20 - v45 = contract_call { u64, b256 } get_s v41, v43, v44, v42, !15 - v46 = get_ptr ptr { u64, b256 } s, ptr { u64, b256 }, 0, !21 - store v45, ptr v46, !21 - v47 = const u64 0, !22 - ret u64 v47 + v0 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !1 + v1 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !2 + v2 = insert_value v0, { b256, u64, u64 }, v1, 0, !1 + v3 = const u64 2559618804, !1 + v4 = insert_value v2, { b256, u64, u64 }, v3, 1, !1 + v5 = const u64 1111, !3 + v6 = insert_value v4, { b256, u64, u64 }, v5, 2, !1 + v7 = const u64 0, !4 + v8 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !5 + v9 = const u64 10000, !6 + v10 = contract_call u64 get_u64 v6, v7, v8, v9, !1 + v11 = get_ptr ptr u64 a, ptr u64, 0, !7 + store v10, ptr v11, !7 + v12 = get_ptr ptr b256 arg_for_get_b256, ptr b256, 0 + v13 = const b256 0x3333333333333333333333333333333333333333333333333333333333333333, !8 + store v13, ptr v12 + v14 = get_ptr ptr b256 arg_for_get_b256, ptr u64, 0, !9 + v15 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !9 + v16 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !10 + v17 = insert_value v15, { b256, u64, u64 }, v16, 0, !9 + v18 = const u64 1108491158, !9 + v19 = insert_value v17, { b256, u64, u64 }, v18, 1, !9 + v20 = insert_value v19, { b256, u64, u64 }, v14, 2, !9 + v21 = const u64 0, !11 + v22 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !12 + v23 = const u64 20000, !13 + v24 = contract_call b256 get_b256 v20, v21, v22, v23, !9 + v25 = get_ptr ptr b256 b, ptr b256, 0, !14 + store v24, ptr v25, !14 + v26 = get_ptr mut ptr { u64, b256 } args_struct_for_get_s, ptr { u64, b256 }, 0, !15 + v27 = const u64 5555, !16 + v28 = insert_value v26, { u64, b256 }, v27, 0, !15 + v29 = const b256 0x5555555555555555555555555555555555555555555555555555555555555555, !17 + v30 = insert_value v28, { u64, b256 }, v29, 1, !15 + v31 = get_ptr mut ptr { u64, b256 } args_struct_for_get_s, ptr u64, 0, !15 + v32 = const { b256, u64, u64 } { b256 undef, u64 undef, u64 undef }, !15 + v33 = const b256 0x0c1c50c2bf5ba4bb351b4249a2f5e7d86556fcb4a6ae90465ff6c86126eeb3c0, !18 + v34 = insert_value v32, { b256, u64, u64 }, v33, 0, !15 + v35 = const u64 4234334249, !15 + v36 = insert_value v34, { b256, u64, u64 }, v35, 1, !15 + v37 = insert_value v36, { b256, u64, u64 }, v31, 2, !15 + v38 = read_register cgas, !15 + v39 = const u64 0, !19 + v40 = const b256 0x0000000000000000000000000000000000000000000000000000000000000000, !20 + v41 = contract_call { u64, b256 } get_s v37, v39, v40, v38, !15 + v42 = get_ptr ptr { u64, b256 } s, ptr { u64, b256 }, 0, !21 + store v41, ptr v42, !21 + v43 = const u64 0, !22 + ret u64 v43 } } !0 = filepath "/path/to/simple_contract_call.sw" !1 = span !0 301 458 -!2 = span !0 453 457 -!3 = span !0 0 66 +!2 = span !0 0 66 +!3 = span !0 453 457 !4 = span !0 333 334 !5 = span !0 354 420 !6 = span !0 435 440 !7 = span !0 293 459 -!8 = span !0 473 693 -!9 = span !0 626 692 +!8 = span !0 626 692 +!9 = span !0 473 693 !10 = span !0 0 66 !11 = span !0 506 507 !12 = span !0 527 593 diff --git a/sway-lib-std/tests/test_projects/context/mod.rs b/sway-lib-std/tests/test_projects/context/mod.rs index 5e1e8c641b9..56847ffad2c 100644 --- a/sway-lib-std/tests/test_projects/context/mod.rs +++ b/sway-lib-std/tests/test_projects/context/mod.rs @@ -66,14 +66,13 @@ async fn can_get_this_balance() { .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //caller_instance - // .call_receive_coins(send_amount, context_sway_id) - // .set_contracts(&[context_id]) - // .tx_params(TxParameters::new(None, Some(1_000_000), None)) - // .call() - // .await - // .unwrap(); + caller_instance + .call_receive_coins(send_amount, context_sway_id) + .set_contracts(&[context_id]) + .tx_params(TxParameters::new(None, Some(1_000_000), None)) + .call() + .await + .unwrap(); let result = context_instance .get_this_balance(caller_sway_id) @@ -81,8 +80,7 @@ async fn can_get_this_balance() { .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //assert_eq!(result.value, send_amount); + assert_eq!(result.value, send_amount); } #[tokio::test] @@ -106,8 +104,7 @@ async fn can_get_balance_of_contract() { .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //assert_eq!(result.value, send_amount); + assert_eq!(result.value, send_amount); } #[tokio::test] @@ -151,16 +148,15 @@ async fn can_get_msg_id() { .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //let result = caller_instance - // .call_get_asset_id_with_coins(send_amount, context_sway_id) - // .set_contracts(&[caller_id, context_id]) - // .tx_params(TxParameters::new(None, Some(1_000_000), None)) - // .call() - // .await - // .unwrap(); - // - //assert_eq!(result.value, caller_sway_id); + let result = caller_instance + .call_get_asset_id_with_coins(send_amount, context_sway_id) + .set_contracts(&[caller_id, context_id]) + .tx_params(TxParameters::new(None, Some(1_000_000), None)) + .call() + .await + .unwrap(); + + assert_eq!(result.value, caller_sway_id); } #[tokio::test] diff --git a/sway-lib-std/tests/test_projects/token_ops/mod.rs b/sway-lib-std/tests/test_projects/token_ops/mod.rs index fdb83463308..2d31bf1695a 100644 --- a/sway-lib-std/tests/test_projects/token_ops/mod.rs +++ b/sway-lib-std/tests/test_projects/token_ops/mod.rs @@ -34,8 +34,7 @@ async fn can_mint() { .call() .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //assert_eq!(balance_result.value, 11); + assert_eq!(balance_result.value, 11); } #[tokio::test] @@ -56,15 +55,14 @@ async fn can_burn() { assert_eq!(balance_result.value, 0); fuelcoin_instance.mint_coins(11).call().await.unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //fuelcoin_instance.burn_coins(7).call().await.unwrap(); - // - //balance_result = fuelcoin_instance - // .get_balance(target, asset_id) - // .call() - // .await - // .unwrap(); - //assert_eq!(balance_result.value, 4); + fuelcoin_instance.burn_coins(7).call().await.unwrap(); + + balance_result = fuelcoin_instance + .get_balance(target, asset_id) + .call() + .await + .unwrap(); + assert_eq!(balance_result.value, 4); } #[tokio::test] @@ -91,13 +89,12 @@ async fn can_force_transfer() { fuelcoin_instance.mint_coins(100).call().await.unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //balance_result = fuelcoin_instance - // .get_balance(asset_id.clone(), asset_id.clone()) - // .call() - // .await - // .unwrap(); - //assert_eq!(balance_result.value, 100); + balance_result = fuelcoin_instance + .get_balance(asset_id.clone(), asset_id.clone()) + .call() + .await + .unwrap(); + assert_eq!(balance_result.value, 100); // confirm initial balance on balance contract (recipient) balance_result = fuelcoin_instance @@ -110,13 +107,12 @@ async fn can_force_transfer() { let coins = 42u64; - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //fuelcoin_instance - // .force_transfer_coins(coins, asset_id.clone(), target.clone()) - // .set_contracts(&[fuelcoin_id, balance_id]) - // .call() - // .await - // .unwrap(); + fuelcoin_instance + .force_transfer_coins(coins, asset_id.clone(), target.clone()) + .set_contracts(&[fuelcoin_id, balance_id]) + .call() + .await + .unwrap(); // confirm remaining balance on fuelcoin contract balance_result = fuelcoin_instance @@ -124,8 +120,7 @@ async fn can_force_transfer() { .call() .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //assert_eq!(balance_result.value, 58); + assert_eq!(balance_result.value, 58); // confirm new balance on balance contract (recipient) balance_result = fuelcoin_instance @@ -134,8 +129,7 @@ async fn can_force_transfer() { .call() .await .unwrap(); - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //assert_eq!(balance_result.value, 42); + assert_eq!(balance_result.value, 42); } #[tokio::test] diff --git a/sway-lib-std/tests/test_projects/tx_fields/mod.rs b/sway-lib-std/tests/test_projects/tx_fields/mod.rs index 31f65d31def..4845947e465 100644 --- a/sway-lib-std/tests/test_projects/tx_fields/mod.rs +++ b/sway-lib-std/tests/test_projects/tx_fields/mod.rs @@ -198,36 +198,35 @@ async fn can_get_script_start_offset() { #[tokio::test] async fn can_get_tx_input_type() { - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //let (contract_instance, _, _) = get_contracts().await; - // - //// Contract input - //let input_type = 1; - //let result_ptr = contract_instance - // .get_tx_input_pointer(0) - // .call() - // .await - // .unwrap(); - //let result = contract_instance - // .get_tx_input_type(result_ptr.value) - // .call() - // .await - // .unwrap(); - //assert_eq!(result.value, input_type); - // - //// Coin input - //let input_type = 0; - //let result_ptr = contract_instance - // .get_tx_input_pointer(1) - // .call() - // .await - // .unwrap(); - //let result = contract_instance - // .get_tx_input_type(result_ptr.value) - // .call() - // .await - // .unwrap(); - //assert_eq!(result.value, input_type); + let (contract_instance, _, _) = get_contracts().await; + + // Contract input + let input_type = 1; + let result_ptr = contract_instance + .get_tx_input_pointer(0) + .call() + .await + .unwrap(); + let result = contract_instance + .get_tx_input_type(result_ptr.value) + .call() + .await + .unwrap(); + assert_eq!(result.value, input_type); + + // Coin input + let input_type = 0; + let result_ptr = contract_instance + .get_tx_input_pointer(1) + .call() + .await + .unwrap(); + let result = contract_instance + .get_tx_input_type(result_ptr.value) + .call() + .await + .unwrap(); + assert_eq!(result.value, input_type); } #[tokio::test] @@ -238,50 +237,48 @@ async fn can_get_tx_input_coin_owner() { let input_owner = txcontracttest_mod::Address { value: wallet.address().into(), }; - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //let result_ptr = contract_instance - // .get_tx_input_pointer(1) - // .call() - // .await - // .unwrap(); - //let result = contract_instance - // .get_tx_input_coin_owner(result_ptr.value) - // .call() - // .await - // .unwrap(); - //assert_eq!(result.value, input_owner); + let result_ptr = contract_instance + .get_tx_input_pointer(1) + .call() + .await + .unwrap(); + let result = contract_instance + .get_tx_input_coin_owner(result_ptr.value) + .call() + .await + .unwrap(); + assert_eq!(result.value, input_owner); } #[tokio::test] async fn can_get_tx_output_type() { - // TEMPORARILY DISABLED until https://github.com/FuelLabs/fuels-rs/issues/201 is resolved. - //let (contract_instance, _, _) = get_contracts().await; - // - //// Contract output - //let output_type = 1; - //let result_ptr = contract_instance - // .get_tx_output_pointer(1) - // .call() - // .await - // .unwrap(); - //let result = contract_instance - // .get_tx_output_type(result_ptr.value) - // .call() - // .await - // .unwrap(); - //assert_eq!(result.value, output_type); - // - //// Change output - //let output_type = 3; - //let result_ptr = contract_instance - // .get_tx_output_pointer(0) - // .call() - // .await - // .unwrap(); - //let result = contract_instance - // .get_tx_output_type(result_ptr.value) - // .call() - // .await - // .unwrap(); - //assert_eq!(result.value, output_type); + let (contract_instance, _, _) = get_contracts().await; + + // Contract output + let output_type = 1; + let result_ptr = contract_instance + .get_tx_output_pointer(1) + .call() + .await + .unwrap(); + let result = contract_instance + .get_tx_output_type(result_ptr.value) + .call() + .await + .unwrap(); + assert_eq!(result.value, output_type); + + // Change output + let output_type = 3; + let result_ptr = contract_instance + .get_tx_output_pointer(0) + .call() + .await + .unwrap(); + let result = contract_instance + .get_tx_output_type(result_ptr.value) + .call() + .await + .unwrap(); + assert_eq!(result.value, output_type); } 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 1a949e820d8..20704ecc8a7 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 @@ -3,7 +3,7 @@ use basic_storage_abi::StoreU64; use std::assert::assert; fn main() -> u64 { - let addr = abi(StoreU64, 0xf4e12fcac2187e1ac5599476c531560cb6f7aa39bd05d20312a4bd237900b4e4); + let addr = abi(StoreU64, 0x068536389987d7308cd696da40a2f706d2d7ae0889b1df96ca280639289b92c8); let key = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; let value = 4242; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw index c3110754cab..82a0edce359 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw @@ -4,7 +4,7 @@ use increment_abi::Incrementor; use std::assert::assert; fn main() -> bool { - let abi = abi(Incrementor, 0x386b732f205fd34c97c5914ddd0f7356c5b923229b1cb39e84acd762d62e69c6); + let abi = abi(Incrementor, 0xc07e767d214aa07d772d589fa0da89a38b93da6fd8f329877c7423cbdefd815d); abi.initialize(0); // comment this line out to just increment without initializing abi.increment(5); abi.increment(5); 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 6ee54f6b7d1..84c1dcc90fe 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 @@ -5,7 +5,7 @@ use context_testing_abi::*; fn main() -> bool { let gas: u64 = 1000; let amount: u64 = 11; - let other_contract_id = ~ContractId::from(0x3915399a401876c5145f3d9ed931ca8cc8c98cb9febda445d4fe2ef893151589); + let other_contract_id = ~ContractId::from(0xea6bc06273b6d7d27de596827cfa73cd31f4d3ac4fd6c8c3b21b59223eb4d287); let native_asset_id = ~ContractId::from(NATIVE_ASSET_ID); let test_contract = abi(ContextTesting, other_contract_id.into()); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw index 23b16135769..a576c3f3449 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw @@ -17,7 +17,7 @@ fn main() -> bool { let default_gas = 1_000_000_000_000; // the deployed fuel_coin Contract_Id: - let fuelcoin_id = ~ContractId::from(0x9ebec04226fdd4c962dc0f299da0555d180e3d60e39610a49613512a9846316a); + let fuelcoin_id = ~ContractId::from(0x06e336901af870e852cc20d49e7d52a700ed2661960c698af8d4a4fe9c9c1bab); // contract ID for sway/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/balance_test_contract/ let balance_test_id = ~ContractId::from(0xb4c0d8c9056c0cde34b66e7e4e3f361d927d26ffdc16c2645dd0e2699bc96cad);