Skip to content
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