mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
refactor abi
This commit is contained in:
parent
39c9aaa703
commit
d94a20f0ed
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use wasmer_runtime::Func;
|
use crate::vm::errors::FCEError;
|
||||||
|
|
||||||
/// Application binary interface of a FCE module. Different module could use such scheme for
|
/// Application binary interface of a FCE module. Different module could use such scheme for
|
||||||
/// communicate with each other.
|
/// communicate with each other.
|
||||||
@ -28,26 +28,19 @@ use wasmer_runtime::Func;
|
|||||||
/// 4. read a result from the res by reading 4 bytes as little-endian result_size
|
/// 4. read a result from the res by reading 4 bytes as little-endian result_size
|
||||||
/// and the read result_size bytes as the final result.
|
/// and the read result_size bytes as the final result.
|
||||||
/// 5. deallocate(res, strlen(sql)) to clean memory.
|
/// 5. deallocate(res, strlen(sql)) to clean memory.
|
||||||
|
pub(crate) trait ModuleABI {
|
||||||
pub(crate) trait ModuleABI<'a> {}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) struct ABI<'a> {
|
|
||||||
// It is safe to use unwrap() while calling these functions because Option is used here
|
|
||||||
// just to allow partially initialization. And all Option fields will contain Some if
|
|
||||||
// invoking FCE::new has been succeed.
|
|
||||||
/// Allocates a region of memory inside a module. Used for passing argument inside the module.
|
/// Allocates a region of memory inside a module. Used for passing argument inside the module.
|
||||||
pub(crate) allocate: Option<Func<'a, i32, i32>>,
|
fn allocate(&self, size: i32) -> Result<i32, FCEError>;
|
||||||
|
|
||||||
/// Deallocates previously allocated memory region.
|
/// Deallocates previously allocated memory region.
|
||||||
pub(crate) deallocate: Option<Func<'a, (i32, i32), ()>>,
|
fn deallocate(&self, ptr: i32, size: i32) -> Result<(), FCEError>;
|
||||||
|
|
||||||
/// Calls the main entry point of a module called invoke.
|
/// Calls the main entry point of a module called invoke.
|
||||||
pub(crate) invoke: Option<Func<'a, (i32, i32), i32>>,
|
fn invoke(&self, arg_address: i32, arg_size: i32) -> Result<i32, FCEError>;
|
||||||
|
|
||||||
/// Stores one given byte on provided address.
|
/// Stores one byte on given address.
|
||||||
pub(crate) store: Option<Func<'a, (i32, i32)>>,
|
fn store(&self, address: i32, value: i32) -> Result<(), FCEError>;
|
||||||
|
|
||||||
/// Loads one bytes from provided address.
|
/// Loads one byte from given address.
|
||||||
pub(crate) load: Option<Func<'a, i32, i32>>,
|
fn load(&self, address: i32) -> Result<i32, FCEError>;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use crate::vm::config::Config;
|
use crate::vm::config::Config;
|
||||||
use crate::vm::errors::FCEError;
|
use crate::vm::errors::FCEError;
|
||||||
use crate::vm::module::fce_result::FCEResult;
|
use crate::vm::module::fce_result::FCEResult;
|
||||||
use crate::vm::module::{ModuleAPI, ABI};
|
use crate::vm::module::{ModuleABI, ModuleAPI};
|
||||||
|
|
||||||
use sha2::digest::generic_array::GenericArray;
|
use sha2::digest::generic_array::GenericArray;
|
||||||
use sha2::digest::FixedOutput;
|
use sha2::digest::FixedOutput;
|
||||||
@ -26,6 +26,22 @@ use wasmer_runtime_core::import::ImportObject;
|
|||||||
use wasmer_runtime_core::memory::ptr::{Array, WasmPtr};
|
use wasmer_runtime_core::memory::ptr::{Array, WasmPtr};
|
||||||
use wasmer_wasi::generate_import_object_for_version;
|
use wasmer_wasi::generate_import_object_for_version;
|
||||||
|
|
||||||
|
/// Desribes Application Binary Interface of a module.
|
||||||
|
/// For more details see comment in abi.rs.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct ABI<'a> {
|
||||||
|
// It is safe to use unwrap() while calling these functions because Option is used here
|
||||||
|
// just to allow partially initialization. And all Option fields will contain Some if
|
||||||
|
// invoking FCE::new has been succeed.
|
||||||
|
pub(crate) allocate: Option<Func<'a, i32, i32>>,
|
||||||
|
pub(crate) deallocate: Option<Func<'a, (i32, i32), ()>>,
|
||||||
|
pub(crate) invoke: Option<Func<'a, (i32, i32), i32>>,
|
||||||
|
pub(crate) store: Option<Func<'a, (i32, i32)>>,
|
||||||
|
pub(crate) load: Option<Func<'a, i32, i32>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A building block of multi-modules scheme of FCE, represents one module that corresponds
|
||||||
|
/// to a one Wasm file.
|
||||||
pub(crate) struct FCEModule {
|
pub(crate) struct FCEModule {
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
abi: ABI<'static>,
|
abi: ABI<'static>,
|
||||||
@ -39,6 +55,7 @@ impl FCEModule {
|
|||||||
"log_utf8_string" => func!(FCEModule::logger_log_utf8_string),
|
"log_utf8_string" => func!(FCEModule::logger_log_utf8_string),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
let config_copy = config.clone();
|
||||||
|
|
||||||
let mut import_object = generate_import_object_for_version(
|
let mut import_object = generate_import_object_for_version(
|
||||||
config.wasi_config.version,
|
config.wasi_config.version,
|
||||||
@ -52,42 +69,41 @@ impl FCEModule {
|
|||||||
import_object.allow_missing_functions = false;
|
import_object.allow_missing_functions = false;
|
||||||
|
|
||||||
let instance = compile(&wasm_bytes)?.instantiate(&import_object)?;
|
let instance = compile(&wasm_bytes)?.instantiate(&import_object)?;
|
||||||
|
let abi = FCEModule::create_abi(&instance, &config_copy)?;
|
||||||
|
|
||||||
|
Ok(Self { instance, abi })
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
fn create_abi(instance: &Instance, config: &Config) -> Result<ABI<'static>, FCEError> {
|
||||||
|
unsafe {
|
||||||
let allocate = std::mem::transmute::<Func<'_, i32, i32>, Func<'static, i32, i32>>(
|
let allocate = std::mem::transmute::<Func<'_, i32, i32>, Func<'static, i32, i32>>(
|
||||||
instance.exports.get(&config.allocate_fn_name)?
|
instance.exports.get(&config.allocate_fn_name)?
|
||||||
);
|
);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let deallocate = std::mem::transmute::<Func<'_, (i32, i32)>, Func<'static, (i32, i32)>>(
|
let deallocate = std::mem::transmute::<Func<'_, (i32, i32)>, Func<'static, (i32, i32)>>(
|
||||||
instance.exports.get(&config.deallocate_fn_name)?
|
instance.exports.get(&config.deallocate_fn_name)?
|
||||||
);
|
);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let invoke = std::mem::transmute::<Func<'_, (i32, i32), i32>, Func<'static, (i32, i32), i32>, >(
|
let invoke = std::mem::transmute::<Func<'_, (i32, i32), i32>, Func<'static, (i32, i32), i32>, >(
|
||||||
instance.exports.get(&config.invoke_fn_name)?
|
instance.exports.get(&config.invoke_fn_name)?
|
||||||
);
|
);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let store = std::mem::transmute::<Func<'_, (i32, i32)>, Func<'static, _, _>>(
|
let store = std::mem::transmute::<Func<'_, (i32, i32)>, Func<'static, _, _>>(
|
||||||
instance.exports.get(&config.store_fn_name)?,
|
instance.exports.get(&config.store_fn_name)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let load = std::mem::transmute::<Func<'_, i32, i32>, Func<'static, _, _>>(
|
let load = std::mem::transmute::<Func<'_, i32, i32>, Func<'static, _, _>>(
|
||||||
instance.exports.get(&config.load_fn_name)?,
|
instance.exports.get(&config.load_fn_name)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let abi = ABI {
|
Ok(ABI {
|
||||||
allocate: Some(allocate),
|
allocate: Some(allocate),
|
||||||
deallocate: Some(deallocate),
|
deallocate: Some(deallocate),
|
||||||
invoke: Some(invoke),
|
invoke: Some(invoke),
|
||||||
store: Some(store),
|
store: Some(store),
|
||||||
load: Some(load),
|
load: Some(load),
|
||||||
};
|
})
|
||||||
|
|
||||||
Ok(Self { instance, abi })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +155,11 @@ impl FCEModule {
|
|||||||
|
|
||||||
impl ModuleAPI for FCEModule {
|
impl ModuleAPI for FCEModule {
|
||||||
fn invoke(&mut self, argument: &[u8]) -> Result<FCEResult, FCEError> {
|
fn invoke(&mut self, argument: &[u8]) -> Result<FCEResult, FCEError> {
|
||||||
// allocate memory for the given argument and write it to memory
|
|
||||||
let argument_len = argument.len() as i32;
|
let argument_len = argument.len() as i32;
|
||||||
|
|
||||||
|
// allocate memory for the given argument and write it to memory
|
||||||
let argument_address = if argument_len != 0 {
|
let argument_address = if argument_len != 0 {
|
||||||
let address = self.abi.allocate.as_ref().unwrap().call(argument_len)?;
|
let address = self.allocate(argument_len)?;
|
||||||
self.write_to_mem(address as usize, argument)?;
|
self.write_to_mem(address as usize, argument)?;
|
||||||
address
|
address
|
||||||
} else {
|
} else {
|
||||||
@ -150,19 +167,9 @@ impl ModuleAPI for FCEModule {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// invoke a main module, read a result and deallocate it
|
// invoke a main module, read a result and deallocate it
|
||||||
let result_address = self
|
let result_address = <Self as ModuleABI>::invoke(self, argument_address, argument_len)?;
|
||||||
.abi
|
|
||||||
.invoke
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.call(argument_address, argument_len)?;
|
|
||||||
let result = self.read_result_from_mem(result_address as _)?;
|
let result = self.read_result_from_mem(result_address as _)?;
|
||||||
|
self.deallocate(result_address, result.len() as i32)?;
|
||||||
self.abi
|
|
||||||
.deallocate
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.call(result_address, result.len() as i32)?;
|
|
||||||
|
|
||||||
Ok(FCEResult::new(result))
|
Ok(FCEResult::new(result))
|
||||||
}
|
}
|
||||||
@ -186,6 +193,33 @@ impl ModuleAPI for FCEModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ModuleABI for FCEModule {
|
||||||
|
fn allocate(&self, size: i32) -> Result<i32, FCEError> {
|
||||||
|
Ok(self.abi.allocate.as_ref().unwrap().call(size)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deallocate(&self, ptr: i32, size: i32) -> Result<(), FCEError> {
|
||||||
|
Ok(self.abi.deallocate.as_ref().unwrap().call(ptr, size)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn invoke(&self, arg_address: i32, arg_size: i32) -> Result<i32, FCEError> {
|
||||||
|
Ok(self
|
||||||
|
.abi
|
||||||
|
.invoke
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.call(arg_address, arg_size)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&self, address: i32, value: i32) -> Result<(), FCEError> {
|
||||||
|
Ok(self.abi.store.as_ref().unwrap().call(address, value)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(&self, address: i32) -> Result<i32, FCEError> {
|
||||||
|
Ok(self.abi.load.as_ref().unwrap().call(address)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for FCEModule {
|
impl Drop for FCEModule {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,6 @@ mod api;
|
|||||||
mod fce_module;
|
mod fce_module;
|
||||||
pub mod fce_result;
|
pub mod fce_result;
|
||||||
|
|
||||||
pub(crate) use abi::ABI;
|
pub(crate) use abi::ModuleABI;
|
||||||
pub(crate) use api::ModuleAPI;
|
pub(crate) use api::ModuleAPI;
|
||||||
pub(crate) use fce_module::FCEModule;
|
pub(crate) use fce_module::FCEModule;
|
||||||
|
Loading…
Reference in New Issue
Block a user