Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

managed dealloc #1680

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions chain/vm/src/tx_mock/tx_managed_types/handle_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,8 @@ impl<V> HandleMap<V> {
pub fn insert(&mut self, handle: RawHandle, value: V) {
let _ = self.map.insert(handle, value);
}

pub fn remove_handle(&mut self, handle: RawHandle) {
let _ = self.map.remove(&handle);
}
}
4 changes: 4 additions & 0 deletions chain/vm/src/tx_mock/tx_managed_types/tx_big_float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ impl TxManagedTypes {
pub fn bf_overwrite(&mut self, handle: RawHandle, value: f64) {
self.big_float_map.insert(handle, value);
}

pub fn bf_remove(&mut self, handle: RawHandle) {
self.big_float_map.remove_handle(handle);
}
}
4 changes: 4 additions & 0 deletions chain/vm/src/tx_mock/tx_managed_types/tx_big_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ impl TxManagedTypes {
self.big_int_map.insert_new_handle_raw(value)
}

pub fn bi_remove(&mut self, handle: RawHandle) {
self.big_int_map.remove_handle(handle);
}

pub fn bi_overwrite(&mut self, destination: RawHandle, value: num_bigint::BigInt) {
self.big_int_map.insert(destination, value);
}
Expand Down
4 changes: 4 additions & 0 deletions chain/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ impl TxManagedTypes {
self.mb_append_bytes(dest_handle, &handle_to_be_bytes(amount_handle)[..]);
}
}

pub fn mb_remove(&mut self, handle: RawHandle) {
self.managed_buffer_map.remove_handle(handle);
}
}

pub fn handle_to_be_bytes(handle: RawHandle) -> [u8; 4] {
Expand Down
4 changes: 4 additions & 0 deletions chain/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ impl TxManagedTypes {
let mmap = self.managed_map_map.get_mut(map_handle);
mmap.remove(key).unwrap_or_default()
}

pub fn mm_remove(&mut self, handle: RawHandle) {
self.managed_map_map.remove_handle(handle);
}
}
2 changes: 1 addition & 1 deletion chain/vm/src/vm_hooks/vh_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::VMHooksHandler;
/// Dispatches messages coming via VMHooks to the underlying implementation (the VMHooksHandler).
#[derive(Debug)]
pub struct VMHooksDispatcher {
handler: Box<dyn VMHooksHandler>,
pub handler: Box<dyn VMHooksHandler>,
}

impl VMHooksDispatcher {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,8 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError {
fn bf_get_const_e(&self, dest: RawHandle) {
self.m_types_lock().bf_overwrite(dest, std::f64::consts::E);
}

fn bf_drop(&self, map_handle: RawHandle) {
self.m_types_lock().bf_remove(map_handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,8 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError {
let result = bi_x.shl(bits);
self.m_types_lock().bi_overwrite(dest, result);
}

fn bi_drop(&self, map_handle: RawHandle) {
self.m_types_lock().bi_remove(map_handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,8 @@ pub trait VMHooksManagedBuffer: VMHooksHandlerSource {
self.m_types_lock()
.mb_set(dest_handle, encoded.into_bytes());
}

fn mb_drop(&self, handle: RawHandle) {
self.m_types_lock().mb_remove(handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ pub trait VMHooksManagedMap: VMHooksHandlerSource {
let key = self.m_types_lock().mb_get(key_handle).to_vec();
self.m_types_lock().mm_contains(map_handle, key.as_slice())
}

fn mm_drop(&self, map_handle: RawHandle) {
self.m_types_lock().mm_remove(map_handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ fn test_managed_address_zero() {
let result = bf.managed_address_zero();
assert_eq!(ManagedAddress::zero(), result);
}

#[test]
fn test_managed_buffer_destructor() {
let my_buffer = ManagedBuffer::<StaticApi>::from(b"my buffer");
assert_eq!(my_buffer, managed_buffer!(b"my buffer"));
drop(my_buffer);
}
6 changes: 6 additions & 0 deletions framework/base/src/api/managed_types/managed_type_api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,10 @@ pub trait ManagedTypeApiImpl:
fn get_token_ticker_len(&self, token_id_len: usize) -> usize {
super::token_identifier_util::get_token_ticker_len(token_id_len)
}

fn drop_managed_buffer(&self, _handle: Self::ManagedBufferHandle) {}
fn drop_big_float(&self, _handle: Self::BigFloatHandle) {}
fn drop_big_int(&self, _handle: Self::BigIntHandle) {}
fn drop_elliptic_curve(&self, _handle: Self::EllipticCurveHandle) {}
fn drop_managed_map(&self, _handle: Self::ManagedMapHandle) {}
}
7 changes: 7 additions & 0 deletions framework/base/src/types/managed/basic/managed_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,13 @@ impl<M: ManagedTypeApi> Clone for ManagedBuffer<M> {
}
}

impl<M: ManagedTypeApi> Drop for ManagedBuffer<M> {
fn drop(&mut self) {
// TODO: enable, after fixing all ownership issues
// M::managed_type_impl().drop_managed_buffer(self.handle.clone());
}
}

impl<M: ManagedTypeApi> PartialEq for ManagedBuffer<M> {
#[inline]
fn eq(&self, other: &Self) -> bool {
Expand Down
12 changes: 6 additions & 6 deletions framework/scenario/src/api/impl_vh/debug_api.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::sync::Arc;

use multiversx_chain_vm::{
executor::{BreakpointValue, VMHooks},
executor::BreakpointValue,
tx_mock::{TxContext, TxContextRef, TxContextStack, TxPanic},
vm_hooks::{DebugApiVMHooksHandler, VMHooksDispatcher},
};
use multiversx_sc::{chain_core::types::ReturnCode, err_msg};

use crate::debug_executor::{StaticVarData, StaticVarStack};
use crate::debug_executor::{StaticVarData, StaticVarStack, VMHooksDebugger};

use super::{DebugHandle, VMHooksApi, VMHooksApiBackend};

Expand All @@ -19,7 +19,7 @@ impl VMHooksApiBackend for DebugApiBackend {

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
let top_context = TxContextStack::static_peek();
let wrapper = DebugApiVMHooksHandler::new(top_context);
Expand All @@ -29,7 +29,7 @@ impl VMHooksApiBackend for DebugApiBackend {

fn with_vm_hooks_ctx_1<R, F>(handle: Self::HandleType, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
let wrapper = DebugApiVMHooksHandler::new(handle.context);
let dispatcher = VMHooksDispatcher::new(Box::new(wrapper));
Expand All @@ -38,7 +38,7 @@ impl VMHooksApiBackend for DebugApiBackend {

fn with_vm_hooks_ctx_2<R, F>(handle1: Self::HandleType, handle2: Self::HandleType, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
assert_handles_on_same_context(&handle1, &handle2);
Self::with_vm_hooks_ctx_1(handle1, f)
Expand All @@ -51,7 +51,7 @@ impl VMHooksApiBackend for DebugApiBackend {
f: F,
) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
assert_handles_on_same_context(&handle1, &handle2);
assert_handles_on_same_context(&handle1, &handle3);
Expand Down
5 changes: 2 additions & 3 deletions framework/scenario/src/api/impl_vh/single_tx_api.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::sync::Mutex;

use multiversx_chain_vm::{
executor::VMHooks,
types::VMAddress,
vm_hooks::{SingleTxApiData, SingleTxApiVMHooksHandler, VMHooksDispatcher},
world_mock::AccountData,
};
use multiversx_sc::api::RawHandle;

use crate::debug_executor::StaticVarData;
use crate::debug_executor::{StaticVarData, VMHooksDebugger};

use super::{VMHooksApi, VMHooksApiBackend};

Expand All @@ -26,7 +25,7 @@ impl VMHooksApiBackend for SingleTxApiBackend {

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
SINGLE_TX_API_VH_CELL.with(|cell| {
let handler = cell.lock().unwrap().clone();
Expand Down
9 changes: 3 additions & 6 deletions framework/scenario/src/api/impl_vh/static_api.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use multiversx_chain_vm::{
executor::VMHooks,
vm_hooks::{StaticApiVMHooksHandler, VMHooksDispatcher, VMHooksHandler},
};
use multiversx_chain_vm::vm_hooks::{StaticApiVMHooksHandler, VMHooksDispatcher, VMHooksHandler};
use multiversx_sc::{api::RawHandle, types::Address};
use std::sync::Mutex;

use crate::debug_executor::StaticVarData;
use crate::debug_executor::{StaticVarData, VMHooksDebugger};

use super::{VMHooksApi, VMHooksApiBackend};

Expand All @@ -28,7 +25,7 @@ impl VMHooksApiBackend for StaticApiBackend {

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
STATIC_API_VH_CELL.with(|vh_mutex| {
let vh = vh_mutex.lock().unwrap();
Expand Down
12 changes: 6 additions & 6 deletions framework/scenario/src/api/impl_vh/vm_hooks_api.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::debug_executor::StaticVarData;
use crate::debug_executor::{StaticVarData, VMHooksDebugger};

use super::VMHooksApiBackend;

use std::marker::PhantomData;

use multiversx_chain_vm::executor::{MemPtr, VMHooks};
use multiversx_chain_vm::executor::MemPtr;
use multiversx_sc::api::{HandleTypeInfo, ManagedBufferApiImpl};

#[derive(Clone, Debug)]
Expand All @@ -22,15 +22,15 @@ impl<VHB: VMHooksApiBackend> VMHooksApi<VHB> {
/// All communication with the VM happens via this method.
pub fn with_vm_hooks<R, F>(&self, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
VHB::with_vm_hooks(f)
}

/// Works with the VM hooks given by the context of 1 handle.
pub fn with_vm_hooks_ctx_1<R, F>(&self, handle: &VHB::HandleType, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
VHB::with_vm_hooks_ctx_1(handle.clone(), f)
}
Expand All @@ -43,7 +43,7 @@ impl<VHB: VMHooksApiBackend> VMHooksApi<VHB> {
f: F,
) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
VHB::with_vm_hooks_ctx_2(handle1.clone(), handle2.clone(), f)
}
Expand All @@ -57,7 +57,7 @@ impl<VHB: VMHooksApiBackend> VMHooksApi<VHB> {
f: F,
) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
VHB::with_vm_hooks_ctx_3(handle1.clone(), handle2.clone(), handle3.clone(), f)
}
Expand Down
11 changes: 5 additions & 6 deletions framework/scenario/src/api/impl_vh/vm_hooks_backend.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use multiversx_chain_vm::executor::VMHooks;
use multiversx_sc::api::HandleConstraints;

use crate::debug_executor::StaticVarData;
use crate::debug_executor::{StaticVarData, VMHooksDebugger};

pub trait VMHooksApiBackend: Clone + Send + Sync + 'static {
/// We use a single handle type for all handles.
Expand All @@ -10,18 +9,18 @@ pub trait VMHooksApiBackend: Clone + Send + Sync + 'static {
/// All communication with the VM happens via this method.
fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R;
F: FnOnce(&dyn VMHooksDebugger) -> R;

fn with_vm_hooks_ctx_1<R, F>(_handle: Self::HandleType, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
Self::with_vm_hooks(f)
}

fn with_vm_hooks_ctx_2<R, F>(_handle1: Self::HandleType, _handle2: Self::HandleType, f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
Self::with_vm_hooks(f)
}
Expand All @@ -33,7 +32,7 @@ pub trait VMHooksApiBackend: Clone + Send + Sync + 'static {
f: F,
) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
F: FnOnce(&dyn VMHooksDebugger) -> R,
{
Self::with_vm_hooks(f)
}
Expand Down
24 changes: 24 additions & 0 deletions framework/scenario/src/api/managed_type_api_vh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,28 @@ impl<VHB: VMHooksApiBackend> ManagedTypeApiImpl for VMHooksApi<VHB> {
)
});
}

fn drop_managed_buffer(&self, handle: Self::ManagedBufferHandle) {
self.with_vm_hooks_ctx_1(&handle, |vh| {
vh.drop_managed_buffer(handle.get_raw_handle_unchecked())
});
}
fn drop_big_float(&self, handle: Self::BigFloatHandle) {
self.with_vm_hooks_ctx_1(&handle, |vh| {
vh.drop_big_float(handle.get_raw_handle_unchecked())
});
}
fn drop_big_int(&self, handle: Self::BigIntHandle) {
self.with_vm_hooks_ctx_1(&handle, |vh| {
vh.drop_big_int(handle.get_raw_handle_unchecked())
});
}
fn drop_elliptic_curve(&self, _handle: Self::EllipticCurveHandle) {
// TODO
}
fn drop_managed_map(&self, handle: Self::ManagedMapHandle) {
self.with_vm_hooks_ctx_1(&handle, |vh| {
vh.drop_managed_map(handle.get_raw_handle_unchecked())
});
}
}
2 changes: 2 additions & 0 deletions framework/scenario/src/debug_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod contract_container;
mod contract_map;
mod static_var_stack;
mod tx_static_vars;
mod vm_hooks_debugger;

pub use catch_tx_panic::catch_tx_panic;
pub use contract_container::{
Expand All @@ -11,3 +12,4 @@ pub use contract_container::{
pub use contract_map::{ContractMap, ContractMapRef};
pub use static_var_stack::{StaticVarData, StaticVarStack};
pub use tx_static_vars::TxStaticVars;
pub use vm_hooks_debugger::VMHooksDebugger;
32 changes: 32 additions & 0 deletions framework/scenario/src/debug_executor/vm_hooks_debugger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use multiversx_chain_vm::vm_hooks::VMHooksDispatcher;
use multiversx_chain_vm_executor::VMHooks;

pub trait VMHooksDebugger: VMHooks {
fn drop_managed_buffer(&self, handle: i32);
fn drop_big_float(&self, handle: i32);
fn drop_big_int(&self, handle: i32);
fn drop_elliptic_curve(&self, handle: i32);
fn drop_managed_map(&self, handle: i32);
}

impl VMHooksDebugger for VMHooksDispatcher {
fn drop_managed_buffer(&self, handle: i32) {
self.handler.mb_drop(handle);
}

fn drop_big_float(&self, handle: i32) {
self.handler.bf_drop(handle);
}

fn drop_big_int(&self, handle: i32) {
self.handler.bi_drop(handle);
}

fn drop_elliptic_curve(&self, _handle: i32) {
// TODO: not implemented
}

fn drop_managed_map(&self, handle: i32) {
self.handler.mm_drop(handle);
}
}
Loading