implement msize opcode

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-03-26 12:03:28 +01:00
parent 69800ae1b3
commit 17832855e0
4 changed files with 88 additions and 6 deletions
+9
View File
@@ -0,0 +1,9 @@
contract MSize {
uint[] public data;
function mSize() public pure returns (uint size) {
assembly {
size := msize()
}
}
}
+39 -1
View File
@@ -1,14 +1,26 @@
pub mod mock_runtime;
/// Compile the blob of `contract_name` found in given `source_code`.
/// The `solc` optimizer will be enabled
pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec<u8> {
compile_blob_with_options(contract_name, source_code, true)
}
/// Compile the blob of `contract_name` found in given `source_code`.
pub fn compile_blob_with_options(
contract_name: &str,
source_code: &str,
solc_optimizer_enabled: bool,
) -> Vec<u8> {
let file_name = "contract.sol";
let contracts = revive_solidity::test_utils::build_solidity(
let contracts = revive_solidity::test_utils::build_solidity_with_options(
[(file_name.into(), source_code.into())].into(),
Default::default(),
None,
revive_solidity::SolcPipeline::Yul,
era_compiler_llvm_context::OptimizerSettings::cycles(),
solc_optimizer_enabled,
)
.expect("source should compile")
.contracts
@@ -149,4 +161,30 @@ mod tests {
let received = I256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected);
}
#[test]
fn msize() {
sol!(
#[derive(Debug, PartialEq, Eq)]
contract MSize {
function mSize() public pure returns (uint);
}
);
let code = crate::compile_blob_with_options(
"MSize",
include_str!("../contracts/MSize.sol"),
false,
);
let input = MSize::mSizeCall::new(()).abi_encode();
let (instance, export) = mock_runtime::prepare(&code, None);
let state = crate::mock_runtime::call(State::new(input), &instance, export);
assert_eq!(state.output.flags, 0);
// Solidity always stores the "free memory pointer" (32 byte int) at offset 64.
let expected = U256::try_from(64 + 32).unwrap();
let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected);
}
}
+18 -2
View File
@@ -2,6 +2,8 @@
//! Translates the context getter instructions.
//!
use inkwell::values::BasicValue;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
@@ -180,10 +182,24 @@ where
/// Translates the `msize` instruction.
///
pub fn msize<'ctx, D>(
_context: &mut Context<'ctx, D>,
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
let heap_end = context.build_sbrk(context.xlen_type().const_zero())?;
let heap_start = context
.get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)?
.value
.as_pointer_value();
let heap_size = context.builder().build_int_nuw_sub(
context
.builder()
.build_ptr_to_int(heap_end, context.xlen_type(), "heap_end")?,
context
.builder()
.build_ptr_to_int(heap_start, context.xlen_type(), "heap_start")?,
"heap_size",
)?;
Ok(heap_size.as_basic_value_enum())
}
+22 -3
View File
@@ -30,15 +30,34 @@ fn check_dependencies() {
}
}
///
/// Builds the Solidity project and returns the standard JSON output.
///
pub fn build_solidity(
sources: BTreeMap<String, String>,
libraries: BTreeMap<String, BTreeMap<String, String>>,
remappings: Option<BTreeSet<String>>,
pipeline: SolcPipeline,
optimizer_settings: era_compiler_llvm_context::OptimizerSettings,
) -> anyhow::Result<SolcStandardJsonOutput> {
build_solidity_with_options(
sources,
libraries,
remappings,
pipeline,
optimizer_settings,
true,
)
}
/// Builds the Solidity project and returns the standard JSON output.
/// Gives control over additional options:
/// - `solc_optimizer_enabled`: Whether to use the `solc` optimizer
pub fn build_solidity_with_options(
sources: BTreeMap<String, String>,
libraries: BTreeMap<String, BTreeMap<String, String>>,
remappings: Option<BTreeSet<String>>,
pipeline: SolcPipeline,
optimizer_settings: era_compiler_llvm_context::OptimizerSettings,
solc_optimizer_enabled: bool,
) -> anyhow::Result<SolcStandardJsonOutput> {
check_dependencies();
@@ -56,7 +75,7 @@ pub fn build_solidity(
remappings,
SolcStandardJsonInputSettingsSelection::new_required(pipeline),
SolcStandardJsonInputSettingsOptimizer::new(
true,
solc_optimizer_enabled,
None,
&solc_version.default,
false,