Unverified Commit b0681a04 authored by Hero Bird's avatar Hero Bird Committed by GitHub

Add method to finalize the dynamic storage allocator (#418)

* [core] implement alloc::finalize for the dynamic storage allocator

* [core] adjust tests for the changes

* [core] apply rustfmt

* [core] fix clippy warning

* [core] add SAFETY comments to dynamic storage allocator for Wasm

* [core] add a Note to the docs of alloc::{initialize, finalize}
parent 718b9f5e
Pipeline #93822 failed with stages
in 6 minutes and 2 seconds
This diff is collapsed.
......@@ -75,21 +75,15 @@ mod init;
#[cfg(test)]
mod tests;
use self::allocator::DynamicAllocator;
pub use self::{
allocation::DynamicAllocation,
init::{
initialize_for,
ContractPhase,
},
};
use self::{
allocator::DynamicAllocator,
init::on_call,
init::ContractPhase,
};
/// Returns a new dynamic storage allocation.
pub fn alloc() -> DynamicAllocation {
on_call(DynamicAllocator::alloc)
init::on_instance(DynamicAllocator::alloc)
}
/// Frees the given dynamic storage allocation.
......@@ -97,5 +91,43 @@ pub fn alloc() -> DynamicAllocation {
/// This makes the given dynamic storage allocation available again
/// for new dynamic storage allocations.
pub fn free(allocation: DynamicAllocation) {
on_call(|allocator| allocator.free(allocation))
init::on_instance(|allocator| allocator.free(allocation))
}
/// Tells the global dynamic storage allocator instance how it shall initialize.
///
/// # Note
///
/// Normally users of ink! do not have to call this function directly as it is
/// automatically being use in the correct order and way by the generated code.
///
/// - The `phase` parameter describes for which execution phase the dynamic
/// storage allocator needs to be initialized since this is different
/// in contract instantiations and calls.
/// - This has to be issued before the first interaction with the global allocator.
/// - The actual instantiation will happen only upon the first interaction with
/// the global allocator, e.g. using its `alloc` or `free` calls. Until then
/// it remains uninitialized.
///
/// If this function is not called before the first global allocator interaction
/// then the default initialization scheme is for contract instantiation.
/// However, this behavior might change and must not be relied upon.
pub fn initialize(phase: ContractPhase) {
init::initialize(phase);
}
/// Finalizes the global dynamic storage allocator instance.
///
/// This pushes all the accumulated state from this contract execution back to
/// the contract storage to be used in the next contract execution for the same
/// contract instance.
///
/// The global dynamic storage allocator must not be used after this!
///
/// # Note
///
/// Normally users of ink! do not have to call this function directly as it is
/// automatically being use in the correct order and way by the generated code.
pub fn finalize() {
init::finalize()
}
......@@ -15,7 +15,6 @@
use super::{
alloc,
free,
initialize_for,
ContractPhase,
DynamicAllocation,
DynamicAllocator,
......@@ -25,9 +24,12 @@ use crate::{
test,
DefaultEnvTypes,
},
storage2::traits::{
KeyPtr,
SpreadLayout,
storage2::{
alloc,
traits::{
KeyPtr,
SpreadLayout,
},
},
};
use ink_primitives::Key;
......@@ -36,7 +38,7 @@ fn run_default_test<F>(f: F)
where
F: FnOnce(),
{
initialize_for(ContractPhase::Deploy);
alloc::initialize(ContractPhase::Deploy);
test::run_test::<DefaultEnvTypes, _>(|_| {
f();
Ok(())
......@@ -195,7 +197,7 @@ fn test_call_setup_works() {
assert_eq!(allocator.alloc(), DynamicAllocation(1));
let root_key = Key([0xFE; 32]);
SpreadLayout::push_spread(&allocator, &mut KeyPtr::from(root_key));
initialize_for(ContractPhase::Call);
alloc::initialize(ContractPhase::Call);
assert_eq!(alloc(), DynamicAllocation(2));
assert_eq!(alloc(), DynamicAllocation(3));
free(DynamicAllocation(0));
......
......@@ -17,10 +17,8 @@ use crate::{
env,
env::test::DefaultAccounts,
storage2::{
alloc::{
initialize_for,
ContractPhase,
},
alloc,
alloc::ContractPhase,
traits::{
KeyPtr,
SpreadLayout,
......@@ -50,7 +48,7 @@ where
F: FnOnce(DefaultAccounts<env::DefaultEnvTypes>),
{
env::test::run_test::<env::DefaultEnvTypes, _>(|default_accounts| {
initialize_for(ContractPhase::Deploy);
alloc::initialize(ContractPhase::Deploy);
f(default_accounts);
Ok(())
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment