Skip to content

Commit

Permalink
Try #1030:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Dec 3, 2019
2 parents 183beb7 + cbf29ee commit 80a86b4
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 53 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## **[Unreleased]**

- [#1030](https://github.com/wasmerio/wasmer/pull/1030) Ability to generate `ImportObject` for a specific version WASI version with the C API.
- [#1028](https://github.com/wasmerio/wasmer/pull/1028) Fix `get_wasi_version` when a module has multiple import namespaces.
- [#1006](https://github.com/wasmerio/wasmer/pull/1006) Fix minor panic issue when `wasmer::compile_with` called with llvm backend
- [#1009](https://github.com/wasmerio/wasmer/pull/1009) Enable LLVM verifier for all tests, add new llvm-backend-tests crate.
- [#1022](https://github.com/wasmerio/wasmer/pull/1022) Add caching support for Singlepass backend.
Expand Down
2 changes: 1 addition & 1 deletion lib/runtime-c-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ rebuild in release mode for the tests to see the changes.
The tests can be run via `cargo test`, such as:

```sh
$ cargo test -- --nocapture
$ cargo test --release -- --nocapture
```

To run tests manually, enter the `lib/runtime-c-api/tests` directory
Expand Down
91 changes: 79 additions & 12 deletions lib/runtime-c-api/src/import/wasi.rs
Original file line number Diff line number Diff line change
@@ -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`
Expand All @@ -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))
}
Expand Down Expand Up @@ -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()
Expand All @@ -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,
Expand All @@ -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
}
8 changes: 4 additions & 4 deletions lib/runtime-c-api/tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ compile_commands.json
CTestTestfile.cmake
_deps
rust-build
test-context
test-exported-memory
test-exports
test-globals
test-import-function
test-import-object
test-imports
test-instantiate
test-memory
test-module
test-module-exports
test-module-import-instantiate
test-module-imports
test-module-serialize
test-tables
test-validate
test-context
test-module-import-instantiate
test-wasi-import-object

test-wasi-import-object
6 changes: 3 additions & 3 deletions lib/runtime-c-api/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ add_executable(test-context test-context.c)
add_executable(test-module-import-instantiate test-module-import-instantiate.c)

if (DEFINED WASI_TESTS)
add_executable(test-wasi-import-object test-wasi-import-object.c)
add_executable(test-wasi-import-object test-wasi-import-object.c)
endif()

find_library(
WASMER_LIB NAMES libwasmer_runtime_c_api.dylib libwasmer_runtime_c_api.so wasmer_runtime_c_api.dll
PATHS ${CMAKE_SOURCE_DIR}/../../../target/release/
WASMER_LIB NAMES libwasmer_runtime_c_api.dylib libwasmer_runtime_c_api.so wasmer_runtime_c_api.dll
PATHS ${CMAKE_SOURCE_DIR}/../../../target/release/
)

if(NOT WASMER_LIB)
Expand Down
44 changes: 27 additions & 17 deletions lib/runtime-c-api/tests/test-wasi-import-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ void print_wasmer_error()

// helper function to print byte array to stdout
void print_byte_array(wasmer_byte_array *arr) {
for (int i = 0; i < arr->bytes_len; ++i) {
putchar(arr->bytes[i]);
}
for (int i = 0; i < arr->bytes_len; ++i) {
putchar(arr->bytes[i]);
}
}

int main()
Expand Down Expand Up @@ -164,20 +164,7 @@ int main()
};
int mapped_dir_len = sizeof(mapped_dirs) / sizeof(mapped_dirs[0]);

// Create the WASI import object
wasmer_import_object_t *import_object =
wasmer_wasi_generate_import_object(args, wasi_argc,
envs, wasi_env_len,
NULL, 0,
mapped_dirs, mapped_dir_len);

// Create our imports
wasmer_import_t imports[] = {func_import, global_import, memory_import, table_import};
int imports_len = sizeof(imports) / sizeof(imports[0]);
// Add our imports to the import object
wasmer_import_object_extend(import_object, imports, imports_len);

// Read the wasm file bytes
// Read the Wasm file bytes.
FILE *file = fopen("assets/extended_wasi.wasm", "r");
assert(file);
fseek(file, 0, SEEK_END);
Expand All @@ -191,16 +178,39 @@ int main()
// Compile the WebAssembly module
wasmer_result_t compile_result = wasmer_compile(&module, bytes, len);
printf("Compile result: %d\n", compile_result);

if (compile_result != WASMER_OK)
{
print_wasmer_error();
}

assert(compile_result == WASMER_OK);

// Detect the WASI version if any. This step is not mandatory, we
// use it to test the WASI version API.
Version wasi_version = wasmer_wasi_get_version(module);

printf("WASI version: %d\n", wasi_version);

// Create the WASI import object
wasmer_import_object_t *import_object =
wasmer_wasi_generate_import_object_for_version(wasi_version,
args, wasi_argc,
envs, wasi_env_len,
NULL, 0,
mapped_dirs, mapped_dir_len);

// Create our imports
wasmer_import_t imports[] = {func_import, global_import, memory_import, table_import};
int imports_len = sizeof(imports) / sizeof(imports[0]);
// Add our imports to the import object
wasmer_import_object_extend(import_object, imports, imports_len);

// Instantiatoe the module with our import_object
wasmer_instance_t *instance = NULL;
wasmer_result_t instantiate_result = wasmer_module_import_instantiate(&instance, module, import_object);
printf("Instantiate result: %d\n", instantiate_result);

if (instantiate_result != WASMER_OK)
{
print_wasmer_error();
Expand Down
39 changes: 39 additions & 0 deletions lib/runtime-c-api/wasmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@
#include <stdint.h>
#include <stdlib.h>

enum Version {
/**
* Version cannot be detected or is unknown.
*/
Unknown,
/**
* `wasi_unstable`.
*/
Snapshot0,
/**
* `wasi_snapshot_preview1`.
*/
Snapshot1,
};
typedef uint8_t Version;

/**
* List of export/import kinds.
*/
Expand Down Expand Up @@ -890,4 +906,27 @@ wasmer_import_object_t *wasmer_wasi_generate_import_object(const wasmer_byte_arr
const wasmer_wasi_map_dir_entry_t *mapped_dirs,
unsigned int mapped_dirs_len);

/**
* Creates a WASI import object.
*
* This function is similar to `wasmer_wasi_generate_import_object`
* except that the first argument describes the WASI version.
*/
wasmer_import_object_t *wasmer_wasi_generate_import_object_for_version(Version version,
const wasmer_byte_array *args,
unsigned int args_len,
const wasmer_byte_array *envs,
unsigned int envs_len,
const wasmer_byte_array *preopened_files,
unsigned int preopened_files_len,
const wasmer_wasi_map_dir_entry_t *mapped_dirs,
unsigned int mapped_dirs_len);

/**
* Find the version of WASI used by the module.
*
* In case of error, the returned version is `Version::Unknown`.
*/
Version wasmer_wasi_get_version(const wasmer_module_t *module);

#endif /* WASMER_H */
28 changes: 28 additions & 0 deletions lib/runtime-c-api/wasmer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
#include <cstdlib>
#include <new>

enum class Version : uint8_t {
/// Version cannot be detected or is unknown.
Unknown,
/// `wasi_unstable`.
Snapshot0,
/// `wasi_snapshot_preview1`.
Snapshot1,
};

/// List of export/import kinds.
enum class wasmer_import_export_kind : uint32_t {
WASM_FUNCTION = 0,
Expand Down Expand Up @@ -702,6 +711,25 @@ wasmer_import_object_t *wasmer_wasi_generate_import_object(const wasmer_byte_arr
const wasmer_wasi_map_dir_entry_t *mapped_dirs,
unsigned int mapped_dirs_len);

/// Creates a WASI import object.
///
/// This function is similar to `wasmer_wasi_generate_import_object`
/// except that the first argument describes the WASI version.
wasmer_import_object_t *wasmer_wasi_generate_import_object_for_version(Version version,
const wasmer_byte_array *args,
unsigned int args_len,
const wasmer_byte_array *envs,
unsigned int envs_len,
const wasmer_byte_array *preopened_files,
unsigned int preopened_files_len,
const wasmer_wasi_map_dir_entry_t *mapped_dirs,
unsigned int mapped_dirs_len);

/// Find the version of WASI used by the module.
///
/// In case of error, the returned version is `Version::Unknown`.
Version wasmer_wasi_get_version(const wasmer_module_t *module);

} // extern "C"

#endif // WASMER_H
Loading

0 comments on commit 80a86b4

Please sign in to comment.