mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
introduce wit_fce
This commit is contained in:
parent
615c7d8423
commit
3d5be0e798
114
Cargo.lock
generated
114
Cargo.lock
generated
@ -15,8 +15,8 @@ dependencies = [
|
|||||||
"rustyline",
|
"rustyline",
|
||||||
"sha2",
|
"sha2",
|
||||||
"tokio",
|
"tokio",
|
||||||
"wasmer-runtime",
|
"wasmer-runtime 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
"wasmer-wasi",
|
"wasmer-wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -470,6 +470,10 @@ dependencies = [
|
|||||||
"failure",
|
"failure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "export_test"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -802,6 +806,10 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipfs_rpc"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@ -1951,8 +1959,34 @@ dependencies = [
|
|||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"wasmer-clif-fork-frontend",
|
"wasmer-clif-fork-frontend",
|
||||||
"wasmer-clif-fork-wasm",
|
"wasmer-clif-fork-wasm",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
"wasmer-win-exception-handler",
|
"wasmer-win-exception-handler 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
|
"wasmparser 0.51.4",
|
||||||
|
"winapi 0.3.8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-clif-backend"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "691ea323652d540a10722066dbf049936f4367bb22a96f8992a262a942a8b11b"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"cranelift-codegen",
|
||||||
|
"cranelift-entity",
|
||||||
|
"cranelift-native",
|
||||||
|
"libc",
|
||||||
|
"nix 0.15.0",
|
||||||
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"serde-bench",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_derive",
|
||||||
|
"target-lexicon",
|
||||||
|
"wasmer-clif-fork-frontend",
|
||||||
|
"wasmer-clif-fork-wasm",
|
||||||
|
"wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasmer-win-exception-handler 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmparser 0.51.4",
|
"wasmparser 0.51.4",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
@ -2002,8 +2036,22 @@ dependencies = [
|
|||||||
"memmap",
|
"memmap",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"wasmer-clif-backend",
|
"wasmer-clif-backend 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-runtime"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30259003902716aa4fb86fd66a2de555116adef545cbc5ab70afb74e74b44fc3"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"memmap",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"wasmer-clif-backend 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2034,6 +2082,35 @@ dependencies = [
|
|||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-runtime-core"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45d4253f097502423d8b19d54cb18745f61b984b9dbce32424cba7945cfef367"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"blake3",
|
||||||
|
"cc",
|
||||||
|
"digest",
|
||||||
|
"errno",
|
||||||
|
"hex",
|
||||||
|
"indexmap",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"nix 0.15.0",
|
||||||
|
"page_size",
|
||||||
|
"parking_lot",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"serde-bench",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_derive",
|
||||||
|
"smallvec",
|
||||||
|
"target-lexicon",
|
||||||
|
"wasmparser 0.51.4",
|
||||||
|
"winapi 0.3.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-wasi"
|
name = "wasmer-wasi"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
@ -2049,7 +2126,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
"time",
|
||||||
"typetag",
|
"typetag",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2060,7 +2137,19 @@ source = "git+http://github.com/fluencelabs/wasmer?branch=fluence#0575a7ed3f8742
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core 0.17.0 (git+http://github.com/fluencelabs/wasmer?branch=fluence)",
|
||||||
|
"winapi 0.3.8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-win-exception-handler"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf22ce6dc66d893099aac853d451bf9443fa8f5443f5bf4fc63f3aebd7b592b1"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2151,6 +2240,15 @@ dependencies = [
|
|||||||
"wasmer-interface-types",
|
"wasmer-interface-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit_fce"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"wasmer-interface-types",
|
||||||
|
"wasmer-runtime 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ws2_32-sys"
|
name = "ws2_32-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"fce",
|
"fce",
|
||||||
|
"wit_fce",
|
||||||
"wit_embedder",
|
"wit_embedder",
|
||||||
|
"wit_fce/examples/export_test",
|
||||||
|
"wit_fce/examples/ipfs_rpc",
|
||||||
]
|
]
|
||||||
|
10
wit_fce/Cargo.toml
Normal file
10
wit_fce/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "wit_fce"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasmer-runtime = "0.17.0"
|
||||||
|
wasmer-runtime-core = "0.17.0"
|
||||||
|
wasmer-interface-types = { git = "http://github.com/fluencelabs/interface-types" }
|
10
wit_fce/examples/export_test/Cargo.toml
Normal file
10
wit_fce/examples/export_test/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "export_test"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "export_test"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
crate-type = ["cdylib"]
|
44
wit_fce/examples/export_test/src/lib.rs
Normal file
44
wit_fce/examples/export_test/src/lib.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod mem;
|
||||||
|
mod result;
|
||||||
|
|
||||||
|
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn strlen(str_ptr: *mut u8, str_len: usize) -> usize {
|
||||||
|
let user_name = String::from_raw_parts(str_ptr, str_len, str_len);
|
||||||
|
user_name.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn greeting(user_name_ptr: *mut u8, user_name_size: usize) {
|
||||||
|
let user_name = String::from_raw_parts(user_name_ptr, user_name_size, user_name_size);
|
||||||
|
let user_name = format!("Hi, {}\n", user_name);
|
||||||
|
|
||||||
|
log_utf8_string(user_name.as_ptr() as i32, user_name.len() as i32);
|
||||||
|
|
||||||
|
*RESULT_PTR.get_mut() = user_name.as_ptr() as _;
|
||||||
|
*RESULT_SIZE.get_mut() = user_name.len();
|
||||||
|
std::mem::forget(user_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link(wasm_import_module = "logger")]
|
||||||
|
extern "C" {
|
||||||
|
// Writes a byte string of size bytes that starts from ptr to a logger
|
||||||
|
fn log_utf8_string(ptr: i32, size: i32);
|
||||||
|
}
|
33
wit_fce/examples/export_test/src/mem.rs
Normal file
33
wit_fce/examples/export_test/src/mem.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
/// Allocates memory area of specified size and returns its address.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn allocate(size: usize) -> NonNull<u8> {
|
||||||
|
let layout: Layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||||
|
NonNull::new_unchecked(global_alloc(layout))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deallocates memory area for provided memory pointer and size.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn deallocate(ptr: NonNull<u8>, size: usize) {
|
||||||
|
let layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||||
|
global_dealloc(ptr.as_ptr(), layout);
|
||||||
|
}
|
31
wit_fce/examples/export_test/src/result.rs
Normal file
31
wit_fce/examples/export_test/src/result.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
|
pub static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn get_result_ptr() -> usize {
|
||||||
|
*RESULT_PTR.get_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn get_result_size() -> usize {
|
||||||
|
*RESULT_SIZE.get_mut()
|
||||||
|
}
|
49
wit_fce/examples/export_test/wit
Normal file
49
wit_fce/examples/export_test/wit
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
;; allocate function
|
||||||
|
(@interface type (func (param i32) (result i32)))
|
||||||
|
|
||||||
|
;; deallocate function
|
||||||
|
(@interface type (func (param i32 i32)))
|
||||||
|
|
||||||
|
;; greeting function
|
||||||
|
(@interface type (func (param string) (result string)))
|
||||||
|
|
||||||
|
;; strlen function
|
||||||
|
(@interface type (func (param string) (result i32)))
|
||||||
|
|
||||||
|
;; result extractor functions
|
||||||
|
(@interface type (func (result i32)))
|
||||||
|
|
||||||
|
(@interface export "allocate" (func 0))
|
||||||
|
(@interface export "deallocate" (func 1))
|
||||||
|
(@interface export "greeting" (func 2))
|
||||||
|
(@interface export "strlen" (func 3))
|
||||||
|
(@interface export "get_result_size" (func 4))
|
||||||
|
(@interface export "get_result_ptr" (func 4))
|
||||||
|
|
||||||
|
(@interface func (type 2)
|
||||||
|
arg.get 0
|
||||||
|
string.size
|
||||||
|
call-core 0 ;; call allocate
|
||||||
|
arg.get 0
|
||||||
|
string.lower_memory
|
||||||
|
call-core 2 ;; call greeting
|
||||||
|
call-core 5 ;; call get_result_ptr
|
||||||
|
call-core 4 ;; call get_result_size
|
||||||
|
string.lift_memory
|
||||||
|
call-core 5 ;; call get_result_ptr
|
||||||
|
call-core 4 ;; call get_result_size
|
||||||
|
call-core 1 ;; call deallocate
|
||||||
|
)
|
||||||
|
|
||||||
|
(@interface func (type 3)
|
||||||
|
arg.get 0
|
||||||
|
string.size
|
||||||
|
call-core 0 ;; call allocate
|
||||||
|
arg.get 0
|
||||||
|
string.lower_memory
|
||||||
|
call-core 3 ;; call strlen
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Implementations
|
||||||
|
(@interface implement (func 0) (func 2))
|
||||||
|
(@interface implement (func 1) (func 3))
|
10
wit_fce/examples/ipfs_rpc/Cargo.toml
Normal file
10
wit_fce/examples/ipfs_rpc/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "ipfs_rpc"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "ipfs_rpc"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
crate-type = ["cdylib"]
|
47
wit_fce/examples/ipfs_rpc/src/lib.rs
Normal file
47
wit_fce/examples/ipfs_rpc/src/lib.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod mem;
|
||||||
|
mod result;
|
||||||
|
|
||||||
|
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn invoke(file_content_ptr: *mut u8, file_content_size: usize) {
|
||||||
|
put(file_content_ptr as _, file_content_size as _);
|
||||||
|
let hash = String::from_raw_parts(
|
||||||
|
*RESULT_PTR.get_mut(),
|
||||||
|
*RESULT_SIZE.get_mut(),
|
||||||
|
*RESULT_SIZE.get_mut(),
|
||||||
|
);
|
||||||
|
|
||||||
|
log_utf8_string(hash.as_ptr() as _, hash.len() as _);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link(wasm_import_module = "logger")]
|
||||||
|
extern "C" {
|
||||||
|
/// Writes a byte string of size bytes that starts from ptr to a logger.
|
||||||
|
fn log_utf8_string(ptr: i32, size: i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link(wasm_import_module = "node")]
|
||||||
|
extern "C" {
|
||||||
|
/// Put a file to ipfs, returns ipfs hash of the file.
|
||||||
|
fn put(ptr: i32, size: i32);
|
||||||
|
|
||||||
|
/// Get file from ipfs by hash.
|
||||||
|
fn get(ptr: i32, size: i32);
|
||||||
|
}
|
33
wit_fce/examples/ipfs_rpc/src/mem.rs
Normal file
33
wit_fce/examples/ipfs_rpc/src/mem.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
/// Allocates memory area of specified size and returns its address.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn allocate(size: usize) -> NonNull<u8> {
|
||||||
|
let layout: Layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||||
|
NonNull::new_unchecked(global_alloc(layout))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deallocates memory area for provided memory pointer and size.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn deallocate(ptr: NonNull<u8>, size: usize) {
|
||||||
|
let layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||||
|
global_dealloc(ptr.as_ptr(), layout);
|
||||||
|
}
|
41
wit_fce/examples/ipfs_rpc/src/result.rs
Normal file
41
wit_fce/examples/ipfs_rpc/src/result.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
|
pub static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn get_result_ptr() -> usize {
|
||||||
|
*RESULT_PTR.get_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn get_result_size() -> usize {
|
||||||
|
*RESULT_SIZE.get_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn set_result_ptr(ptr: usize) {
|
||||||
|
*RESULT_PTR.get_mut() = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe fn set_result_size(ptr: usize) {
|
||||||
|
*RESULT_SIZE.get_mut() = size;
|
||||||
|
}
|
46
wit_fce/examples/ipfs_rpc/wit
Normal file
46
wit_fce/examples/ipfs_rpc/wit
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
;; allocate function type
|
||||||
|
(@interface type (func (param i32) (result i32)))
|
||||||
|
|
||||||
|
;; deallocate function
|
||||||
|
(@interface type (func (param i32 i32)))
|
||||||
|
|
||||||
|
;; invoke function
|
||||||
|
(@interface type (func (param string) (result string)))
|
||||||
|
|
||||||
|
;; result extractor functions
|
||||||
|
(@interface type (func (result i32)))
|
||||||
|
|
||||||
|
;; result setter functions
|
||||||
|
(@interface type (func (param i32)))
|
||||||
|
|
||||||
|
;; import ipfs put/get function
|
||||||
|
(@interface type (func (param string) (param string)))
|
||||||
|
|
||||||
|
(@interface export "allocate" (func 0))
|
||||||
|
(@interface export "deallocate" (func 1))
|
||||||
|
(@interface export "invoke" (func 2))
|
||||||
|
(@interface export "get_result_size" (func 3))
|
||||||
|
(@interface export "get_result_ptr" (func 3))
|
||||||
|
(@interface export "set_result_size" (func 4))
|
||||||
|
(@interface export "set_result_ptr" (func 4))
|
||||||
|
|
||||||
|
(@interface import "node" "get" (func 5))
|
||||||
|
(@interface import "node" "put" (func 5))
|
||||||
|
|
||||||
|
(@interface func (type 2)
|
||||||
|
arg.get 0
|
||||||
|
string.size
|
||||||
|
call-core 0 ;; call allocate
|
||||||
|
arg.get 0
|
||||||
|
string.lower_memory
|
||||||
|
call-core 2 ;; call greeting
|
||||||
|
call-core 3 ;; call get_result_size
|
||||||
|
call-core 4 ;; call get_result_ptr
|
||||||
|
string.lift_memory
|
||||||
|
call-core 3 ;; call get_result_size
|
||||||
|
call-core 4 ;; call get_result_ptr
|
||||||
|
call-core 1 ;; call deallocate
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Implementations
|
||||||
|
(@interface implement (func 0) (func 2))
|
141
wit_fce/src/instance/errors.rs
Normal file
141
wit_fce/src/instance/errors.rs
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
use wasmer_interface_types::errors::InstructionError;
|
||||||
|
use wasmer_runtime::error::{
|
||||||
|
CallError, CompileError, CreationError, Error as WasmerError, ResolveError, RuntimeError,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
|
pub enum WITFCEError {
|
||||||
|
/// Errors for I/O errors raising while opening a file.
|
||||||
|
IOError(String),
|
||||||
|
|
||||||
|
/// This error type is produced by Wasmer during resolving a Wasm function.
|
||||||
|
WasmerResolveError(String),
|
||||||
|
|
||||||
|
/// Error related to calling a main Wasm module.
|
||||||
|
WasmerInvokeError(String),
|
||||||
|
|
||||||
|
/// Error that raises during compilation Wasm code by Wasmer.
|
||||||
|
WasmerCreationError(String),
|
||||||
|
|
||||||
|
/// Error that raises during creation of some Wasm objects (like table and memory) by Wasmer.
|
||||||
|
WasmerCompileError(String),
|
||||||
|
|
||||||
|
/// Error that raises on the preparation step.
|
||||||
|
PrepareError(String),
|
||||||
|
|
||||||
|
/// Indicates that there is already a module with such name.
|
||||||
|
NonUniqueModuleName,
|
||||||
|
|
||||||
|
/// Returns when there is no module with such name.
|
||||||
|
NoSuchFunction,
|
||||||
|
|
||||||
|
/// Returns when there is no module with such name.
|
||||||
|
NoSuchModule,
|
||||||
|
|
||||||
|
/// WIT section is absent.
|
||||||
|
NoWITSection,
|
||||||
|
|
||||||
|
/// Multiple WIT sections.
|
||||||
|
MultipleWITSections,
|
||||||
|
|
||||||
|
/// WIT section remainder isn't empty.
|
||||||
|
WITRemainderNotEmpty,
|
||||||
|
|
||||||
|
/// An error occurred while parsing WIT section.
|
||||||
|
WITParseError,
|
||||||
|
|
||||||
|
/// Indicates that modules currently in use and couldn't be deleted.
|
||||||
|
ModuleInUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for WITFCEError {}
|
||||||
|
|
||||||
|
impl std::fmt::Display for WITFCEError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
match self {
|
||||||
|
WITFCEError::IOError(msg) => write!(f, "IOError: {}", msg),
|
||||||
|
WITFCEError::WasmerResolveError(msg) => write!(f, "WasmerResolveError: {}", msg),
|
||||||
|
WITFCEError::WasmerInvokeError(msg) => write!(f, "WasmerInvokeError: {}", msg),
|
||||||
|
WITFCEError::WasmerCompileError(msg) => write!(f, "WasmerCompileError: {}", msg),
|
||||||
|
WITFCEError::WasmerCreationError(msg) => write!(f, "WasmerCreationError: {}", msg),
|
||||||
|
WITFCEError::PrepareError(msg) => {
|
||||||
|
write!(f, "Prepare error: {}, probably module is mailformed", msg)
|
||||||
|
}
|
||||||
|
WITFCEError::NonUniqueModuleName => write!(f, "FCE already has module with such name"),
|
||||||
|
WITFCEError::NoSuchModule => write!(f, "FCE doesn't have a module with such name"),
|
||||||
|
WITFCEError::ModuleInUse => {
|
||||||
|
write!(f, "Module is used by other modules and couldn't be deleted")
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CreationError> for WITFCEError {
|
||||||
|
fn from(err: CreationError) -> Self {
|
||||||
|
WITFCEError::WasmerCreationError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CompileError> for WITFCEError {
|
||||||
|
fn from(err: CompileError) -> Self {
|
||||||
|
WITFCEError::WasmerCompileError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CallError> for WITFCEError {
|
||||||
|
fn from(err: CallError) -> Self {
|
||||||
|
match err {
|
||||||
|
CallError::Resolve(err) => WITFCEError::WasmerResolveError(format!("{}", err)),
|
||||||
|
CallError::Runtime(err) => WITFCEError::WasmerInvokeError(format!("{}", err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ResolveError> for WITFCEError {
|
||||||
|
fn from(err: ResolveError) -> Self {
|
||||||
|
WITFCEError::WasmerResolveError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RuntimeError> for WITFCEError {
|
||||||
|
fn from(err: RuntimeError) -> Self {
|
||||||
|
WITFCEError::WasmerInvokeError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WasmerError> for WITFCEError {
|
||||||
|
fn from(err: WasmerError) -> Self {
|
||||||
|
WITFCEError::WasmerInvokeError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for WITFCEError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
WITFCEError::IOError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InstructionError> for WITFCEError {
|
||||||
|
fn from(err: InstructionError) -> Self {
|
||||||
|
WITFCEError::WasmerInvokeError(format!("{}", err))
|
||||||
|
}
|
||||||
|
}
|
59
wit_fce/src/instance/exports.rs
Normal file
59
wit_fce/src/instance/exports.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use wasmer_interface_types::interpreter::wasm;
|
||||||
|
use wasmer_interface_types::{types::InterfaceType, values::InterfaceValue};
|
||||||
|
|
||||||
|
// In current implementation export simply does nothing.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct WITExport {
|
||||||
|
pub(crate) inputs: Vec<InterfaceType>,
|
||||||
|
pub(crate) outputs: Vec<InterfaceType>,
|
||||||
|
pub(crate) function: fn(arguments: &[InterfaceValue]) -> Result<Vec<InterfaceValue>, ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WITExport {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inputs: vec![],
|
||||||
|
outputs: vec![],
|
||||||
|
function: |_| -> _ { Ok(vec![]) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm::structures::Export for WITExport {
|
||||||
|
fn inputs_cardinality(&self) -> usize {
|
||||||
|
self.inputs.len() as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs_cardinality(&self) -> usize {
|
||||||
|
self.outputs.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(&self) -> &[InterfaceType] {
|
||||||
|
&self.inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs(&self) -> &[InterfaceType] {
|
||||||
|
&self.outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, arguments: &[InterfaceValue]) -> Result<Vec<InterfaceValue>, ()> {
|
||||||
|
(self.function)(arguments)
|
||||||
|
}
|
||||||
|
}
|
86
wit_fce/src/instance/locals_imports.rs
Normal file
86
wit_fce/src/instance/locals_imports.rs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::instance::errors::WITFCEError;
|
||||||
|
use wasmer_interface_types::interpreter::wasm;
|
||||||
|
use wasmer_interface_types::{types::InterfaceType, values::InterfaceValue};
|
||||||
|
use wasmer_runtime_core::instance::DynFunc;
|
||||||
|
use wasmer_runtime_core::types::Value;
|
||||||
|
|
||||||
|
pub(crate) struct WITLocalImport {
|
||||||
|
inner: DynFunc<'static>,
|
||||||
|
inputs: Vec<InterfaceType>,
|
||||||
|
outputs: Vec<InterfaceType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WITLocalImport {
|
||||||
|
pub fn new(dyn_func: DynFunc<'static>) -> Result<Self, WITFCEError> {
|
||||||
|
use super::wtype_to_itype;
|
||||||
|
|
||||||
|
let signature = dyn_func.signature();
|
||||||
|
let inputs = signature
|
||||||
|
.params()
|
||||||
|
.iter()
|
||||||
|
.map(wtype_to_itype)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let outputs = signature
|
||||||
|
.returns()
|
||||||
|
.iter()
|
||||||
|
.map(wtype_to_itype)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
inner: dyn_func,
|
||||||
|
inputs,
|
||||||
|
outputs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for WITLocalImport {
|
||||||
|
type Target = DynFunc<'static>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm::structures::LocalImport for WITLocalImport {
|
||||||
|
fn inputs_cardinality(&self) -> usize {
|
||||||
|
self.inputs.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs_cardinality(&self) -> usize {
|
||||||
|
self.outputs.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(&self) -> &[InterfaceType] {
|
||||||
|
&self.inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs(&self) -> &[InterfaceType] {
|
||||||
|
&self.outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, arguments: &[InterfaceValue]) -> Result<Vec<InterfaceValue>, ()> {
|
||||||
|
use super::{ival_to_wval, wval_to_ival};
|
||||||
|
|
||||||
|
self.inner
|
||||||
|
.call(&arguments.iter().map(ival_to_wval).collect::<Vec<Value>>())
|
||||||
|
.map(|results| results.iter().map(wval_to_ival).collect())
|
||||||
|
.map_err(|_| ())
|
||||||
|
}
|
||||||
|
}
|
49
wit_fce/src/instance/memory.rs
Normal file
49
wit_fce/src/instance/memory.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use wasmer_interface_types::interpreter::wasm;
|
||||||
|
use wasmer_runtime_core::memory::{Memory, MemoryView};
|
||||||
|
|
||||||
|
pub struct WITMemoryView<'a>(pub MemoryView<'a, u8>);
|
||||||
|
impl<'a> std::ops::Deref for WITMemoryView<'a> {
|
||||||
|
type Target = [std::cell::Cell<u8>];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.0.deref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WITMemory(pub Memory);
|
||||||
|
impl std::ops::Deref for WITMemory {
|
||||||
|
type Target = Memory;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm::structures::MemoryView for WITMemoryView<'_> {}
|
||||||
|
|
||||||
|
impl<'a> wasm::structures::Memory<WITMemoryView<'a>> for WITMemory {
|
||||||
|
fn view(&self) -> WITMemoryView<'a> {
|
||||||
|
use wasmer_runtime_core::vm::LocalMemory;
|
||||||
|
|
||||||
|
let LocalMemory { base, .. } = unsafe { *self.0.vm_local_memory() };
|
||||||
|
let length = self.0.size().bytes().0 / std::mem::size_of::<u8>();
|
||||||
|
|
||||||
|
unsafe { WITMemoryView(MemoryView::new(base as _, length as u32)) }
|
||||||
|
}
|
||||||
|
}
|
56
wit_fce/src/instance/mod.rs
Normal file
56
wit_fce/src/instance/mod.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub mod errors;
|
||||||
|
pub mod exports;
|
||||||
|
pub mod locals_imports;
|
||||||
|
pub mod memory;
|
||||||
|
pub mod wit_instance;
|
||||||
|
pub mod wit_module;
|
||||||
|
|
||||||
|
use wasmer_interface_types::types::InterfaceType as IType;
|
||||||
|
use wasmer_interface_types::values::InterfaceValue as IValue;
|
||||||
|
use wasmer_runtime_core::types::{Type as WType, Value as WValue};
|
||||||
|
|
||||||
|
pub fn wtype_to_itype(ty: &WType) -> IType {
|
||||||
|
match ty {
|
||||||
|
WType::I32 => IType::I32,
|
||||||
|
WType::I64 => IType::I64,
|
||||||
|
WType::F32 => IType::F32,
|
||||||
|
WType::F64 => IType::F64,
|
||||||
|
WType::V128 => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ival_to_wval(value: &IValue) -> WValue {
|
||||||
|
match value {
|
||||||
|
IValue::I32(v) => WValue::I32(*v),
|
||||||
|
IValue::I64(v) => WValue::I64(*v),
|
||||||
|
IValue::F32(v) => WValue::F32(*v),
|
||||||
|
IValue::F64(v) => WValue::F64(*v),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wval_to_ival(value: &WValue) -> IValue {
|
||||||
|
match value {
|
||||||
|
WValue::I32(v) => IValue::I32(*v),
|
||||||
|
WValue::I64(v) => IValue::I64(*v),
|
||||||
|
WValue::F32(v) => IValue::F32(*v),
|
||||||
|
WValue::F64(v) => IValue::F64(*v),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
119
wit_fce/src/instance/wit_instance.rs
Normal file
119
wit_fce/src/instance/wit_instance.rs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::instance::errors::WITFCEError;
|
||||||
|
use crate::instance::exports::WITExport;
|
||||||
|
use crate::instance::locals_imports::WITLocalImport;
|
||||||
|
use crate::instance::memory::{WITMemory, WITMemoryView};
|
||||||
|
|
||||||
|
use wasmer_interface_types::interpreter::wasm;
|
||||||
|
use wasmer_runtime_core::Instance as WasmerInstance;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use wasmer_interface_types::ast::Interfaces;
|
||||||
|
use wasmer_interface_types::ast::Type;
|
||||||
|
use wasmer_interface_types::interpreter::wasm::structures::{LocalImportIndex, TypedIndex};
|
||||||
|
|
||||||
|
pub struct WITInstance {
|
||||||
|
// represent all import and export functions
|
||||||
|
funcs: HashMap<usize, WITLocalImport>,
|
||||||
|
memories: Vec<WITMemory>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WITInstance {
|
||||||
|
pub fn new(
|
||||||
|
wasmer_instance: &WasmerInstance,
|
||||||
|
interfaces: &Interfaces,
|
||||||
|
) -> Result<Self, WITFCEError> {
|
||||||
|
let funcs = Self::extract_funcs(&wasmer_instance, interfaces)?;
|
||||||
|
let memories = Self::extract_memories(&wasmer_instance);
|
||||||
|
|
||||||
|
Ok(Self { funcs, memories })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_funcs(
|
||||||
|
wasmer_instance: &WasmerInstance,
|
||||||
|
interfaces: &Interfaces,
|
||||||
|
) -> Result<HashMap<usize, WITLocalImport>, WITFCEError> {
|
||||||
|
use wasmer_runtime_core::DynFunc;
|
||||||
|
let module_exports = &wasmer_instance.exports;
|
||||||
|
|
||||||
|
interfaces
|
||||||
|
.exports
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(export_id, export)| {
|
||||||
|
let export_func = module_exports.get(export.name)?;
|
||||||
|
unsafe {
|
||||||
|
// TODO: refactor this with new Wasmer API when it is ready
|
||||||
|
// here it is safe because dyn func is never lives WITInstance
|
||||||
|
let export_func =
|
||||||
|
std::mem::transmute::<DynFunc<'_>, DynFunc<'static>>(export_func);
|
||||||
|
Ok((export_id, WITLocalImport::new(export_func)?))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_memories(wasmer_instance: &WasmerInstance) -> Vec<WITMemory> {
|
||||||
|
use wasmer_runtime_core::export::Export::Memory;
|
||||||
|
|
||||||
|
let mut memories = wasmer_instance
|
||||||
|
.exports()
|
||||||
|
.filter_map(|(_, export)| match export {
|
||||||
|
Memory(memory) => Some(WITMemory(memory)),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if let Some(Memory(memory)) = wasmer_instance
|
||||||
|
.import_object
|
||||||
|
.maybe_with_namespace("env", |env| env.get_export("memory"))
|
||||||
|
{
|
||||||
|
memories.push(WITMemory(memory));
|
||||||
|
}
|
||||||
|
|
||||||
|
memories
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'instance> wasm::structures::Instance<WITExport, WITLocalImport, WITMemory, WITMemoryView<'_>>
|
||||||
|
for WITInstance
|
||||||
|
{
|
||||||
|
fn export(&self, _export_name: &str) -> Option<&WITExport> {
|
||||||
|
// exports aren't needed for this version of WIT
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_or_import<I: TypedIndex + LocalImportIndex>(
|
||||||
|
&mut self,
|
||||||
|
index: I,
|
||||||
|
) -> Option<&WITLocalImport> {
|
||||||
|
self.funcs.get(&index.index())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memory(&self, index: usize) -> Option<&WITMemory> {
|
||||||
|
if index >= self.memories.len() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(&self.memories[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wit_type(&self, _index: u32) -> Option<&Type> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
140
wit_fce/src/instance/wit_module.rs
Normal file
140
wit_fce/src/instance/wit_module.rs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::instance::errors::WITFCEError;
|
||||||
|
use crate::instance::exports::WITExport;
|
||||||
|
use crate::instance::locals_imports::WITLocalImport;
|
||||||
|
use crate::instance::memory::{WITMemory, WITMemoryView};
|
||||||
|
use crate::instance::wit_instance::WITInstance;
|
||||||
|
|
||||||
|
use wasmer_interface_types as wit;
|
||||||
|
use wasmer_interface_types::interpreter::Interpreter;
|
||||||
|
use wasmer_interface_types::values::InterfaceValue;
|
||||||
|
use wasmer_runtime::{compile, ImportObject};
|
||||||
|
use wasmer_runtime_core::Instance as WasmerInstance;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use wasmer_interface_types::interpreter::stack::Stackable;
|
||||||
|
|
||||||
|
const WIT_SECTION_NAME: &str = "interface-types";
|
||||||
|
|
||||||
|
pub struct WITModule {
|
||||||
|
instance: WasmerInstance,
|
||||||
|
wit_instance: WITInstance,
|
||||||
|
exports: HashMap<
|
||||||
|
String,
|
||||||
|
Interpreter<WITInstance, WITExport, WITLocalImport, WITMemory, WITMemoryView<'static>>,
|
||||||
|
>,
|
||||||
|
import_object: ImportObject,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WITModule {
|
||||||
|
pub fn new(wasm_bytes: &[u8], imports: &ImportObject) -> Result<Self, WITFCEError> {
|
||||||
|
let wasmer_instance = compile(&wasm_bytes)?.instantiate(imports)?;
|
||||||
|
|
||||||
|
let wit_sections = wasmer_instance
|
||||||
|
.module
|
||||||
|
.info
|
||||||
|
.custom_sections
|
||||||
|
.get(WIT_SECTION_NAME)
|
||||||
|
.ok_or_else(|| WITFCEError::NoWITSection)?;
|
||||||
|
|
||||||
|
if wit_sections.len() > 1 {
|
||||||
|
return Err(WITFCEError::MultipleWITSections);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (remainder, interfaces) = wit::decoders::binary::parse::<()>(&wit_sections[0])
|
||||||
|
.map_err(|_e| WITFCEError::WITParseError)?;
|
||||||
|
if remainder.len() > 1 {
|
||||||
|
return Err(WITFCEError::WITRemainderNotEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
let wit_instance = WITInstance::new(&wasmer_instance, &interfaces)?;
|
||||||
|
|
||||||
|
let wit_export_names = interfaces
|
||||||
|
.imports
|
||||||
|
.iter()
|
||||||
|
.map(|export| (export.function_type, export.name.to_string()))
|
||||||
|
.collect::<HashMap<u32, String>>();
|
||||||
|
|
||||||
|
let callable_exports = interfaces
|
||||||
|
.adapters
|
||||||
|
.iter()
|
||||||
|
.map(|adapter| {
|
||||||
|
let export_func_name = wit_export_names
|
||||||
|
.get(&adapter.function_type)
|
||||||
|
.ok_or_else(|| WITFCEError::NoSuchFunction)?;
|
||||||
|
let instructions = &adapter.instructions;
|
||||||
|
|
||||||
|
let interpreter: Interpreter<
|
||||||
|
WITInstance,
|
||||||
|
WITExport,
|
||||||
|
WITLocalImport,
|
||||||
|
WITMemory,
|
||||||
|
WITMemoryView<'static>,
|
||||||
|
> = instructions.try_into().unwrap();
|
||||||
|
|
||||||
|
Ok((export_func_name.to_owned(), interpreter))
|
||||||
|
})
|
||||||
|
.collect::<Result<HashMap<_, _>, WITFCEError>>()?;
|
||||||
|
|
||||||
|
|
||||||
|
let callable_imports = interfaces
|
||||||
|
.adapters
|
||||||
|
.iter()
|
||||||
|
.map(|adapter| {
|
||||||
|
let import_func_name = wit_export_names
|
||||||
|
.get(&adapter.function_type)
|
||||||
|
.ok_or_else(|| WITFCEError::NoSuchFunction)?;
|
||||||
|
let instructions = &adapter.instructions;
|
||||||
|
|
||||||
|
let interpreter: Interpreter<
|
||||||
|
WITInstance,
|
||||||
|
WITExport,
|
||||||
|
WITLocalImport,
|
||||||
|
WITMemory,
|
||||||
|
WITMemoryView<'static>,
|
||||||
|
> = instructions.try_into().unwrap();
|
||||||
|
|
||||||
|
Ok((export_func_name.to_owned(), interpreter))
|
||||||
|
})
|
||||||
|
.collect::<Result<HashMap<_, _>, WITFCEError>>()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
instance: wasmer_instance,
|
||||||
|
wit_instance,
|
||||||
|
exports: callable_exports,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(
|
||||||
|
&mut self,
|
||||||
|
function_name: &str,
|
||||||
|
args: &[InterfaceValue],
|
||||||
|
) -> Result<Vec<InterfaceValue>, WITFCEError> {
|
||||||
|
match self.exports.get(function_name) {
|
||||||
|
Some(func) => {
|
||||||
|
let result = func
|
||||||
|
.run(args, &mut self.wit_instance)?
|
||||||
|
.as_slice()
|
||||||
|
.to_owned();
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
None => Err(WITFCEError::NoSuchFunction),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
wit_fce/src/main.rs
Normal file
60
wit_fce/src/main.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod instance;
|
||||||
|
|
||||||
|
use crate::instance::wit_module::WITModule;
|
||||||
|
|
||||||
|
use wasmer_interface_types::values::InterfaceValue;
|
||||||
|
use wasmer_runtime::{func, imports, ImportObject};
|
||||||
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
|
|
||||||
|
const FILE_NAME: &str =
|
||||||
|
"/Users/mike/dev/work/fluence/wasm/fce/target/wasm32-unknown-unknown/release/export_test_wit.wasm";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let wasm_bytes = std::fs::read(FILE_NAME).unwrap();
|
||||||
|
let logger_imports = imports! {
|
||||||
|
"logger" => {
|
||||||
|
"log_utf8_string" => func!(logger_log_utf8_string),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mut import_object = ImportObject::new();
|
||||||
|
import_object.extend(logger_imports);
|
||||||
|
|
||||||
|
let mut module =
|
||||||
|
WITModule::new(&wasm_bytes, &import_object).expect("module successfully created");
|
||||||
|
|
||||||
|
let result1 = module
|
||||||
|
.call("strlen", &[InterfaceValue::String("aaaaaa".to_string())])
|
||||||
|
.unwrap();
|
||||||
|
let result2 = module
|
||||||
|
.call("greeting", &[InterfaceValue::String("Mike".to_string())])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("stack state {:?}", result1);
|
||||||
|
println!("stack state {:?}", result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logger_log_utf8_string(ctx: &mut Ctx, offset: i32, size: i32) {
|
||||||
|
use wasmer_runtime_core::memory::ptr::{Array, WasmPtr};
|
||||||
|
|
||||||
|
let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _);
|
||||||
|
match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) {
|
||||||
|
Some(msg) => print!("{}", msg),
|
||||||
|
None => print!("fce logger: incorrect UTF8 string's been supplied to logger"),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user