mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 06:45:32 +00:00
Move to the new sdk (#8)
This commit is contained in:
parent
37ce9dafb3
commit
e9ef12b6b4
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,6 +2,9 @@ target/
|
||||
**/*.rs.bk
|
||||
.idea
|
||||
|
||||
# MacOS misc file
|
||||
*.DS_Store
|
||||
|
||||
# Wasm files
|
||||
*.wasm
|
||||
*.wat
|
||||
|
73
Cargo.lock
generated
73
Cargo.lock
generated
@ -11,9 +11,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc9a9dd069569f212bc4330af9f17c4afb5e8ce185e83dbb14f1349dda18b10"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
@ -91,9 +91,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "423897d97e11b810c9da22458400b28ec866991c711409073662eb34dc44bfff"
|
||||
checksum = "59f88a20f7dc23e3896bcbd85add056543c87215de721468b90e0c85d5a9f365"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
@ -101,7 +101,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
"crypto-mac",
|
||||
"digest",
|
||||
"digest 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -268,11 +268,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.2",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
@ -292,7 +292,16 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array 0.14.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -403,7 +412,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fluence"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#9775ca6144b67b96aa70ad8020336cd264063316"
|
||||
dependencies = [
|
||||
"fluence-sdk-macro",
|
||||
"fluence-sdk-main",
|
||||
@ -428,7 +437,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fluence-sdk-macro"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#9775ca6144b67b96aa70ad8020336cd264063316"
|
||||
dependencies = [
|
||||
"fluence-sdk-wit",
|
||||
]
|
||||
@ -436,7 +445,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#9775ca6144b67b96aa70ad8020336cd264063316"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@ -444,7 +453,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fluence-sdk-wit"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#9775ca6144b67b96aa70ad8020336cd264063316"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -479,6 +488,16 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
@ -521,7 +540,8 @@ checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||
name = "greeting"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fluence",
|
||||
"anyhow",
|
||||
"fluence-faas",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -898,9 +918,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
@ -1014,9 +1034,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
@ -1202,13 +1222,28 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasm_greeting"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fluence",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm_ipfs_node"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fluence",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm_ipfs_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fluence",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-clif-backend"
|
||||
@ -1292,7 +1327,7 @@ dependencies = [
|
||||
"bincode",
|
||||
"blake3",
|
||||
"cc",
|
||||
"digest",
|
||||
"digest 0.8.1",
|
||||
"errno",
|
||||
"hex",
|
||||
"indexmap",
|
||||
|
@ -7,7 +7,8 @@ members = [
|
||||
"examples/ipfs_node",
|
||||
"examples/ipfs_node/wasm/ipfs_node",
|
||||
"examples/ipfs_node/wasm/ipfs_rpc",
|
||||
"examples/simple_greeting",
|
||||
"examples/greeting",
|
||||
"examples/greeting/wasm/",
|
||||
"fluence-faas",
|
||||
"tools/cli",
|
||||
]
|
||||
|
@ -182,13 +182,13 @@ impl<'a> FCEWITInterfaces<'a> {
|
||||
&self,
|
||||
core_function_type: CoreFunctionType,
|
||||
) -> Option<&Vec<AdapterFunctionType>> {
|
||||
self.adapter_type_to_core.get_vec(&core_function_type)
|
||||
self.core_type_to_adapter.get_vec(&core_function_type)
|
||||
}
|
||||
|
||||
pub fn core_types_by_adapter_type(
|
||||
&self,
|
||||
adapter_function_type: AdapterFunctionType,
|
||||
) -> Option<&Vec<CoreFunctionType>> {
|
||||
self.core_type_to_adapter.get_vec(&adapter_function_type)
|
||||
self.adapter_type_to_core.get_vec(&adapter_function_type)
|
||||
}
|
||||
}
|
||||
|
@ -61,14 +61,14 @@ impl WITGenerator for AstFunctionItem {
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let export_function_index = (interfaces.exports.len() - 1) as u32;
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: export_idx,
|
||||
function_index: export_function_index,
|
||||
});
|
||||
|
||||
instructions.extend(match &self.signature.output_type {
|
||||
@ -114,10 +114,10 @@ impl FnInstructionGenerator for ParsedType {
|
||||
],
|
||||
ParsedType::ByteVector => vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringSize,
|
||||
Instruction::ByteArraySize,
|
||||
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::ByteArrayLowerMemory,
|
||||
],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ use fluence_sdk_wit::AstExternModItem;
|
||||
use fluence_sdk_wit::AstExternFnItem;
|
||||
use fluence_sdk_wit::ParsedType;
|
||||
use wasmer_wit::interpreter::Instruction;
|
||||
use crate::instructions_generator::utils::wtype_to_itype;
|
||||
|
||||
impl WITGenerator for AstExternModItem {
|
||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
||||
@ -52,35 +53,71 @@ fn generate_wit_for_import<'a>(
|
||||
Some(ref output_type) => vec![ptype_to_itype(output_type)],
|
||||
None => vec![],
|
||||
};
|
||||
interfaces.types.push(Type::Function {
|
||||
inputs: inputs.clone(),
|
||||
outputs: outputs.clone(),
|
||||
});
|
||||
|
||||
// TODO: replace with Wasm types
|
||||
interfaces.types.push(Type::Function { inputs, outputs });
|
||||
|
||||
let raw_inputs = import
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.map(to_raw_input_types)
|
||||
.flatten()
|
||||
.map(|wt| wtype_to_itype(&wt))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let raw_outputs = match import.signature.output_type {
|
||||
Some(ref output_type) => to_raw_output_type(output_type)
|
||||
.iter()
|
||||
.map(wtype_to_itype)
|
||||
.collect(),
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
interfaces.types.push(Type::Function {
|
||||
inputs: raw_inputs.clone(),
|
||||
outputs: raw_outputs.clone(),
|
||||
});
|
||||
|
||||
interfaces.types.push(Type::Function {
|
||||
inputs: raw_inputs,
|
||||
outputs: raw_outputs,
|
||||
});
|
||||
|
||||
let adapter_idx = (interfaces.types.len() - 2) as u32;
|
||||
let import_idx = (interfaces.types.len() - 1) as u32;
|
||||
let import_idx = (interfaces.types.len() - 3) as u32;
|
||||
let raw_import_idx = (interfaces.types.len() - 1) as u32;
|
||||
|
||||
let link_name = match &import.link_name {
|
||||
Some(link_name) => link_name,
|
||||
None => &import.signature.name,
|
||||
};
|
||||
|
||||
interfaces.imports.push(wasmer_wit::ast::Import {
|
||||
namespace: &namespace,
|
||||
name: &import.signature.name,
|
||||
name: link_name,
|
||||
function_type: import_idx,
|
||||
});
|
||||
|
||||
interfaces.imports.push(wasmer_wit::ast::Import {
|
||||
namespace: &namespace,
|
||||
name: link_name,
|
||||
function_type: raw_import_idx,
|
||||
});
|
||||
|
||||
let mut instructions: Vec<Instruction> = import
|
||||
.signature
|
||||
.input_types
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
// TODO: refactor
|
||||
let import_function_index =
|
||||
(interfaces.exports.len() + interfaces.imports.len() / 2 - 1) as u32;
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: import_idx,
|
||||
function_index: import_function_index,
|
||||
});
|
||||
|
||||
instructions.extend(match &import.signature.output_type {
|
||||
@ -95,7 +132,7 @@ fn generate_wit_for_import<'a>(
|
||||
interfaces.adapters.push(adapter);
|
||||
|
||||
let implementation = wasmer_wit::ast::Implementation {
|
||||
core_function_type: import_idx,
|
||||
core_function_type: raw_import_idx,
|
||||
adapter_function_type: adapter_idx,
|
||||
};
|
||||
interfaces.implementations.push(implementation);
|
||||
@ -163,3 +200,39 @@ impl ForeignModInstructionGenerator for ParsedType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use fluence_sdk_wit::WasmType;
|
||||
|
||||
pub fn to_raw_input_types(ty: &ParsedType) -> Vec<WasmType> {
|
||||
match ty {
|
||||
ParsedType::Boolean
|
||||
| ParsedType::I8
|
||||
| ParsedType::I16
|
||||
| ParsedType::I32
|
||||
| ParsedType::U8
|
||||
| ParsedType::U16
|
||||
| ParsedType::U32 => vec![WasmType::I32],
|
||||
ParsedType::I64 | ParsedType::U64 => vec![WasmType::I64],
|
||||
ParsedType::F32 => vec![WasmType::F32],
|
||||
ParsedType::F64 => vec![WasmType::F64],
|
||||
ParsedType::Utf8String | ParsedType::ByteVector | ParsedType::Record(_) => {
|
||||
vec![WasmType::I32, WasmType::I32]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_raw_output_type(ty: &ParsedType) -> Vec<WasmType> {
|
||||
match ty {
|
||||
ParsedType::Boolean
|
||||
| ParsedType::I8
|
||||
| ParsedType::I16
|
||||
| ParsedType::I32
|
||||
| ParsedType::U8
|
||||
| ParsedType::U16
|
||||
| ParsedType::U32 => vec![WasmType::I32],
|
||||
ParsedType::I64 | ParsedType::U64 => vec![WasmType::I64],
|
||||
ParsedType::F32 => vec![WasmType::F32],
|
||||
ParsedType::F64 => vec![WasmType::F64],
|
||||
ParsedType::Utf8String | ParsedType::ByteVector | ParsedType::Record(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use super::IType;
|
||||
use fluence_sdk_wit::ParsedType;
|
||||
use fluence_sdk_wit::WasmType;
|
||||
|
||||
pub(crate) fn ptype_to_itype(pty: &ParsedType) -> IType {
|
||||
match pty {
|
||||
@ -35,3 +36,12 @@ pub(crate) fn ptype_to_itype(pty: &ParsedType) -> IType {
|
||||
ParsedType::Record(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn wtype_to_itype(pty: &WasmType) -> IType {
|
||||
match pty {
|
||||
WasmType::I32 => IType::I32,
|
||||
WasmType::I64 => IType::I64,
|
||||
WasmType::F32 => IType::F32,
|
||||
WasmType::F64 => IType::F64,
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
|
||||
let ast_set = wasm_ast_extractor(&wasm_module)?;
|
||||
let interfaces = generate_interfaces(&ast_set);
|
||||
|
||||
let wasm_module = wit_parser::delete_wit_section(wasm_module);
|
||||
let mut wasm_module = wit_parser::embed_wit(wasm_module, &interfaces);
|
||||
|
||||
wasm_module.emit_wasm_file(path).map_err(|e| {
|
||||
WITGeneratorError::IOError(format!("resulted Wasm fule can't be emitted: {:?}", e))
|
||||
})
|
||||
@ -68,10 +70,11 @@ fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> {
|
||||
}
|
||||
|
||||
fn generate_default_export_api(interfaces: &mut Interfaces) {
|
||||
// TODO: the order is matter
|
||||
ALLOCATE_FUNC.update_interfaces(interfaces);
|
||||
DEALLOCATE_FUNC.update_interfaces(interfaces);
|
||||
SET_RESULT_SIZE_FUNC.update_interfaces(interfaces);
|
||||
SET_RESULT_PTR_FUNC.update_interfaces(interfaces);
|
||||
GET_RESULT_SIZE_FUNC.update_interfaces(interfaces);
|
||||
GET_RESULT_PTR_FUNC.update_interfaces(interfaces);
|
||||
SET_RESULT_SIZE_FUNC.update_interfaces(interfaces);
|
||||
SET_RESULT_PTR_FUNC.update_interfaces(interfaces);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ impl FCE {
|
||||
match self.modules.get_mut(module_name.as_ref()) {
|
||||
// TODO: refactor errors
|
||||
Some(module) => module.call(func_name.as_ref(), argument),
|
||||
None => Err(FCEError::NoSuchModule),
|
||||
None => Err(FCEError::NoSuchModule(module_name.as_ref().to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ impl FCE {
|
||||
pub fn unload_module<S: AsRef<str>>(&mut self, module_name: S) -> Result<(), FCEError> {
|
||||
match self.modules.remove(module_name.as_ref()) {
|
||||
Some(_) => Ok(()),
|
||||
None => Err(FCEError::NoSuchModule),
|
||||
None => Err(FCEError::NoSuchModule(module_name.as_ref().to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ impl FCE {
|
||||
) -> Result<Vec<FCEFunctionSignature<'_>>, FCEError> {
|
||||
match self.modules.get(module_name.as_ref()) {
|
||||
Some(module) => Ok(Self::get_module_function_signatures(module)),
|
||||
None => Err(FCEError::NoSuchModule),
|
||||
None => Err(FCEError::NoSuchModule(module_name.as_ref().to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ pub enum FCEError {
|
||||
NoSuchFunction(String),
|
||||
|
||||
/// Returns when there is no module with such name.
|
||||
NoSuchModule,
|
||||
NoSuchModule(String),
|
||||
|
||||
/// WIT section parse error.
|
||||
WITParseError(WITParserError),
|
||||
@ -73,7 +73,9 @@ impl std::fmt::Display for FCEError {
|
||||
FCEError::NoSuchFunction(msg) => {
|
||||
write!(f, "FCE doesn't have a function with such a name: {}", msg)
|
||||
}
|
||||
FCEError::NoSuchModule => write!(f, "FCE doesn't have a module with such a name"),
|
||||
FCEError::NoSuchModule(module_name) => {
|
||||
write!(f, "FCE doesn't have a module with name {}", module_name)
|
||||
}
|
||||
FCEError::WITParseError(err) => write!(f, "{}", err),
|
||||
FCEError::IncorrectWIT(err_msg) => write!(f, "{}", err_msg),
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use super::wit_prelude::*;
|
||||
use super::{IType, IValue, WValue};
|
||||
use crate::FCEModuleConfig;
|
||||
|
||||
use fce_wit_interfaces::FCEWITInterfaces;
|
||||
use wasmer_wit::interpreter::Interpreter;
|
||||
@ -28,7 +29,6 @@ use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::sync::Arc;
|
||||
use crate::FCEModuleConfig;
|
||||
|
||||
type WITInterpreter =
|
||||
Interpreter<WITInstance, WITExport, WITFunction, WITMemory, WITMemoryView<'static>>;
|
||||
@ -231,15 +231,20 @@ impl FCEModule {
|
||||
use wasmer_core::vm::Ctx;
|
||||
|
||||
// returns function that will be called from imports of Wasmer module
|
||||
fn dyn_func_from_raw_import<F>(inputs: Vec<IType>, raw_import: F) -> DynamicFunc<'static>
|
||||
fn dyn_func_from_raw_import<F>(
|
||||
inputs: Vec<IType>,
|
||||
outputs: Vec<IType>,
|
||||
raw_import: F,
|
||||
) -> DynamicFunc<'static>
|
||||
where
|
||||
F: Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static,
|
||||
{
|
||||
use wasmer_core::types::FuncSig;
|
||||
use super::type_converters::itype_to_wtype;
|
||||
|
||||
let signature = inputs.iter().map(itype_to_wtype).collect::<Vec<_>>();
|
||||
DynamicFunc::new(Arc::new(FuncSig::new(signature, vec![])), raw_import)
|
||||
let inputs = inputs.iter().map(itype_to_wtype).collect::<Vec<_>>();
|
||||
let outputs = outputs.iter().map(itype_to_wtype).collect::<Vec<_>>();
|
||||
DynamicFunc::new(Arc::new(FuncSig::new(inputs, outputs)), raw_import)
|
||||
}
|
||||
|
||||
// creates a closure that is represent a WIT module import
|
||||
@ -302,7 +307,7 @@ impl FCEModule {
|
||||
let wit_type = wit.type_by_idx_r(adapter_function_type)?;
|
||||
|
||||
match wit_type {
|
||||
WITAstType::Function { inputs, .. } => {
|
||||
WITAstType::Function { inputs, outputs } => {
|
||||
let interpreter: WITInterpreter = adapter_instructions.try_into()?;
|
||||
|
||||
let raw_import = create_raw_import(
|
||||
@ -311,7 +316,8 @@ impl FCEModule {
|
||||
import_namespace.to_string(),
|
||||
import_name.to_string(),
|
||||
);
|
||||
let wit_import = dyn_func_from_raw_import(inputs.clone(), raw_import);
|
||||
let wit_import =
|
||||
dyn_func_from_raw_import(inputs.clone(), outputs.clone(), raw_import);
|
||||
|
||||
Ok((import_namespace.to_string(), (*import_name, wit_import)))
|
||||
}
|
||||
|
@ -78,17 +78,16 @@ impl WITInstance {
|
||||
start_index: usize,
|
||||
) -> Result<HashMap<usize, WITFunction>, FCEError> {
|
||||
wit.imports()
|
||||
.filter(|import| {
|
||||
.filter(|import|
|
||||
// filter out imports that have implementations
|
||||
matches!(wit.adapter_by_type(import.function_type), None)
|
||||
})
|
||||
matches!(wit.adapter_types_by_core_type(import.function_type), Some(_)))
|
||||
.enumerate()
|
||||
.map(|(idx, import)| match modules.get(import.namespace) {
|
||||
Some(module) => {
|
||||
let func = WITFunction::from_import(module, import.name)?;
|
||||
Ok((start_index + idx as usize, func))
|
||||
}
|
||||
None => Err(FCEError::NoSuchModule),
|
||||
None => Err(FCEError::NoSuchModule(import.namespace.to_string())),
|
||||
})
|
||||
.collect::<Result<HashMap<_, _>, _>>()
|
||||
}
|
||||
|
9
examples/greeting/Cargo.toml
Normal file
9
examples/greeting/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "greeting"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
fluence-faas = { path = "../../fluence-faas" }
|
||||
anyhow = "1.0.31"
|
6
examples/greeting/Config.toml
Normal file
6
examples/greeting/Config.toml
Normal file
@ -0,0 +1,6 @@
|
||||
core_modules_dir = "wasm/artifacts/"
|
||||
|
||||
[[core_module]]
|
||||
name = "greeting.wasm"
|
||||
mem_pages_count = 1
|
||||
logger_enabled = false
|
40
examples/greeting/src/main.rs
Normal file
40
examples/greeting/src/main.rs
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 fluence_faas::FluenceFaaS;
|
||||
use fluence_faas::IValue;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
const GREETING_MODULE_CONFIG_PATH: &str = "Config.toml";
|
||||
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
let mut greeting_node = FluenceFaaS::new(PathBuf::from(GREETING_MODULE_CONFIG_PATH))?;
|
||||
println!(
|
||||
"greeting node interface is\n{}",
|
||||
greeting_node.get_interface()
|
||||
);
|
||||
|
||||
let result = greeting_node.call_module(
|
||||
"greeting.wasm",
|
||||
"greeting",
|
||||
&[IValue::String("Fluence".to_string()), IValue::I32(1)],
|
||||
)?;
|
||||
|
||||
println!("execution result {:?}", result);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "greeting"
|
||||
name = "wasm_greeting"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
@ -10,4 +10,4 @@ path = "src/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk" }
|
||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["debug"] }
|
@ -18,5 +18,5 @@ use fluence::fce;
|
||||
|
||||
#[fce]
|
||||
pub fn greeting(name: String) -> String {
|
||||
format!("Hi, {}\n", name)
|
||||
format!("Hi, {}", name)
|
||||
}
|
@ -21,25 +21,24 @@ use std::path::PathBuf;
|
||||
use anyhow::Context;
|
||||
|
||||
const IPFS_MODULES_CONFIG_PATH: &str = "Config.toml";
|
||||
const IPFS_RPC: &str = "wasm/artifacts/wasm_ipfs_rpc_wit.wasi.wasm";
|
||||
const IPFS_RPC: &str = "wasm/artifacts/ipfs_rpc.wasm";
|
||||
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
let ipfs_rpc = std::fs::read(IPFS_RPC).context(format!("{} wasn't found", IPFS_RPC))?;
|
||||
let ipfs_rpc = std::fs::read(IPFS_RPC).with_context(|| format!("{} wasn't found", IPFS_RPC))?;
|
||||
|
||||
let mut ipfs_node = FluenceFaaS::new(PathBuf::from(IPFS_MODULES_CONFIG_PATH))?;
|
||||
|
||||
println!("ipfs node interface is\n{}", ipfs_node.get_interface());
|
||||
|
||||
let node_address = ipfs_node.call_module("ipfs_node.wasm", "get_address", &[])?;
|
||||
|
||||
println!("ipfs node address is:\n{:?}", node_address);
|
||||
|
||||
let result = ipfs_node.call_code(
|
||||
&ipfs_rpc,
|
||||
"put",
|
||||
&[IValue::String("Hello, world".to_string())],
|
||||
"get",
|
||||
&[IValue::String(
|
||||
"QmXdC36pX1B1sdHdbri859vMYctQjAhvTmkWyG9xzhShxb".to_string(),
|
||||
)],
|
||||
)?;
|
||||
|
||||
println!("execution result {:?}", result);
|
||||
|
||||
Ok(())
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
[build]
|
||||
target = "wasm32-wasi"
|
@ -5,5 +5,9 @@ authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[[bin]]
|
||||
name = "wasm_ipfs_node"
|
||||
name = "ipfs_node"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["debug"] }
|
||||
log = "0.4.8"
|
||||
|
@ -14,63 +14,38 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
mod mem;
|
||||
mod result;
|
||||
mod path;
|
||||
|
||||
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
||||
use crate::path::to_full_path;
|
||||
|
||||
use fluence::fce;
|
||||
use fluence::WasmLogger;
|
||||
|
||||
const RESULT_FILE_PATH: &str = "/tmp/ipfs_rpc_file";
|
||||
const IPFS_ADDR_ENV_NAME: &str = "IPFS_ADDR";
|
||||
const TIMEOUT_ENV_NAME: &str = "timeout";
|
||||
|
||||
pub fn main() {
|
||||
let msg = "ipfs_node.main: WASI initialization finished";
|
||||
unsafe {
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
}
|
||||
WasmLogger::init_with_level(log::Level::Info).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn put(file_path_ptr: *mut u8, file_path_size: usize) {
|
||||
let file_path = String::from_raw_parts(file_path_ptr, file_path_size, file_path_size);
|
||||
|
||||
let msg = format!("ipfs_node.put: file path is {}\n", file_path);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
/// Put file from specified path to IPFS and return its hash.
|
||||
#[fce]
|
||||
pub fn put(file_path: String) -> String {
|
||||
log::info!("put called with file path {}", file_path);
|
||||
|
||||
let file_path = to_full_path(file_path);
|
||||
|
||||
let timeout = std::env::var(TIMEOUT_ENV_NAME).unwrap_or_else(|_| "1s".to_string());
|
||||
let cmd = format!("add --timeout {} -Q {}", timeout, file_path);
|
||||
let result = ipfs(cmd.as_ptr() as _, cmd.len() as _);
|
||||
|
||||
let hash = if result == 0 {
|
||||
String::from_raw_parts(
|
||||
*RESULT_PTR.get_mut() as _,
|
||||
*RESULT_SIZE.get_mut(),
|
||||
*RESULT_SIZE.get_mut(),
|
||||
)
|
||||
} else {
|
||||
"host ipfs call failed".to_string()
|
||||
};
|
||||
|
||||
let msg = format!("ipfs_node.put: file add with hash is {} \n", hash);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = hash.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = hash.len();
|
||||
std::mem::forget(hash);
|
||||
call_ipfs(cmd)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) {
|
||||
let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size);
|
||||
|
||||
let msg = format!("ipfs_node.get: file hash is {}\n", hash);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
/// Get file by provided hash from IPFS, saves it to a temporary file and returns a path to it.
|
||||
#[fce]
|
||||
pub fn get(hash: String) -> String {
|
||||
log::info!("get called with hash {}", hash);
|
||||
|
||||
let result_file_path = to_full_path(RESULT_FILE_PATH);
|
||||
|
||||
@ -79,51 +54,39 @@ pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) {
|
||||
"get --timeout {} -o {} {}",
|
||||
timeout, result_file_path, hash
|
||||
);
|
||||
let _result = ipfs(cmd.as_ptr() as _, cmd.len() as _);
|
||||
|
||||
let _output = String::from_raw_parts(
|
||||
*RESULT_PTR.get_mut() as _,
|
||||
*RESULT_SIZE.get_mut(),
|
||||
*RESULT_SIZE.get_mut(),
|
||||
);
|
||||
call_ipfs(cmd);
|
||||
|
||||
// TODO: check output
|
||||
|
||||
let file_path = RESULT_FILE_PATH.to_string();
|
||||
let msg = format!("ipfs_node.get: file path is {}", file_path);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = file_path.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = file_path.len();
|
||||
std::mem::forget(file_path);
|
||||
RESULT_FILE_PATH.to_string()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_address() {
|
||||
let msg = "ipfs_node.get_address".to_string();
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
let ipfs_address = match std::env::var(IPFS_ADDR_ENV_NAME) {
|
||||
#[fce]
|
||||
pub fn get_address() -> String {
|
||||
match std::env::var(IPFS_ADDR_ENV_NAME) {
|
||||
Ok(addr) => addr,
|
||||
Err(e) => format!(
|
||||
"getting {} env variable failed with error {:?}",
|
||||
IPFS_ADDR_ENV_NAME, e
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let msg = format!("ipfs_node.get_address: node address is {} \n", ipfs_address);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = ipfs_address.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = ipfs_address.len();
|
||||
std::mem::forget(ipfs_address);
|
||||
fn call_ipfs(cmd: String) -> String {
|
||||
unsafe {
|
||||
// TODO: better error handling
|
||||
match ipfs(cmd.as_ptr() as _, cmd.len() as _) {
|
||||
0 => String::from_raw_parts(
|
||||
fluence::internal::get_result_ptr() as _,
|
||||
fluence::internal::get_result_size(),
|
||||
fluence::internal::get_result_size(),
|
||||
),
|
||||
_ => "host ipfs call failed".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[link(wasm_import_module = "host")]
|
||||
extern "C" {
|
||||
/// Writes a byte string of size bytes that starts from ptr to a logger.
|
||||
fn log_utf8_string(ptr: i32, size: i32);
|
||||
|
||||
/// Put a file to ipfs, returns ipfs hash of the file.
|
||||
fn ipfs(ptr: i32, size: i32) -> i32;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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::log_utf8_string;
|
||||
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();
|
||||
|
||||
let msg = format!("ipfs_node.allocate: {}\n", size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
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();
|
||||
|
||||
let msg = format!("ipfs_node.deallocate: {:?} {}\n", ptr, size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
global_dealloc(ptr.as_ptr(), layout);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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::log_utf8_string;
|
||||
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 {
|
||||
let msg = "ipfs_node.get_result_ptr\n";
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_size() -> usize {
|
||||
let msg = "ipfs_node.get_result_size\n";
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_SIZE.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_ptr(ptr: usize) {
|
||||
let msg = format!("ipfs_node.set_result_ptr: {}\n", ptr);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = ptr;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_size(size: usize) {
|
||||
let msg = format!("ipfs_node.set_result_size: {}\n", size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_SIZE.get_mut() = size;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
;; allocate function type
|
||||
(@interface type (func (param i32) (result i32))) ;; 0
|
||||
|
||||
;; deallocate function
|
||||
(@interface type (func (param i32 i32))) ;; 1
|
||||
|
||||
;; invoke function
|
||||
(@interface type (func (param string) (result string))) ;; 2
|
||||
|
||||
;; result extractor functions
|
||||
(@interface type (func (result i32))) ;; 3
|
||||
|
||||
;; result setter functions
|
||||
(@interface type (func (param string))) ;; 4
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param i32 i32))) ;; 5
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 6
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 7
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 8
|
||||
|
||||
;; export ipfs.get_address function
|
||||
(@interface type (func (result string))) ;; 9
|
||||
|
||||
;; export ipfs.get_address function
|
||||
(@interface type (func )) ;; 10
|
||||
|
||||
(@interface export "allocate" (func 0)) ;; 0
|
||||
(@interface export "deallocate" (func 1)) ;; 1
|
||||
(@interface export "get_result_size" (func 3)) ;; 2
|
||||
(@interface export "get_result_ptr" (func 3)) ;; 3
|
||||
(@interface export "set_result_size" (func 4)) ;; 4
|
||||
(@interface export "set_result_ptr" (func 4)) ;; 5
|
||||
|
||||
(@interface export "put" (func 5)) ;; 6
|
||||
(@interface export "get" (func 6)) ;; 7
|
||||
(@interface export "get_address" (func 10)) ;; 8
|
||||
|
||||
;; adapter for export function put
|
||||
(@interface func (type 7)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 6 ;; call self.put
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
string.lift_memory
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; adapter for export function get
|
||||
(@interface func (type 8)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 7 ;; call self.get
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
string.lift_memory
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; adapter for export function get_address
|
||||
(@interface func (type 9)
|
||||
call-core 8 ;; call self.get
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
string.lift_memory
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 2 ;; call get_result_size
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; Implementations
|
||||
(@interface implement (func 5) (func 7))
|
||||
(@interface implement (func 6) (func 8))
|
||||
(@interface implement (func 10) (func 9))
|
@ -1,2 +0,0 @@
|
||||
[build]
|
||||
target = "wasm32-wasi"
|
@ -5,5 +5,9 @@ authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[[bin]]
|
||||
name = "wasm_ipfs_rpc"
|
||||
name = "ipfs_rpc"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["debug"] }
|
||||
log = "0.4.8"
|
||||
|
@ -13,107 +13,54 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
mod mem;
|
||||
mod result;
|
||||
use fluence::fce;
|
||||
use fluence::WasmLogger;
|
||||
|
||||
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
const RPC_TMP_FILEPATH: &str = "/tmp/ipfs_rpc_file";
|
||||
|
||||
pub fn main() {
|
||||
let msg = "ipfs_rpc.main: WASI initialization finished";
|
||||
unsafe {
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
}
|
||||
WasmLogger::init_with_level(log::Level::Info).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn invoke(_ptr: *mut u8, _size: usize) {
|
||||
let msg = "ipfs_rpc.invoke: invoke called\n";
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
let result = "IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string();
|
||||
|
||||
*RESULT_PTR.get_mut() = result.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = result.len();
|
||||
std::mem::forget(result);
|
||||
#[fce]
|
||||
pub fn invoke() -> String {
|
||||
"IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) {
|
||||
let file_content =
|
||||
String::from_raw_parts(file_content_ptr, file_content_size, file_content_size);
|
||||
|
||||
let msg = format!("ipfs_rpc.put: file_content is {}\n", file_content);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
#[fce]
|
||||
pub fn put(file_content: Vec<u8>) -> String {
|
||||
log::info!("put called with {:?}", file_content);
|
||||
|
||||
let rpc_tmp_filepath = RPC_TMP_FILEPATH.to_string();
|
||||
|
||||
let r = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content);
|
||||
if let Err(e) = r {
|
||||
let msg: String = e.to_string();
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
return format!("file can't be written: {}", e);
|
||||
}
|
||||
|
||||
ipfs_put(rpc_tmp_filepath.as_ptr() as _, rpc_tmp_filepath.len() as _);
|
||||
std::mem::forget(rpc_tmp_filepath);
|
||||
|
||||
let hash = String::from_raw_parts(
|
||||
*RESULT_PTR.get_mut() as _,
|
||||
*RESULT_SIZE.get_mut(),
|
||||
*RESULT_SIZE.get_mut(),
|
||||
);
|
||||
|
||||
let msg = format!("ipfs_rpc.put: file add with hash {}\n", hash);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = hash.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = hash.len();
|
||||
std::mem::forget(hash);
|
||||
ipfs_put(rpc_tmp_filepath)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) {
|
||||
let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size);
|
||||
#[fce]
|
||||
pub fn get(hash: String) -> Vec<u8> {
|
||||
log::info!("get called with hash: {}", hash);
|
||||
|
||||
let msg = format!("ipfs_rpc.get: getting file with hash {}\n", hash);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
ipfs_get(hash.as_ptr() as _, hash.len() as _);
|
||||
|
||||
let file_path = String::from_raw_parts(
|
||||
*RESULT_PTR.get_mut() as _,
|
||||
*RESULT_SIZE.get_mut(),
|
||||
*RESULT_SIZE.get_mut(),
|
||||
);
|
||||
|
||||
let msg = format!("ipfs_rpc.get: reading file from {}\n", file_path);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
let file_content = fs::read(file_path).unwrap_or_else(|_| b"error while reading file".to_vec());
|
||||
|
||||
*RESULT_PTR.get_mut() = file_content.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = file_content.len();
|
||||
std::mem::forget(file_content);
|
||||
}
|
||||
|
||||
#[link(wasm_import_module = "host")]
|
||||
extern "C" {
|
||||
/// Writes a byte string of size bytes that starts from ptr to a logger.
|
||||
fn log_utf8_string(ptr: i32, size: i32);
|
||||
let file_path = ipfs_get(hash);
|
||||
fs::read(file_path).unwrap_or_else(|_| b"error while reading file".to_vec())
|
||||
}
|
||||
|
||||
#[fce]
|
||||
#[link(wasm_import_module = "ipfs_node.wasm")]
|
||||
extern "C" {
|
||||
/// Put a file to ipfs, returns ipfs hash of the file.
|
||||
/// Put provided file to ipfs, return ipfs hash of the file.
|
||||
#[link_name = "put"]
|
||||
fn ipfs_put(ptr: i32, size: i32);
|
||||
pub fn ipfs_put(file_path: String) -> String;
|
||||
|
||||
/// Get file from ipfs by hash.
|
||||
#[link_name = "get"]
|
||||
fn ipfs_get(ptr: i32, size: i32);
|
||||
pub fn ipfs_get(hash: String) -> String;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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::log_utf8_string;
|
||||
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();
|
||||
|
||||
let msg = format!("ipfs_rpc.allocate: {}\n", size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
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();
|
||||
|
||||
let msg = format!("ipfs_rpc.deallocate: {:?} {}\n", ptr, size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
global_dealloc(ptr.as_ptr(), layout);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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::log_utf8_string;
|
||||
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 {
|
||||
let msg = "ipfs_rpc.get_result_ptr\n";
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_size() -> usize {
|
||||
let msg = "ipfs_rpc.get_result_size\n";
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_SIZE.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_ptr(ptr: usize) {
|
||||
let msg = format!("ipfs_rpc.set_result_ptr: {}\n", ptr);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_PTR.get_mut() = ptr;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_size(size: usize) {
|
||||
let msg = format!("ipfs_rpc.set_result_size: {}\n", size);
|
||||
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
|
||||
|
||||
*RESULT_SIZE.get_mut() = size;
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
;; allocate function type
|
||||
(@interface type (func (param i32) (result i32))) ;; 0
|
||||
|
||||
;; deallocate function
|
||||
(@interface type (func (param i32 i32))) ;; 1
|
||||
|
||||
;; invoke function
|
||||
(@interface type (func (param string) (result string))) ;; 2
|
||||
|
||||
;; result extractor functions
|
||||
(@interface type (func (result i32))) ;; 3
|
||||
|
||||
;; result setter functions
|
||||
(@interface type (func (param i32))) ;; 4
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param i32 i32))) ;; 5
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param i32 i32))) ;; 6
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 7
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 8
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param i32 i32))) ;; 9
|
||||
|
||||
;; import ipfs put/get function
|
||||
(@interface type (func (param i32 i32))) ;; 10
|
||||
|
||||
;; export ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 11
|
||||
|
||||
;; export ipfs put/get function
|
||||
(@interface type (func (param string) (result string))) ;; 12
|
||||
|
||||
(@interface export "allocate" (func 0)) ;; 0
|
||||
(@interface export "deallocate" (func 1)) ;; 1
|
||||
(@interface export "invoke" (func 2)) ;; 2
|
||||
(@interface export "get_result_size" (func 3)) ;; 3
|
||||
(@interface export "get_result_ptr" (func 3)) ;; 4
|
||||
(@interface export "set_result_size" (func 4)) ;; 5
|
||||
(@interface export "set_result_ptr" (func 4)) ;; 6
|
||||
(@interface export "put" (func 11)) ;; 7
|
||||
(@interface export "get" (func 12)) ;; 8
|
||||
|
||||
(@interface import "ipfs_node.wasm" "get" (func (type 5)))
|
||||
(@interface import "ipfs_node.wasm" "put" (func (type 6)))
|
||||
|
||||
(@interface import "ipfs_node.wasm" "get" (func (type 7))) ;; 9
|
||||
(@interface import "ipfs_node.wasm" "put" (func (type 8))) ;; 10
|
||||
|
||||
;; adapter for export invoke function
|
||||
(@interface func (type 2)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 2 ;; call invoke
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
string.lift_memory
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; adapter for export put function
|
||||
(@interface func (type 11)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 7 ;; call put
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
string.lift_memory
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; adapter for export get function
|
||||
(@interface func (type 12)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 8 ;; call get
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
string.lift_memory
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 3 ;; call get_result_ptr
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; adapter for import function ipfs.get
|
||||
(@interface func (type 9)
|
||||
arg.get 0
|
||||
arg.get 1
|
||||
string.lift_memory
|
||||
call-core 9 ;; call ipfs_node.get that returns string
|
||||
dup
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
swap2
|
||||
string.lower_memory
|
||||
call-core 5 ;; call set_result_size
|
||||
call-core 6 ;; call set_result_ptr
|
||||
)
|
||||
|
||||
;; adapter for import function ipfs.put
|
||||
(@interface func (type 10)
|
||||
arg.get 0
|
||||
arg.get 1
|
||||
string.lift_memory
|
||||
call-core 10 ;; call ipfs_node.put that returns string
|
||||
dup
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
swap2
|
||||
string.lower_memory
|
||||
call-core 5 ;; call set_result_size
|
||||
call-core 6 ;; call set_result_ptr
|
||||
)
|
||||
|
||||
;; Implementations
|
||||
(@interface implement (func 2) (func 2))
|
||||
(@interface implement (func 5) (func 9))
|
||||
(@interface implement (func 6) (func 10))
|
||||
(@interface implement (func 11) (func 11))
|
||||
(@interface implement (func 12) (func 12))
|
@ -1,2 +0,0 @@
|
||||
[build]
|
||||
target = "wasm32-unknown-unknown"
|
Loading…
Reference in New Issue
Block a user