Skip to content

Commit

Permalink
Merge branch 'master' into bitzoic-6106
Browse files Browse the repository at this point in the history
  • Loading branch information
bitzoic authored Jun 17, 2024
2 parents f39ae58 + 7b56ec7 commit d0be688
Show file tree
Hide file tree
Showing 19 changed files with 145 additions and 67 deletions.
6 changes: 5 additions & 1 deletion sway-core/src/asm_generation/from_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use super::{
MidenVMAsmBuilder,
};
use crate::{asm_generation::ProgramKind, BuildConfig, BuildTarget};

use crate::asm_lang::VirtualImmediate18;

use sway_error::handler::{ErrorEmitted, Handler};
use sway_ir::{Context, Kind, Module};

Expand Down Expand Up @@ -105,8 +108,9 @@ fn compile(

#[derive(Clone, Debug)]
pub(super) enum Storage {
Data(DataId), // Const storage in the data section.
Data(DataId), // Const storage in the data section.
Stack(u64), // Storage in the runtime stack starting at an absolute word offset. Essentially a global.
Const(VirtualImmediate18), // An immediate value that can be moved to a register using MOVI.
}

pub enum StateAccessType {
Expand Down
32 changes: 31 additions & 1 deletion sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,17 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {

Ok(())
}
Some(Storage::Const(c)) => {
let instr_reg = self.reg_seqr.next();
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MOVI(instr_reg.clone(), c.clone())),
comment: "get local constant".into(),
owning_span,
});
self.reg_map.insert(*instr_val, instr_reg);

Ok(())
}
_ => Err(CompileError::Internal(
"Malformed storage for local var found.",
self.md_mgr
Expand Down Expand Up @@ -2056,7 +2067,26 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
.or_else(|| {
value.get_constant(self.context).map(|constant| {
let span = self.md_mgr.val_to_span(self.context, *value);
self.initialise_constant(constant, None, span).0
match constant.value {
// If it's a small enough constant, just initialize using an IMM value.
// (exceptions for zero and one as they have special registers).
ConstantValue::Uint(c)
if c <= compiler_constants::EIGHTEEN_BITS && !(c == 0 || c == 1) =>
{
let imm = VirtualImmediate18::new_unchecked(
c,
"Cannot happen, we just checked",
);
let reg = self.reg_seqr.next();
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MOVI(reg.clone(), imm)),
comment: "initializer constant into register".into(),
owning_span: None,
});
reg
}
_ => self.initialise_constant(constant, None, span).0,
}
})
})
.ok_or_else(|| {
Expand Down
128 changes: 84 additions & 44 deletions sway-core/src/asm_generation/fuel/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use sway_error::{
};
use sway_types::{Ident, Span};

use super::{compiler_constants::NUM_ARG_REGISTERS, data_section::DataId};
use super::compiler_constants::NUM_ARG_REGISTERS;

/// A summary of the adopted calling convention:
///
Expand Down Expand Up @@ -802,44 +802,69 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
// Otherwise they go in runtime allocated space, either a register or on the stack.
//
// Stack offsets are in words to both enforce alignment and simplify use with LW/SW.
let (stack_base_words, init_mut_vars) =
function.locals_iter(self.context).fold(
(0, Vec::new()),
|(stack_base_words, mut init_mut_vars), (_name, ptr)| {
if let (false, Some(constant)) = (
ptr.is_mutable(self.context),
ptr.get_initializer(self.context),
) {
let data_id = self.data_section.insert_data_value(Entry::from_constant(
self.context,
constant,
None,
None,
));
self.ptr_map.insert(*ptr, Storage::Data(data_id));
(stack_base_words, init_mut_vars)
} else {
self.ptr_map.insert(*ptr, Storage::Stack(stack_base_words));

let ptr_ty = ptr.get_inner_type(self.context);
let var_size = ptr_ty.size(self.context);

if let Some(constant) = ptr.get_initializer(self.context) {
let (stack_base_words, init_mut_vars) = function.locals_iter(self.context).fold(
(0, Vec::new()),
|(stack_base_words, mut init_mut_vars), (_name, ptr)| {
if let (false, Some(constant)) = (
ptr.is_mutable(self.context),
ptr.get_initializer(self.context),
) {
match constant.value {
ConstantValue::Uint(c) if c <= compiler_constants::EIGHTEEN_BITS => {
self.ptr_map.insert(
*ptr,
Storage::Const(VirtualImmediate18::new_unchecked(
c,
"Cannot happen, we just checked",
)),
);
}
_ => {
let data_id = self.data_section.insert_data_value(
Entry::from_constant(self.context, constant, None, None),
);

init_mut_vars.push(InitMutVars {
stack_base_words,
var_size: var_size.clone(),
data_id,
});
self.ptr_map.insert(*ptr, Storage::Data(data_id));
}
}
(stack_base_words, init_mut_vars)
} else {
self.ptr_map.insert(*ptr, Storage::Stack(stack_base_words));

let ptr_ty = ptr.get_inner_type(self.context);
let var_size = ptr_ty.size(self.context);

if let Some(constant) = ptr.get_initializer(self.context) {
match constant.value {
ConstantValue::Uint(c) if c <= compiler_constants::EIGHTEEN_BITS => {
let imm = VirtualImmediate18::new_unchecked(
c,
"Cannot happen, we just checked",
);
dbg!();
init_mut_vars.push(InitMutVars {
stack_base_words,
var_size: var_size.clone(),
data: Storage::Const(imm),
});
}
_ => {
let data_id = self.data_section.insert_data_value(
Entry::from_constant(self.context, constant, None, None),
);

init_mut_vars.push(InitMutVars {
stack_base_words,
var_size: var_size.clone(),
data: Storage::Data(data_id),
});
}
}

(stack_base_words + var_size.in_words(), init_mut_vars)
}
},
);

(stack_base_words + var_size.in_words(), init_mut_vars)
}
},
);

// Reserve space on the stack (in bytes) for all our locals which require it. Firstly save
// the current $sp.
Expand Down Expand Up @@ -887,22 +912,37 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
for InitMutVars {
stack_base_words,
var_size,
data_id,
data,
} in init_mut_vars
{
if var_size.in_bytes() == 0 {
// Don't bother initializing zero-sized types.
continue;
}
// Load our initialiser from the data section.
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::LoadDataId(
VirtualRegister::Constant(ConstantRegister::Scratch),
data_id,
)),
comment: "load initializer from data section".to_owned(),
owning_span: None,
});
match data {
Storage::Data(data_id) => {
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::LoadDataId(
VirtualRegister::Constant(ConstantRegister::Scratch),
data_id,
)),
comment: "load initializer from data section".to_owned(),
owning_span: None,
});
}
Storage::Stack(_) => panic!("Initializer cannot be on the stack"),
Storage::Const(c) => {
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MOVI(
VirtualRegister::Constant(ConstantRegister::Scratch),
c.clone(),
)),
comment: "load initializer from register".into(),
owning_span: None,
});
}
}

// Get the stack offset in bytes rather than words.
let var_stack_off_bytes = stack_base_words * 8;
Expand Down Expand Up @@ -1020,5 +1060,5 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
struct InitMutVars {
stack_base_words: u64,
var_size: TypeSize,
data_id: DataId,
data: Storage,
}
5 changes: 3 additions & 2 deletions sway-core/src/asm_generation/fuel/optimizations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ impl AbstractInstructionSet {
c2: u64,
) {
match reg_contents.get(opd1) {
Some(RegContents::Constant(c1)) => {
Some(RegContents::Constant(c1)) if c1.checked_add(c2).is_some() => {
reg_contents.insert(dest.clone(), RegContents::Constant(c1 + c2));
record_new_def(latest_version, dest);
}
Some(RegContents::BaseOffset(base_reg, offset))
if get_def_version(latest_version, &base_reg.reg) == base_reg.ver =>
if get_def_version(latest_version, &base_reg.reg) == base_reg.ver
&& offset.checked_add(c2).is_some() =>
{
reg_contents.insert(
dest.clone(),
Expand Down
8 changes: 6 additions & 2 deletions sway-core/src/asm_lang/allocated_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,8 +745,12 @@ fn realize_load(
Span::new(" ".into(), 0, 0, None).unwrap(),
);
let offset = match imm {
Ok(value) => value,
Err(_) => panic!("Unable to offset into the data section more than 2^12 bits. Unsupported data section length.")
Ok(value) => value,
Err(_) => panic!(
"Unable to offset into the data section more than 2^12 bits. \
Unsupported data section length: {} words.",
offset_words
),
};

if !has_copy_type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::hash::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x14ed3cd06c2947248f69d54bfa681fe40d26267be84df7e19e253622b7921bbe;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x0f37bc63915b0217c6eb60b40a8d1848a395c263946cd660028757da4cc65135;
const CONTRACT_ID = 0xad5e3937508bd711011c85aaa1e20a7a1051c723174d30139c87978cd24913cd;

fn main() -> u64 {
let addr = abi(TestContract, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use test_fuel_coin_abi::*;
#[cfg(experimental_new_encoding = false)]
const FUEL_COIN_CONTRACT_ID = 0x4c7b43ef5a097d7cfb87600a4234e33311eeeeb8081e5ea7bb6d9a1f8555c9c4;
#[cfg(experimental_new_encoding = true)]
const FUEL_COIN_CONTRACT_ID = 0xe6f335b3e362f429cb0f4f4fd960ba42eab79ffdf0678d95c8fc747f12a29b41;
const FUEL_COIN_CONTRACT_ID = 0x3f3177f1f94e6eba832d5b79d0468e1a78eda5bdcf53f4740b65c7a09e5f6ff0;

#[cfg(experimental_new_encoding = false)]
const BALANCE_CONTRACT_ID = 0x3120fdd1b99c0c611308aff43a99746cc2c661c69c22aa56331d5f3ce5534ee9;
#[cfg(experimental_new_encoding = true)]
const BALANCE_CONTRACT_ID = 0xfa37c9d0472b9da4e12d1d28531631c1ba74c7f20bd622f60178e9a698d78c5c;
const BALANCE_CONTRACT_ID = 0x9dac51d44d9d053eb2bf1f68bfdbd889ddfdcb470727cda2e1a132f5660f63a6;

fn main() -> bool {
let default_gas = 1_000_000_000_000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use balance_test_abi::BalanceTest;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x3120fdd1b99c0c611308aff43a99746cc2c661c69c22aa56331d5f3ce5534ee9;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0xfa37c9d0472b9da4e12d1d28531631c1ba74c7f20bd622f60178e9a698d78c5c;
const CONTRACT_ID = 0x9dac51d44d9d053eb2bf1f68bfdbd889ddfdcb470727cda2e1a132f5660f63a6;

fn main() -> bool {
let balance_test_contract = abi(BalanceTest, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use abi_with_tuples::{MyContract, Location, Person};
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0xb351aff8258ce46d16a71be666dd2b0b09d72243105c51f4423765824e59cac9;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x2d4418537296e2545fedc7ca9040040be7b0c99e27dc051aefa4b7567f14d090;
const CONTRACT_ID = 0xbc8374cc7bbfa50d3c1f1b6b3a000176272ae875402e6ee55a7ad3bcc3bdde9d;

fn main() -> bool {
let the_abi = abi(MyContract, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use basic_storage_abi::{BasicStorage, Quad};
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x044ab65bcabeebb73c88d8625ce392224c613cb1dae21ebedaa36bf6db1f5f4e;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0xb9c54e6c356e7f3ef52dbf6157d07d46311e09a6b9d0c6020f63f767ed20b129;
const CONTRACT_ID = 0x26729c48ebff0ab7f4972208a56281396b6385ee0993faea7b78f96471c9b083;

fn main() -> u64 {
let addr = abi(BasicStorage, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x0cbeb6efe3104b460be769bdc4ea101ebf16ccc16f2d7b667ec3e1c7f5ce35b5;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0xfc63115974ea86fce2df41ee655954feed547ce2defafdfb80b382a1104e644c;
const CONTRACT_ID = 0xd5615006ae0854832fa45a8dbbfe716fba427bc3021946fc80817ca62c153850;

fn main() {
let caller = abi(MyContract, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use dynamic_contract_call::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x080ca4b6a4661d3cc2138f733cbe54095ce8b910eee73d913c1f43ecad6bf0d2;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x8cfa01a28a4d9542ecedc1f160c45e16b7b4b0d97580010b11aa8872588010eb;
const CONTRACT_ID = 0x45f1f78e4c108017591a3334e84c63ee7be0aca9e5a521ecf7c6fd801462e0f8;

fn main() -> bool {
let the_abi = abi(Incrementor, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use storage_enum_abi::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x0d2d9546e833c166b64a340f5694fa01ca6bb53c3ec681d6c1ade1b9c0a2bf46;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x5b224455ff94a4f40a0f690409bfb7cd1c1722ebe4961c309cecd0c874ba4292;
const CONTRACT_ID = 0x0bd1b4a22ec11c944291e457524c291711d7c88533b31414a8b6e2c884d18e5e;

fn main() -> u64 {
let caller = abi(StorageEnum, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use auth_testing_abi::AuthTesting;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0xc2eec20491b53aab7232cbd27c31d15417b4e9daf0b89c74cc242ef1295f681f;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x4a62e214817115ba2de1657321e2b67358aafb00e89c5233b54b5e89d38b5338;
const CONTRACT_ID = 0x886f83b58dd6af803814b3af3c7f4b2fcdc9b6e99577746996feba8e117fe760;

// should be false in the case of a script
fn main() -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use context_testing_abi::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0xc2ec2a4a1b20475700e6793c7f20ad8082294894242b17cf08b5fd7c0d3968ad;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x49aeefc85c1ccf65a3248fd83f2264962bb6fda776b1d297e6a41c9713cd6bd4;
const CONTRACT_ID = 0x554f1971d3f43aea4a4802bb0d2d11422a9a1bf33c6e347a6a1d188782a78840;

fn main() -> bool {
let gas: u64 = u64::max();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use nested_struct_args_abi::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x64390eb0cac08d41b6476ad57d711b88846ea35ac800d4fc3c95a551e4039432;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0xa2fcd56b7e4810217a4baf5d17111b3399fbad3e6c0a1271db1b7e938fc5020d;
const CONTRACT_ID = 0x26e66c5eeb71a2d0b8610b6f94ac59922d9b3405de2790bf863a63c46b1b5227;

fn main() -> bool {
let caller = abi(NestedStructArgs, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::hash::*;
#[cfg(experimental_new_encoding = false)]
const CONTRACT_ID = 0x88732a14508defea37a44d0b0ae9af5c776253215180a1c3288f8d504ebb84db;
#[cfg(experimental_new_encoding = true)]
const CONTRACT_ID = 0x257a60b6d43000783e2fff62eaccd9a4601484a44897f11b899cd12bbdde09d3;
const CONTRACT_ID = 0x5579e2e539784e50b4383c89adaceaae6a2ae4ee315862b982f76266971fa12b;

fn main() -> bool {
let caller = abi(StorageAccess, CONTRACT_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ fn test_foo() {

#[test(should_revert)]
fn test_fail() {
let contract_id = 0x641ff2f86dcb64636047b41d6feca5bb9cb61808c53f54718db323294b451c63;
let contract_id = 0x0e92e0e9e366124ded23d8c8a9f4dfdc4a966c665387d22b1c977a6a9c3b0653;
let caller = abi(MyContract, contract_id);
let result = caller.test_function {}();
assert(result == false)
}

#[test]
fn test_success() {
let contract_id = 0x641ff2f86dcb64636047b41d6feca5bb9cb61808c53f54718db323294b451c63;
let contract_id = 0x0e92e0e9e366124ded23d8c8a9f4dfdc4a966c665387d22b1c977a6a9c3b0653;
let caller = abi(MyContract, contract_id);
let result = caller.test_function {}();
assert(result == true)
Expand Down
Loading

0 comments on commit d0be688

Please sign in to comment.