From 37cfd15543cb022c17b710687986aaff35dcc1e9 Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 9 Mar 2021 01:01:04 +0300 Subject: [PATCH] add explicit deletion of forgetting objects --- crates/main/src/lib.rs | 2 ++ crates/main/src/result.rs | 20 ++++++++++++++++++++ crates/wit/src/parsed_type/fn_arg.rs | 20 ++++++++++---------- crates/wit/src/parsed_type/fn_epilog.rs | 20 ++++++++------------ src/lib.rs | 1 + 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/crates/main/src/lib.rs b/crates/main/src/lib.rs index 15c4df8..285e606 100644 --- a/crates/main/src/lib.rs +++ b/crates/main/src/lib.rs @@ -57,6 +57,8 @@ pub use result::get_result_ptr; pub use result::get_result_size; pub use result::set_result_ptr; pub use result::set_result_size; +pub use result::release_objects; +pub use result::add_object_to_release; #[allow(unused_variables)] pub(crate) fn log>(msg: S) { diff --git a/crates/main/src/result.rs b/crates/main/src/result.rs index 59d0113..c3b31be 100644 --- a/crates/main/src/result.rs +++ b/crates/main/src/result.rs @@ -21,10 +21,13 @@ use super::log; use std::sync::atomic::AtomicUsize; +use std::cell::RefCell; static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0); static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); +thread_local!(static OBJECTS_TO_RELEASE: RefCell>> = RefCell::new(Vec::new())); + #[no_mangle] pub unsafe fn get_result_ptr() -> usize { log(format!( @@ -58,3 +61,20 @@ pub unsafe fn set_result_size(size: usize) { *RESULT_SIZE.get_mut() = size; } + +#[no_mangle] +pub unsafe fn release_objects() { + OBJECTS_TO_RELEASE.with(|objects| { + let mut objects = objects.borrow_mut(); + while let Some(object) = objects.pop() { + drop(object); + } + }) +} + +pub fn add_object_to_release(object: Box) { + OBJECTS_TO_RELEASE.with(|objects| { + let mut objects = objects.borrow_mut(); + objects.push(object); + }); +} diff --git a/crates/wit/src/parsed_type/fn_arg.rs b/crates/wit/src/parsed_type/fn_arg.rs index 0354170..54edf2a 100644 --- a/crates/wit/src/parsed_type/fn_arg.rs +++ b/crates/wit/src/parsed_type/fn_arg.rs @@ -1,17 +1,17 @@ /* - * copyright 2020 fluence labs limited + * Copyright 2020 Fluence Labs Limited * - * licensed under the apache license, version 2.0 (the "license"); - * you may not use this file except in compliance with the license. - * you may obtain a copy of the license at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/license-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * unless required by applicable law or agreed to in writing, software - * distributed under the license is distributed on an "as is" basis, - * without warranties or conditions of any kind, either express or implied. - * see the license for the specific language governing permissions and - * limitations under the license. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ use super::ParsedType; diff --git a/crates/wit/src/parsed_type/fn_epilog.rs b/crates/wit/src/parsed_type/fn_epilog.rs index 1eb60bb..c3d7270 100644 --- a/crates/wit/src/parsed_type/fn_epilog.rs +++ b/crates/wit/src/parsed_type/fn_epilog.rs @@ -133,9 +133,9 @@ fn generate_epilog(ty: &Option) -> proc_macro2::TokenStream { } } -/// If an export function returns a reference, probably this reference is to one -/// of these function arguments. In this case they should preserve after the end -/// of the function and then deleted by IT with explicitly call of deallocate. +/// If an export function returns a reference, this is probably a reference to one +/// of the function arguments. If that's the case, reference must be still valid after +/// the end of the function. Their deletion will be handled by IT with calling `release_objects`. fn generate_mem_forget( args: &Vec<(String, ParsedType)>, converted_args: &Vec, @@ -144,7 +144,7 @@ fn generate_mem_forget( let passing_style = ret_type.as_ref().map(passing_style_of); match passing_style { - Some(PassingStyle::ByValue) => mem_forget_by_ret_type(ret_type), + Some(PassingStyle::ByValue) => quote! { std::mem::forget(result); }, Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => { mem_forget_by_args(args, converted_args) } @@ -152,13 +152,6 @@ fn generate_mem_forget( } } -fn mem_forget_by_ret_type(ret_type: &Option) -> proc_macro2::TokenStream { - match ret_type { - Some(_) => quote! { std::mem::forget(result); }, - None => quote! {}, - } -} - fn mem_forget_by_args( args: &Vec<(String, ParsedType)>, converted_args: &Vec, @@ -171,7 +164,10 @@ fn mem_forget_by_args( match arg_passing_style { // such values will be deleted inside an export function because they are being moved PassingStyle::ByValue => {} - _ => res.extend(quote! { std::mem::forget(#converted_arg); }), + _ => res.extend(quote! { + fluence::internal::add_object_to_release(Box::new(#converted_arg)); + std::mem::forget(#converted_arg); + }), } } diff --git a/src/lib.rs b/src/lib.rs index c17e00e..69fc9b2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,4 +90,5 @@ pub mod internal { pub use fluence_sdk_main::get_result_size; pub use fluence_sdk_main::set_result_ptr; pub use fluence_sdk_main::set_result_size; + pub use fluence_sdk_main::add_object_to_release; }