mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-17 08:40:50 +00:00
feat(runtime-c-api) Ability to generate ImportObject
for a specific WASI version.
This patch introduces 2 new functions: * `wasmer_wasi_generate_import_object_for_version` and * `wasmer_wasi_get_version`. It mimics the current API provided by `wasmer_wasi`, nothing fancy here. It's just a regular port to C/C++. Because `wasmer_wasi::get_wasi_version` returns an option, and in order to simplify the C/C++ API, `wasmer_wasi_get_version` can return `Version::Unknown` in case of an error. It's up to the user to check the version is valid (i.e. not unknown).
This commit is contained in:
parent
fdc3d5107a
commit
ca4a1b41a6
@ -1,6 +1,18 @@
|
||||
use super::*;
|
||||
use crate::get_slice_checked;
|
||||
use std::path::PathBuf;
|
||||
use std::{path::PathBuf, ptr, str};
|
||||
use wasmer_wasi as wasi;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum Version {
|
||||
/// Version cannot be detected or is unknown.
|
||||
Unknown,
|
||||
/// `wasi_unstable`.
|
||||
Snapshot0,
|
||||
/// `wasi_snapshot_preview1`.
|
||||
Snapshot1,
|
||||
}
|
||||
|
||||
/// Opens a directory that's visible to the WASI module as `alias` but
|
||||
/// is backed by the host file at `host_file_path`
|
||||
@ -14,9 +26,9 @@ pub struct wasmer_wasi_map_dir_entry_t {
|
||||
|
||||
impl wasmer_wasi_map_dir_entry_t {
|
||||
/// Converts the data into owned, Rust types
|
||||
pub unsafe fn as_tuple(&self) -> Result<(String, PathBuf), std::str::Utf8Error> {
|
||||
pub unsafe fn as_tuple(&self) -> Result<(String, PathBuf), str::Utf8Error> {
|
||||
let alias = self.alias.as_str()?.to_owned();
|
||||
let host_path = std::path::PathBuf::from(self.host_file_path.as_str()?);
|
||||
let host_path = PathBuf::from(self.host_file_path.as_str()?);
|
||||
|
||||
Ok((alias, host_path))
|
||||
}
|
||||
@ -44,21 +56,74 @@ pub unsafe extern "C" fn wasmer_wasi_generate_import_object(
|
||||
let mapped_dir_list = get_slice_checked(mapped_dirs, mapped_dirs_len as usize);
|
||||
|
||||
wasmer_wasi_generate_import_object_inner(
|
||||
Version::Snapshot1,
|
||||
arg_list,
|
||||
env_list,
|
||||
preopened_file_list,
|
||||
mapped_dir_list,
|
||||
)
|
||||
.unwrap_or(std::ptr::null_mut())
|
||||
.unwrap_or(ptr::null_mut())
|
||||
}
|
||||
|
||||
/// Creates a WASI import object.
|
||||
///
|
||||
/// This function is similar to `wasmer_wasi_generate_import_object`
|
||||
/// except that the first argument describes the WASI version.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_wasi_generate_import_object_for_version(
|
||||
version: Version,
|
||||
args: *const wasmer_byte_array,
|
||||
args_len: c_uint,
|
||||
envs: *const wasmer_byte_array,
|
||||
envs_len: c_uint,
|
||||
preopened_files: *const wasmer_byte_array,
|
||||
preopened_files_len: c_uint,
|
||||
mapped_dirs: *const wasmer_wasi_map_dir_entry_t,
|
||||
mapped_dirs_len: c_uint,
|
||||
) -> *mut wasmer_import_object_t {
|
||||
let arg_list = get_slice_checked(args, args_len as usize);
|
||||
let env_list = get_slice_checked(envs, envs_len as usize);
|
||||
let preopened_file_list = get_slice_checked(preopened_files, preopened_files_len as usize);
|
||||
let mapped_dir_list = get_slice_checked(mapped_dirs, mapped_dirs_len as usize);
|
||||
|
||||
wasmer_wasi_generate_import_object_inner(
|
||||
version,
|
||||
arg_list,
|
||||
env_list,
|
||||
preopened_file_list,
|
||||
mapped_dir_list,
|
||||
)
|
||||
.unwrap_or(ptr::null_mut())
|
||||
}
|
||||
|
||||
/// Find the version of WASI used by the module.
|
||||
///
|
||||
/// In case of error, the returned version is `Version::Unknown`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_wasi_get_version(module: *const wasmer_module_t) -> Version {
|
||||
if module.is_null() {
|
||||
return Version::Unknown;
|
||||
}
|
||||
|
||||
let module = &*(module as *const Module);
|
||||
|
||||
match wasi::get_wasi_version(module) {
|
||||
Some(version) => match version {
|
||||
wasi::WasiVersion::Snapshot0 => Version::Snapshot0,
|
||||
wasi::WasiVersion::Snapshot1 => Version::Snapshot1,
|
||||
},
|
||||
None => Version::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inner function that wraps error handling
|
||||
fn wasmer_wasi_generate_import_object_inner(
|
||||
version: Version,
|
||||
arg_list: &[wasmer_byte_array],
|
||||
env_list: &[wasmer_byte_array],
|
||||
preopened_file_list: &[wasmer_byte_array],
|
||||
mapped_dir_list: &[wasmer_wasi_map_dir_entry_t],
|
||||
) -> Result<*mut wasmer_import_object_t, std::str::Utf8Error> {
|
||||
) -> Result<*mut wasmer_import_object_t, str::Utf8Error> {
|
||||
let arg_vec = arg_list.iter().map(|arg| unsafe { arg.as_vec() }).collect();
|
||||
let env_vec = env_list
|
||||
.iter()
|
||||
@ -73,7 +138,14 @@ fn wasmer_wasi_generate_import_object_inner(
|
||||
.map(|entry| unsafe { entry.as_tuple() })
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let import_object = Box::new(wasmer_wasi::generate_import_object(
|
||||
let version = match version {
|
||||
Version::Snapshot0 => wasi::WasiVersion::Snapshot0,
|
||||
Version::Snapshot1 => wasi::WasiVersion::Snapshot1,
|
||||
_ => panic!(format!("Version {:?} is invalid.", version)),
|
||||
};
|
||||
|
||||
let import_object = Box::new(wasi::generate_import_object_for_version(
|
||||
version,
|
||||
arg_vec,
|
||||
env_vec,
|
||||
po_file_vec,
|
||||
@ -90,12 +162,7 @@ fn wasmer_wasi_generate_import_object_inner(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_wasi_generate_default_import_object() -> *mut wasmer_import_object_t
|
||||
{
|
||||
let import_object = Box::new(wasmer_wasi::generate_import_object(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
));
|
||||
let import_object = Box::new(wasi::generate_import_object(vec![], vec![], vec![], vec![]));
|
||||
|
||||
Box::into_raw(import_object) as *mut wasmer_import_object_t
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user