Skip to content
Draft
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ impl ManagedTypeContainer {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ impl ManagedTypeContainer {
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
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ impl ManagedTypeContainer {

num_bytes_copied
}

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
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ impl ManagedTypeContainer {
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/host/vm_hooks/vh_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(super) const RESULT_ERROR: i32 = 1;
/// Dispatches messages coming via VMHooks to the underlying implementation (the VMHooksHandler).
#[derive(Debug)]
pub struct VMHooksDispatcher<C: VMHooksContext> {
pub(crate) handler: VMHooksHandler<C>,
pub handler: VMHooksHandler<C>,
}

impl<C: VMHooksContext> VMHooksDispatcher<C> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,8 @@ impl<C: VMHooksContext> VMHooksHandler<C> {

Ok(())
}

pub fn bf_drop(&self, map_handle: RawHandle) {
self.context.m_types_lock().bf_remove(map_handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,8 @@ impl<C: VMHooksContext> VMHooksHandler<C> {

Ok(())
}

pub fn bi_drop(&self, map_handle: RawHandle) {
self.context.m_types_lock().bi_remove(map_handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,8 @@ impl<C: VMHooksContext> VMHooksHandler<C> {
.mb_set(dest_handle, encoded.into_bytes());
Ok(())
}

pub fn mb_drop(&self, handle: RawHandle) {
self.context.m_types_lock().mb_remove(handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@ impl<C: VMHooksContext> VMHooksHandler<C> {
.m_types_lock()
.mm_contains(map_handle, key.as_slice())
}

pub fn mm_drop(&self, map_handle: RawHandle) {
self.context.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 @@ -59,4 +59,10 @@ pub trait ManagedTypeApiImpl:
fn get_token_ticker_len(&self, token_id_len: usize) -> usize {
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 @@ -425,6 +425,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
11 changes: 6 additions & 5 deletions framework/scenario/src/api/impl_vh/debug_api.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use multiversx_chain_vm::{
executor::{VMHooks, VMHooksEarlyExit},
executor::VMHooksEarlyExit,
host::context::TxContextRef,
host::vm_hooks::{TxVMHooksContext, VMHooksDispatcher},
};
use multiversx_sc::{chain_core::types::ReturnCode, err_msg};

use crate::executor::debug::{
ContractDebugInstance, ContractDebugInstanceState, ContractDebugStack, StaticVarData,
VMHooksDebugger,
};

use super::{DebugHandle, VMHooksApi, VMHooksApiBackend};
Expand All @@ -19,7 +20,7 @@ impl VMHooksApiBackend for DebugApiBackend {

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
let instance = ContractDebugStack::static_peek();
let tx_context_ref = instance.tx_context_ref.clone();
Expand All @@ -30,7 +31,7 @@ impl VMHooksApiBackend for DebugApiBackend {

fn with_vm_hooks_ctx_1<R, F>(handle: Self::HandleType, f: F) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
let tx_context_ref = TxContextRef(handle.context.clone());
let vh_context = TxVMHooksContext::new(tx_context_ref, ContractDebugInstanceState);
Expand All @@ -40,7 +41,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(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
assert_handles_on_same_context(&handle1, &handle2);
Self::with_vm_hooks_ctx_1(handle1, f)
Expand All @@ -53,7 +54,7 @@ impl VMHooksApiBackend for DebugApiBackend {
f: F,
) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
assert_handles_on_same_context(&handle1, &handle2);
assert_handles_on_same_context(&handle1, &handle3);
Expand Down
7 changes: 3 additions & 4 deletions framework/scenario/src/api/impl_vh/single_tx_api.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::sync::Mutex;

use multiversx_chain_vm::{
blockchain::state::AccountData, executor::VMHooks, host::vm_hooks::VMHooksDispatcher,
types::VMAddress,
blockchain::state::AccountData, host::vm_hooks::VMHooksDispatcher, types::VMAddress,
};
use multiversx_chain_vm_executor::VMHooksEarlyExit;
use multiversx_sc::api::RawHandle;

use crate::executor::debug::{ContractDebugInstanceState, StaticVarData};
use crate::executor::debug::{ContractDebugInstanceState, StaticVarData, VMHooksDebugger};

use super::{SingleTxApiData, SingleTxApiVMHooksContext, VMHooksApi, VMHooksApiBackend};

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

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

use crate::executor::debug::{ContractDebugInstanceState, StaticVarData};
use crate::executor::debug::{ContractDebugInstanceState, StaticVarData, VMHooksDebugger};

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

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

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
STATIC_API_VH_CELL.with(|vh_mutex| {
let mut 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::executor::debug::StaticVarData;
use crate::executor::debug::{StaticVarData, VMHooksDebugger};

use super::VMHooksApiBackend;

use std::marker::PhantomData;

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

Expand All @@ -23,15 +23,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(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
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(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
VHB::with_vm_hooks_ctx_1(handle.clone(), f)
}
Expand All @@ -44,7 +44,7 @@ impl<VHB: VMHooksApiBackend> VMHooksApi<VHB> {
f: F,
) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
VHB::with_vm_hooks_ctx_2(handle1.clone(), handle2.clone(), f)
}
Expand All @@ -58,7 +58,7 @@ impl<VHB: VMHooksApiBackend> VMHooksApi<VHB> {
f: F,
) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
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,8 +1,7 @@
use multiversx_chain_vm::executor::VMHooks;
use multiversx_chain_vm_executor::VMHooksEarlyExit;
use multiversx_sc::api::HandleConstraints;

use crate::executor::debug::StaticVarData;
use crate::executor::debug::{StaticVarData, VMHooksDebugger};

pub trait VMHooksApiBackend: Clone + Send + Sync + 'static {
/// We use a single handle type for all handles.
Expand All @@ -11,18 +10,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(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>;
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>;

fn with_vm_hooks_ctx_1<R, F>(_handle: Self::HandleType, f: F) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
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(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
Self::with_vm_hooks(f)
}
Expand All @@ -34,7 +33,7 @@ pub trait VMHooksApiBackend: Clone + Send + Sync + 'static {
f: F,
) -> R
where
F: FnOnce(&mut dyn VMHooks) -> Result<R, VMHooksEarlyExit>,
F: FnOnce(&mut dyn VMHooksDebugger) -> Result<R, VMHooksEarlyExit>,
{
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 @@ -127,4 +127,28 @@ impl<VHB: VMHooksApiBackend> ManagedTypeApiImpl for VMHooksApi<VHB> {
});
i32_to_bool(result)
}

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/executor/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod contract_debug_whitebox_lambda;
mod contract_map;
mod static_var_data;
mod tx_static_vars;
mod vm_hooks_debugger;

pub use catch_tx_panic::catch_tx_panic;
pub use contract_container::{ContractContainer, ContractContainerRef};
Expand All @@ -21,3 +22,4 @@ pub use contract_debug_whitebox_lambda::ContractDebugWhiteboxLambda;
pub use contract_map::{ContractMap, ContractMapRef};
pub use static_var_data::StaticVarData;
pub use tx_static_vars::TxStaticVars;
pub use vm_hooks_debugger::VMHooksDebugger;
37 changes: 37 additions & 0 deletions framework/scenario/src/executor/debug/vm_hooks_debugger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use multiversx_chain_vm::host::vm_hooks::{VMHooksContext, VMHooksDispatcher};
use multiversx_chain_vm_executor::{VMHooks, VMHooksEarlyExit};

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

impl<C: VMHooksContext> VMHooksDebugger for VMHooksDispatcher<C> {
fn drop_managed_buffer(&self, handle: i32) -> Result<(), VMHooksEarlyExit> {
self.handler.mb_drop(handle);
Ok(())
}

fn drop_big_float(&self, handle: i32) -> Result<(), VMHooksEarlyExit> {
self.handler.bf_drop(handle);
Ok(())
}

fn drop_big_int(&self, handle: i32) -> Result<(), VMHooksEarlyExit> {
self.handler.bi_drop(handle);
Ok(())
}

fn drop_elliptic_curve(&self, _handle: i32) -> Result<(), VMHooksEarlyExit> {
// TODO: not implemented
Ok(())
}

fn drop_managed_map(&self, handle: i32) -> Result<(), VMHooksEarlyExit> {
self.handler.mm_drop(handle);
Ok(())
}
}
Loading