mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 06:45:32 +00:00
Fix IT generation (#87)
This commit is contained in:
parent
fa38bc4025
commit
c51b5982d6
@ -29,7 +29,7 @@ jobs:
|
||||
(cd ./examples; ./build.sh)
|
||||
(cd ./fluence-faas/tests/wasm_tests; ./build.sh)
|
||||
|
||||
cargo test --release -v --all-features -p marine-runtime -p fluence-faas -p fluence-app-service -p marine -p mrepl
|
||||
cargo test --release -v --all-features -p marine-it-generator -p marine-runtime -p fluence-faas -p fluence-app-service -p marine -p mrepl
|
||||
cargo clippy -v -p marine-runtime -p fluence-faas -p fluence-app-service -p marine -p mrepl
|
||||
|
||||
- save_cache:
|
||||
|
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -700,9 +700,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fluence"
|
||||
version = "0.6.5"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd1f159a4da6aef89e8e4a0bf061a8031d669d03d9928266942581a52df03f56"
|
||||
checksum = "88b09e1cd11a51ba4d169db347d009fe41ece2714eef4d5df720343733a1d5a6"
|
||||
dependencies = [
|
||||
"fluence-sdk-main",
|
||||
"marine-macro",
|
||||
@ -805,9 +805,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.6.4"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3a5d1ca20ada064379d959a9a82f9c006e4d9388533cf06010186fef6dd583b"
|
||||
checksum = "68d93cde99e1494e11755a39b93863333397245c9959c774fe3bebd9e4143879"
|
||||
dependencies = [
|
||||
"log",
|
||||
"marine-macro",
|
||||
@ -1549,18 +1549,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro"
|
||||
version = "0.6.4"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c1652b6ac1bbdde9a66c16c8a2f9cd34d005a1f1b211a538c5b28764faa6ef4"
|
||||
checksum = "f63d927851847cc3dd9e3bd0f10bdeb313859d4822d5b5f650d9d34d461ed419"
|
||||
dependencies = [
|
||||
"marine-macro-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro-impl"
|
||||
version = "0.6.4"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80fee75eaf1a97ee9fe2d382c0537c06a79e5d7ab9d81bda6cb263fb8fd1a15a"
|
||||
checksum = "fb504be4a90e229ab453c7369cc8a9063acec819f3397802eea719cd0a232be1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1699,9 +1699,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "marine-timestamp-macro"
|
||||
version = "0.6.2"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6feb612ccd3fd39ec3d50c9a1a96885e1fd32d36a92cf674a0fbe6f7c452613"
|
||||
checksum = "5994c7db5567d21609f2a2e5a40d9d4564f86c17ca35b2d77007152619b9d7fc"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "marine-it-generator"
|
||||
description = "Fluence Marine interface types generator"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
authors = ["Fluence Labs"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
@ -12,7 +12,7 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
marine-it-parser = { path = "../it-parser", version = "0.6.0"}
|
||||
marine-macro-impl = "0.6.4"
|
||||
marine-macro-impl = "0.6.9"
|
||||
|
||||
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.0" }
|
||||
it-lilo = "0.1.0"
|
||||
|
@ -17,6 +17,8 @@
|
||||
mod fn_instructions;
|
||||
mod foreign_mod_instructions;
|
||||
mod record_instructions;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod utils;
|
||||
|
||||
use crate::Result;
|
||||
@ -102,6 +104,75 @@ impl<'a> ITResolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ITResolver<'a> {
|
||||
pub(crate) fn add_adapter(
|
||||
&mut self,
|
||||
function_type: u32,
|
||||
instructions: Vec<wasmer_it::interpreter::Instruction>,
|
||||
) {
|
||||
let adapter = wasmer_it::ast::Adapter {
|
||||
function_type,
|
||||
instructions,
|
||||
};
|
||||
|
||||
self.interfaces.adapters.push(adapter);
|
||||
}
|
||||
|
||||
pub(crate) fn add_implementation(
|
||||
&mut self,
|
||||
core_function_type: u32,
|
||||
adapter_function_type: u32,
|
||||
) {
|
||||
let implementation = wasmer_it::ast::Implementation {
|
||||
core_function_type,
|
||||
adapter_function_type,
|
||||
};
|
||||
|
||||
self.interfaces.implementations.push(implementation);
|
||||
}
|
||||
|
||||
pub(crate) fn add_export(&mut self, name: &'a str, function_type: u32) {
|
||||
let export = wasmer_it::ast::Export {
|
||||
name,
|
||||
function_type,
|
||||
};
|
||||
|
||||
self.interfaces.exports.push(export);
|
||||
}
|
||||
|
||||
pub(crate) fn add_import(&mut self, namespace: &'a str, name: &'a str, function_type: u32) {
|
||||
let import = wasmer_it::ast::Import {
|
||||
namespace,
|
||||
name,
|
||||
function_type,
|
||||
};
|
||||
|
||||
self.interfaces.imports.push(import);
|
||||
}
|
||||
|
||||
pub(crate) fn add_fn_type(
|
||||
&mut self,
|
||||
arguments: Rc<Vec<wasmer_it::ast::FunctionArg>>,
|
||||
output_types: Rc<Vec<IType>>,
|
||||
) {
|
||||
let fn_type = wasmer_it::ast::Type::Function {
|
||||
arguments,
|
||||
output_types,
|
||||
};
|
||||
|
||||
self.interfaces.types.push(fn_type);
|
||||
}
|
||||
|
||||
pub(crate) fn add_record_type(
|
||||
&mut self,
|
||||
name: String,
|
||||
fields: wasmer_it::NEVec<wasmer_it::IRecordFieldType>,
|
||||
) {
|
||||
let record = wasmer_it::IRecordType { name, fields };
|
||||
self.insert_record_type(record);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ITGenerator {
|
||||
fn generate_it<'a>(&'a self, it_resolver: &mut ITResolver<'a>) -> Result<()>;
|
||||
}
|
||||
|
@ -14,225 +14,87 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod args_it_generator;
|
||||
mod output_type_it_generator;
|
||||
|
||||
use super::ITGenerator;
|
||||
use super::ITResolver;
|
||||
use super::utils::ptype_to_itype_checked;
|
||||
use crate::default_export_api_config::*;
|
||||
use super::utils::*;
|
||||
use crate::Result;
|
||||
use crate::default_export_api_config::RELEASE_OBJECTS;
|
||||
|
||||
use marine_macro_impl::FnType;
|
||||
use marine_macro_impl::ParsedType;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||
use wasmer_it::IType;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
impl ITGenerator for FnType {
|
||||
fn generate_it<'a>(&'a self, it_resolver: &mut ITResolver<'a>) -> Result<()> {
|
||||
use wasmer_it::ast::Type;
|
||||
use wasmer_it::ast::Adapter;
|
||||
generate_it_types(self, it_resolver)?;
|
||||
generate_instructions(self, it_resolver)
|
||||
}
|
||||
}
|
||||
|
||||
let arguments = self
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| -> Result<IFunctionArg> {
|
||||
Ok(IFunctionArg {
|
||||
name: arg.name.clone(),
|
||||
ty: ptype_to_itype_checked(&arg.ty, it_resolver)?,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
fn generate_it_types<'f>(fn_type: &'f FnType, it_resolver: &mut ITResolver<'f>) -> Result<()> {
|
||||
let arguments = generate_it_args(&fn_type.signature, it_resolver)?;
|
||||
let output_types = generate_it_output_type(&fn_type.signature, it_resolver)?;
|
||||
|
||||
let arguments = Rc::new(arguments);
|
||||
it_resolver.add_fn_type(arguments.clone(), output_types.clone());
|
||||
// TODO: replace with Wasm types
|
||||
it_resolver.add_fn_type(arguments, output_types);
|
||||
|
||||
let output_types = self
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
.map(|ty| ptype_to_itype_checked(ty, it_resolver))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
let output_types = Rc::new(output_types);
|
||||
let export_idx = (it_resolver.interfaces.types.len() - 1) as u32;
|
||||
it_resolver.add_export(&fn_type.signature.name, export_idx);
|
||||
|
||||
let interfaces = &mut it_resolver.interfaces;
|
||||
interfaces.types.push(Type::Function {
|
||||
arguments: arguments.clone(),
|
||||
output_types: output_types.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: replace with Wasm types
|
||||
interfaces.types.push(Type::Function {
|
||||
arguments,
|
||||
output_types,
|
||||
});
|
||||
fn generate_instructions<'f>(fn_type: &'f FnType, it_resolver: &mut ITResolver<'f>) -> Result<()> {
|
||||
use args_it_generator::ArgumentITGenerator;
|
||||
use output_type_it_generator::OutputITGenerator;
|
||||
|
||||
let adapter_idx = (interfaces.types.len() - 2) as u32;
|
||||
let export_idx = (interfaces.types.len() - 1) as u32;
|
||||
let mut instructions = fn_type
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.try_fold::<_, _, Result<_>>(Vec::new(), |mut instructions, (arg_id, arg)| {
|
||||
let new_instructions = arg
|
||||
.ty
|
||||
.generate_instructions_for_arg(arg_id as _, it_resolver)?;
|
||||
|
||||
interfaces.exports.push(wasmer_it::ast::Export {
|
||||
name: &self.signature.name,
|
||||
function_type: export_idx,
|
||||
});
|
||||
instructions.extend(new_instructions);
|
||||
Ok(instructions)
|
||||
})?;
|
||||
|
||||
let mut instructions = self
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.try_fold::<_, _, Result<_>>(Vec::new(), |mut instructions, (arg_id, arg)| {
|
||||
let new_instructions = arg
|
||||
.ty
|
||||
.generate_instructions_for_input_type(arg_id as _, it_resolver)?;
|
||||
let export_function_index = (it_resolver.interfaces.exports.len() - 1) as u32;
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: export_function_index,
|
||||
});
|
||||
|
||||
instructions.extend(new_instructions);
|
||||
Ok(instructions)
|
||||
})?;
|
||||
let mut should_generate_release = false;
|
||||
let mut instructions = fn_type
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
.try_fold::<_, _, Result<_>>(instructions, |mut instructions, ty| {
|
||||
let new_instructions = ty.generate_instructions_for_output_type(it_resolver)?;
|
||||
instructions.extend(new_instructions);
|
||||
|
||||
let export_function_index = (it_resolver.interfaces.exports.len() - 1) as u32;
|
||||
should_generate_release |= ty.is_complex_type();
|
||||
Ok(instructions)
|
||||
})?;
|
||||
|
||||
if should_generate_release {
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: export_function_index,
|
||||
function_index: RELEASE_OBJECTS.id,
|
||||
});
|
||||
|
||||
let instructions = self
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
.try_fold::<_, _, Result<_>>(instructions, |mut instructions, ty| {
|
||||
let new_instructions = ty.generate_instructions_for_output_type(it_resolver)?;
|
||||
|
||||
instructions.extend(new_instructions);
|
||||
Ok(instructions)
|
||||
})?;
|
||||
|
||||
let adapter = Adapter {
|
||||
function_type: adapter_idx,
|
||||
instructions,
|
||||
};
|
||||
|
||||
it_resolver.interfaces.adapters.push(adapter);
|
||||
|
||||
let implementation = wasmer_it::ast::Implementation {
|
||||
core_function_type: export_idx,
|
||||
adapter_function_type: adapter_idx,
|
||||
};
|
||||
it_resolver.interfaces.implementations.push(implementation);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate IT instructions for a function.
|
||||
trait FnInstructionGenerator {
|
||||
fn generate_instructions_for_input_type<'a>(
|
||||
&self,
|
||||
arg_id: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
|
||||
fn generate_instructions_for_output_type<'a>(
|
||||
&self,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
}
|
||||
|
||||
impl FnInstructionGenerator for ParsedType {
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_input_type<'a>(&self, index: u32, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromBool],
|
||||
ParsedType::I8(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
|
||||
ParsedType::I16(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
|
||||
ParsedType::I32(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS32],
|
||||
ParsedType::I64(_) => vec![Instruction::ArgumentGet { index }, Instruction::I64FromS64],
|
||||
ParsedType::U8(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU8],
|
||||
ParsedType::U16(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU16],
|
||||
ParsedType::U32(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU32],
|
||||
ParsedType::U64(_) => vec![Instruction::ArgumentGet { index }, Instruction::I64FromU64],
|
||||
ParsedType::F32(_) => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::F64(_) => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
|
||||
vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: type_tag },
|
||||
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringLowerMemory,
|
||||
]
|
||||
},
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArrayLowerMemory {
|
||||
value_type
|
||||
},
|
||||
]
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
vec! [
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::RecordLowerMemory { record_type_id },
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_output_type<'a>(&self, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::BoolFromI32],
|
||||
ParsedType::I8(_) => vec![Instruction::S8FromI32],
|
||||
ParsedType::I16(_) => vec![Instruction::S16FromI32],
|
||||
ParsedType::I32(_) => vec![Instruction::S32FromI32],
|
||||
ParsedType::I64(_) => vec![Instruction::S64FromI64],
|
||||
ParsedType::U8(_) => vec![Instruction::U8FromI32],
|
||||
ParsedType::U16(_) => vec![Instruction::U16FromI32],
|
||||
ParsedType::U32(_) => vec![Instruction::U32FromI32],
|
||||
ParsedType::U64(_) => vec![Instruction::U64FromI64],
|
||||
ParsedType::F32(_) => vec![],
|
||||
ParsedType::F64(_) => vec![],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::StringLiftMemory,
|
||||
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
|
||||
],
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
if let IType::U8 = value_type {
|
||||
vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::ByteArrayLiftMemory,
|
||||
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::ArrayLiftMemory { value_type },
|
||||
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
|
||||
]
|
||||
}
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
let types_count = it_resolver.interfaces.types.len() as u32;
|
||||
let adapter_idx = types_count - 2;
|
||||
let export_idx = types_count - 1;
|
||||
|
||||
vec! [
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::RecordLiftMemory { record_type_id },
|
||||
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
|
||||
]
|
||||
},
|
||||
};
|
||||
it_resolver.add_adapter(adapter_idx, instructions);
|
||||
it_resolver.add_implementation(export_idx, adapter_idx);
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2021 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 super::ITResolver;
|
||||
use super::ptype_to_itype_checked;
|
||||
use crate::default_export_api_config::*;
|
||||
use crate::Result;
|
||||
|
||||
use marine_macro_impl::ParsedType;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
|
||||
/// Generates IT instructions for a argument of an export function.
|
||||
pub(super) trait ArgumentITGenerator {
|
||||
fn generate_instructions_for_arg<'a>(
|
||||
&self,
|
||||
arg_id: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
}
|
||||
|
||||
impl ArgumentITGenerator for ParsedType {
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_arg<'a>(&self, index: u32, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromBool],
|
||||
ParsedType::I8(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
|
||||
ParsedType::I16(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
|
||||
ParsedType::I32(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS32],
|
||||
ParsedType::I64(_) => vec![Instruction::ArgumentGet { index }, Instruction::I64FromS64],
|
||||
ParsedType::U8(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU8],
|
||||
ParsedType::U16(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU16],
|
||||
ParsedType::U32(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromU32],
|
||||
ParsedType::U64(_) => vec![Instruction::ArgumentGet { index }, Instruction::I64FromU64],
|
||||
ParsedType::F32(_) => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::F64(_) => vec![Instruction::ArgumentGet { index }],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
|
||||
vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: type_tag },
|
||||
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::StringLowerMemory,
|
||||
]
|
||||
},
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArrayLowerMemory {
|
||||
value_type
|
||||
},
|
||||
]
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
vec! [
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::RecordLowerMemory { record_type_id },
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2021 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 super::ITResolver;
|
||||
use super::ptype_to_itype_checked;
|
||||
use crate::default_export_api_config::*;
|
||||
use crate::Result;
|
||||
|
||||
use marine_macro_impl::ParsedType;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
|
||||
/// Generates IT instructions for a output type of an export function.
|
||||
pub(super) trait OutputITGenerator {
|
||||
fn generate_instructions_for_output_type<'a>(
|
||||
&self,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
}
|
||||
|
||||
impl OutputITGenerator for ParsedType {
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_output_type<'a>(&self, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::BoolFromI32],
|
||||
ParsedType::I8(_) => vec![Instruction::S8FromI32],
|
||||
ParsedType::I16(_) => vec![Instruction::S16FromI32],
|
||||
ParsedType::I32(_) => vec![Instruction::S32FromI32],
|
||||
ParsedType::I64(_) => vec![Instruction::S64FromI64],
|
||||
ParsedType::U8(_) => vec![Instruction::U8FromI32],
|
||||
ParsedType::U16(_) => vec![Instruction::U16FromI32],
|
||||
ParsedType::U32(_) => vec![Instruction::U32FromI32],
|
||||
ParsedType::U64(_) => vec![Instruction::U64FromI64],
|
||||
ParsedType::F32(_) => vec![],
|
||||
ParsedType::F64(_) => vec![],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::StringLiftMemory,
|
||||
],
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
if let IType::U8 = value_type {
|
||||
vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::ByteArrayLiftMemory,
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::ArrayLiftMemory { value_type },
|
||||
]
|
||||
}
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
vec! [
|
||||
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||
Instruction::RecordLiftMemory { record_type_id },
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
}
|
@ -14,17 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod args_it_generator;
|
||||
mod output_type_it_generator;
|
||||
|
||||
use super::ITGenerator;
|
||||
use super::ITResolver;
|
||||
use super::utils::ptype_to_itype_checked;
|
||||
use super::utils::*;
|
||||
use crate::Result;
|
||||
use crate::default_export_api_config::*;
|
||||
use crate::default_export_api_config::RELEASE_OBJECTS;
|
||||
use crate::instructions_generator::utils::wtype_to_itype;
|
||||
|
||||
use marine_macro_impl::ExternModType;
|
||||
use marine_macro_impl::ExternFnType;
|
||||
use marine_macro_impl::ParsedType;
|
||||
use marine_macro_impl::FnArgument;
|
||||
use marine_macro_impl::FnSignature;
|
||||
use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
@ -49,108 +53,76 @@ impl ITGenerator for ExternModType {
|
||||
}
|
||||
|
||||
fn generate_it_for_import<'a>(
|
||||
import: &'a ExternFnType,
|
||||
fn_type: &'a ExternFnType,
|
||||
namespace: &'a str,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<()> {
|
||||
use wasmer_it::ast::Type;
|
||||
use wasmer_it::ast::Adapter;
|
||||
generate_it_types(fn_type, namespace, it_resolver)?;
|
||||
generate_it_instructions(fn_type, it_resolver)
|
||||
}
|
||||
|
||||
let arguments = import
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| -> Result<IFunctionArg> {
|
||||
Ok(IFunctionArg {
|
||||
name: arg.name.clone(),
|
||||
ty: ptype_to_itype_checked(&arg.ty, it_resolver)?,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
let arguments = Rc::new(arguments);
|
||||
fn generate_it_types<'f>(
|
||||
fn_type: &'f ExternFnType,
|
||||
namespace: &'f str,
|
||||
it_resolver: &mut ITResolver<'f>,
|
||||
) -> Result<()> {
|
||||
let arguments = generate_it_args(&fn_type.signature, it_resolver)?;
|
||||
let output_types = generate_it_output_type(&fn_type.signature, it_resolver)?;
|
||||
it_resolver.add_fn_type(arguments, output_types);
|
||||
|
||||
let output_types = import
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
.map(|ty| ptype_to_itype_checked(ty, it_resolver))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
let output_types = Rc::new(output_types);
|
||||
let raw_arguments = generate_raw_args(&fn_type.signature);
|
||||
let raw_output_types = generate_raw_output_type(&fn_type.signature);
|
||||
it_resolver.add_fn_type(raw_arguments.clone(), raw_output_types.clone());
|
||||
it_resolver.add_fn_type(raw_arguments, raw_output_types);
|
||||
|
||||
let interfaces = &mut it_resolver.interfaces;
|
||||
interfaces.types.push(Type::Function {
|
||||
arguments,
|
||||
output_types,
|
||||
});
|
||||
let types_count = it_resolver.interfaces.types.len() as u32;
|
||||
let import_idx = types_count - 3;
|
||||
let raw_import_idx = types_count - 1;
|
||||
|
||||
let raw_inputs = import
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(to_raw_input_types)
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
let raw_inputs = Rc::new(raw_inputs);
|
||||
|
||||
let raw_outputs = import
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
to_raw_output_type(ty)
|
||||
.iter()
|
||||
.map(wtype_to_itype)
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
let raw_outputs = Rc::new(raw_outputs);
|
||||
|
||||
interfaces.types.push(Type::Function {
|
||||
arguments: raw_inputs.clone(),
|
||||
output_types: raw_outputs.clone(),
|
||||
});
|
||||
|
||||
interfaces.types.push(Type::Function {
|
||||
arguments: raw_inputs,
|
||||
output_types: raw_outputs,
|
||||
});
|
||||
|
||||
let adapter_idx = (interfaces.types.len() - 2) 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 {
|
||||
let link_name = match &fn_type.link_name {
|
||||
Some(link_name) => link_name,
|
||||
None => &import.signature.name,
|
||||
None => &fn_type.signature.name,
|
||||
};
|
||||
|
||||
interfaces.imports.push(wasmer_it::ast::Import {
|
||||
namespace: &namespace,
|
||||
name: link_name,
|
||||
function_type: import_idx,
|
||||
});
|
||||
it_resolver.add_import(namespace, link_name, import_idx);
|
||||
it_resolver.add_import(namespace, link_name, raw_import_idx);
|
||||
|
||||
interfaces.imports.push(wasmer_it::ast::Import {
|
||||
namespace: &namespace,
|
||||
name: link_name,
|
||||
function_type: raw_import_idx,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let mut instructions = import
|
||||
fn generate_it_instructions<'f>(
|
||||
fn_type: &'f ExternFnType,
|
||||
it_resolver: &mut ITResolver<'f>,
|
||||
) -> Result<()> {
|
||||
use args_it_generator::ArgumentITGenerator;
|
||||
use output_type_it_generator::OutputITGenerator;
|
||||
|
||||
let adapter_idx = (it_resolver.interfaces.types.len() - 2) as u32;
|
||||
let raw_import_idx = (it_resolver.interfaces.types.len() - 1) as u32;
|
||||
|
||||
let mut should_generate_release = false;
|
||||
let mut instructions = fn_type
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.try_fold::<_, _, Result<_>>((0, Vec::new()), |(arg_id, mut instructions), arg| {
|
||||
let (new_instructions, shift) = arg
|
||||
.ty
|
||||
.generate_instructions_for_input_type(arg_id as _, it_resolver)?;
|
||||
.generate_instructions_for_arg(arg_id as _, it_resolver)?;
|
||||
|
||||
should_generate_release |= arg.ty.is_complex_type();
|
||||
|
||||
instructions.extend(new_instructions);
|
||||
Ok((arg_id + shift, instructions))
|
||||
})?
|
||||
.1;
|
||||
|
||||
if should_generate_release {
|
||||
instructions.push(Instruction::CallCore {
|
||||
function_index: RELEASE_OBJECTS.id,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: refactor
|
||||
let import_function_index = (it_resolver.interfaces.exports.len()
|
||||
+ it_resolver.interfaces.imports.len() / 2
|
||||
@ -159,7 +131,7 @@ fn generate_it_for_import<'a>(
|
||||
function_index: import_function_index,
|
||||
});
|
||||
|
||||
let instructions = import
|
||||
let instructions = fn_type
|
||||
.signature
|
||||
.output_types
|
||||
.iter()
|
||||
@ -170,137 +142,37 @@ fn generate_it_for_import<'a>(
|
||||
Ok(instructions)
|
||||
})?;
|
||||
|
||||
let adapter = Adapter {
|
||||
function_type: adapter_idx,
|
||||
instructions,
|
||||
};
|
||||
it_resolver.interfaces.adapters.push(adapter);
|
||||
|
||||
let implementation = wasmer_it::ast::Implementation {
|
||||
core_function_type: raw_import_idx,
|
||||
adapter_function_type: adapter_idx,
|
||||
};
|
||||
it_resolver.interfaces.implementations.push(implementation);
|
||||
it_resolver.add_adapter(adapter_idx, instructions);
|
||||
it_resolver.add_implementation(raw_import_idx, adapter_idx);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Generate IT instructions for a foreign mod.
|
||||
trait ForeignModInstructionGenerator {
|
||||
fn generate_instructions_for_input_type<'a>(
|
||||
&self,
|
||||
arg_id: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<(Vec<Instruction>, u32)>;
|
||||
pub(crate) fn generate_raw_args<'f>(signature: &FnSignature) -> Rc<Vec<IFunctionArg>> {
|
||||
let raw_inputs = signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(to_raw_input_types)
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
fn generate_instructions_for_output_type<'a>(
|
||||
&self,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
Rc::new(raw_inputs)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl ForeignModInstructionGenerator for ParsedType {
|
||||
fn generate_instructions_for_input_type<'a>(
|
||||
&self,
|
||||
index: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<(Vec<Instruction>, u32)> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => (vec![Instruction::ArgumentGet { index }, Instruction::BoolFromI32], 1),
|
||||
ParsedType::I8(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32], 1),
|
||||
ParsedType::I16(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32], 1),
|
||||
ParsedType::I32(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S32FromI32], 1),
|
||||
ParsedType::I64(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S64FromI64], 1),
|
||||
ParsedType::U8(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U8FromI32], 1),
|
||||
ParsedType::U16(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U16FromI32], 1),
|
||||
ParsedType::U32(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U32FromI32], 1),
|
||||
ParsedType::U64(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U64FromI64], 1),
|
||||
ParsedType::F32(_) => (vec![Instruction::ArgumentGet { index }], 1),
|
||||
ParsedType::F64(_) => (vec![Instruction::ArgumentGet { index }], 1),
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => (vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::StringLiftMemory,
|
||||
], 2),
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
if let IType::U8 = value_type {
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::ByteArrayLiftMemory,
|
||||
], 2)
|
||||
} else {
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::ArrayLiftMemory { value_type },
|
||||
], 2)
|
||||
}
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
pub(crate) fn generate_raw_output_type<'f>(signature: &FnSignature) -> Rc<Vec<IType>> {
|
||||
let raw_outputs = signature
|
||||
.output_types
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
to_raw_output_type(ty)
|
||||
.iter()
|
||||
.map(wtype_to_itype)
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::RecordLiftMemory { record_type_id },
|
||||
], 1)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_output_type<'a>(&self, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::I32FromBool],
|
||||
ParsedType::I8(_) => vec![Instruction::I32FromS8],
|
||||
ParsedType::I16(_) => vec![Instruction::I32FromS16],
|
||||
ParsedType::I32(_) => vec![Instruction::I32FromS32],
|
||||
ParsedType::I64(_) => vec![Instruction::I64FromS64],
|
||||
ParsedType::U8(_) => vec![Instruction::I32FromU8],
|
||||
ParsedType::U16(_) => vec![Instruction::I32FromU16],
|
||||
ParsedType::U32(_) => vec![Instruction::I32FromU32],
|
||||
ParsedType::U64(_) => vec![Instruction::I64FromU64],
|
||||
ParsedType::F32(_) => vec![],
|
||||
ParsedType::F64(_) => vec![],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
|
||||
|
||||
vec![
|
||||
Instruction::Dup,
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: type_tag },
|
||||
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
|
||||
Instruction::Swap2,
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
|
||||
vec![
|
||||
Instruction::ArrayLowerMemory { value_type },
|
||||
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
vec![
|
||||
Instruction::RecordLowerMemory { record_type_id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
Rc::new(raw_outputs)
|
||||
}
|
||||
|
||||
use marine_macro_impl::RustType;
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2021 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 super::ITResolver;
|
||||
use super::ptype_to_itype_checked;
|
||||
use crate::Result;
|
||||
|
||||
use marine_macro_impl::ParsedType;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
|
||||
/// Generate IT instructions for a foreign mod.
|
||||
pub(super) trait ArgumentITGenerator {
|
||||
fn generate_instructions_for_arg<'a>(
|
||||
&self,
|
||||
arg_id: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<(Vec<Instruction>, u32)>;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl ArgumentITGenerator for ParsedType {
|
||||
fn generate_instructions_for_arg<'a>(
|
||||
&self,
|
||||
index: u32,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<(Vec<Instruction>, u32)> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => (vec![Instruction::ArgumentGet { index }, Instruction::BoolFromI32], 1),
|
||||
ParsedType::I8(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32], 1),
|
||||
ParsedType::I16(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32], 1),
|
||||
ParsedType::I32(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S32FromI32], 1),
|
||||
ParsedType::I64(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S64FromI64], 1),
|
||||
ParsedType::U8(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U8FromI32], 1),
|
||||
ParsedType::U16(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U16FromI32], 1),
|
||||
ParsedType::U32(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U32FromI32], 1),
|
||||
ParsedType::U64(_) => (vec![Instruction::ArgumentGet { index }, Instruction::U64FromI64], 1),
|
||||
ParsedType::F32(_) => (vec![Instruction::ArgumentGet { index }], 1),
|
||||
ParsedType::F64(_) => (vec![Instruction::ArgumentGet { index }], 1),
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => (vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::StringLiftMemory,
|
||||
], 2),
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
if let IType::U8 = value_type {
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::ByteArrayLiftMemory,
|
||||
], 2)
|
||||
} else {
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::ArgumentGet { index: index + 1 },
|
||||
Instruction::ArrayLiftMemory { value_type },
|
||||
], 2)
|
||||
}
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
(vec![
|
||||
Instruction::ArgumentGet { index },
|
||||
Instruction::RecordLiftMemory { record_type_id },
|
||||
], 1)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2021 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 super::ITResolver;
|
||||
use super::ptype_to_itype_checked;
|
||||
use crate::Result;
|
||||
use crate::default_export_api_config::*;
|
||||
|
||||
use marine_macro_impl::ParsedType;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
|
||||
/// Generate IT instructions for a foreign mod.
|
||||
pub(super) trait OutputITGenerator {
|
||||
fn generate_instructions_for_output_type<'a>(
|
||||
&self,
|
||||
it_resolver: &mut ITResolver<'a>,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl OutputITGenerator for ParsedType {
|
||||
#[rustfmt::skip]
|
||||
fn generate_instructions_for_output_type<'a>(&self, it_resolver: &mut ITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||
let instructions = match self {
|
||||
ParsedType::Boolean(_) => vec![Instruction::I32FromBool],
|
||||
ParsedType::I8(_) => vec![Instruction::I32FromS8],
|
||||
ParsedType::I16(_) => vec![Instruction::I32FromS16],
|
||||
ParsedType::I32(_) => vec![Instruction::I32FromS32],
|
||||
ParsedType::I64(_) => vec![Instruction::I64FromS64],
|
||||
ParsedType::U8(_) => vec![Instruction::I32FromU8],
|
||||
ParsedType::U16(_) => vec![Instruction::I32FromU16],
|
||||
ParsedType::U32(_) => vec![Instruction::I32FromU32],
|
||||
ParsedType::U64(_) => vec![Instruction::I64FromU64],
|
||||
ParsedType::F32(_) => vec![],
|
||||
ParsedType::F64(_) => vec![],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
|
||||
|
||||
vec![
|
||||
Instruction::Dup,
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: type_tag },
|
||||
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
|
||||
Instruction::Swap2,
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
ParsedType::Vector(value_type, _) => {
|
||||
let value_type = ptype_to_itype_checked(value_type, it_resolver)?;
|
||||
|
||||
vec![
|
||||
Instruction::ArrayLowerMemory { value_type },
|
||||
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_type_id = it_resolver.get_record_type_id(record_name)? as u32;
|
||||
|
||||
vec![
|
||||
Instruction::RecordLowerMemory { record_type_id },
|
||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
Ok(instructions)
|
||||
}
|
||||
}
|
@ -22,7 +22,6 @@ use marine_macro_impl::RecordType;
|
||||
use marine_macro_impl::RecordFields;
|
||||
|
||||
use wasmer_it::IRecordFieldType;
|
||||
use wasmer_it::IRecordType;
|
||||
use wasmer_it::NEVec;
|
||||
|
||||
impl ITGenerator for RecordType {
|
||||
@ -48,12 +47,7 @@ impl ITGenerator for RecordType {
|
||||
))
|
||||
})?;
|
||||
|
||||
let new_record_type = IRecordType {
|
||||
name: self.name.clone(),
|
||||
fields,
|
||||
};
|
||||
|
||||
it_resolver.insert_record_type(new_record_type);
|
||||
it_resolver.add_record_type(self.name.clone(), fields);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
334
crates/it-generator/src/instructions_generator/tests.rs
Normal file
334
crates/it-generator/src/instructions_generator/tests.rs
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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 super::ITGenerator;
|
||||
use crate::default_export_api_config::RELEASE_OBJECTS;
|
||||
use crate::instructions_generator::ITResolver;
|
||||
|
||||
use marine_macro_impl::*;
|
||||
use wasmer_it::interpreter::Instruction;
|
||||
use wasmer_it::IType;
|
||||
|
||||
fn generate_export_fn(args: Vec<ParsedType>, output: Option<ParsedType>) -> FnType {
|
||||
let name = String::from("some_fn_name");
|
||||
|
||||
let arguments = args
|
||||
.into_iter()
|
||||
.map(|ty| FnArgument {
|
||||
name: String::from("arg_name"),
|
||||
ty,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let output_types = match output {
|
||||
Some(output) => vec![output],
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
let signature = FnSignature {
|
||||
name,
|
||||
arguments,
|
||||
output_types,
|
||||
};
|
||||
|
||||
FnType { signature }
|
||||
}
|
||||
|
||||
fn generate_import_mod(args: Vec<ParsedType>, output: Option<ParsedType>) -> ExternModType {
|
||||
let name = String::from("some_fn_name");
|
||||
|
||||
let arguments = args
|
||||
.into_iter()
|
||||
.map(|ty| FnArgument {
|
||||
name: String::from("arg_name"),
|
||||
ty,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let output_types = match output {
|
||||
Some(output) => vec![output],
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
let signature = FnSignature {
|
||||
name,
|
||||
arguments,
|
||||
output_types,
|
||||
};
|
||||
|
||||
let extern_fn_type = ExternFnType {
|
||||
link_name: None,
|
||||
signature,
|
||||
};
|
||||
|
||||
ExternModType {
|
||||
namespace: String::from("some namespace"),
|
||||
imports: vec![extern_fn_type],
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_arg_types_in_export() {
|
||||
let args = vec![
|
||||
ParsedType::I8(PassingStyle::ByValue),
|
||||
ParsedType::I16(PassingStyle::ByValue),
|
||||
ParsedType::I32(PassingStyle::ByValue),
|
||||
ParsedType::I64(PassingStyle::ByValue),
|
||||
ParsedType::U8(PassingStyle::ByValue),
|
||||
ParsedType::U16(PassingStyle::ByValue),
|
||||
ParsedType::U32(PassingStyle::ByValue),
|
||||
ParsedType::U64(PassingStyle::ByValue),
|
||||
ParsedType::F32(PassingStyle::ByValue),
|
||||
ParsedType::F64(PassingStyle::ByValue),
|
||||
];
|
||||
|
||||
let outputs = Some(ParsedType::I32(PassingStyle::ByValue));
|
||||
let fn_type = generate_export_fn(args, outputs);
|
||||
|
||||
let mut it_resolver = ITResolver::default();
|
||||
fn_type
|
||||
.generate_it(&mut it_resolver)
|
||||
.expect("IT generation succeeded");
|
||||
|
||||
let interfaces = it_resolver.interfaces;
|
||||
|
||||
let actual_instruction = &interfaces.adapters[0].instructions;
|
||||
|
||||
let expected_instruction = vec![
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::I32FromS8,
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::I32FromS16,
|
||||
Instruction::ArgumentGet { index: 2 },
|
||||
Instruction::I32FromS32,
|
||||
Instruction::ArgumentGet { index: 3 },
|
||||
Instruction::I64FromS64,
|
||||
Instruction::ArgumentGet { index: 4 },
|
||||
Instruction::I32FromU8,
|
||||
Instruction::ArgumentGet { index: 5 },
|
||||
Instruction::I32FromU16,
|
||||
Instruction::ArgumentGet { index: 6 },
|
||||
Instruction::I32FromU32,
|
||||
Instruction::ArgumentGet { index: 7 },
|
||||
Instruction::I64FromU64,
|
||||
Instruction::ArgumentGet { index: 8 },
|
||||
Instruction::ArgumentGet { index: 9 },
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::S32FromI32,
|
||||
];
|
||||
|
||||
assert_eq!(actual_instruction, &expected_instruction);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_arg_types_in_export() {
|
||||
let args = vec![
|
||||
ParsedType::I8(PassingStyle::ByValue),
|
||||
ParsedType::I16(PassingStyle::ByValue),
|
||||
ParsedType::I32(PassingStyle::ByValue),
|
||||
ParsedType::I64(PassingStyle::ByValue),
|
||||
ParsedType::U8(PassingStyle::ByValue),
|
||||
ParsedType::U16(PassingStyle::ByValue),
|
||||
ParsedType::U32(PassingStyle::ByValue),
|
||||
ParsedType::U64(PassingStyle::ByValue),
|
||||
ParsedType::F32(PassingStyle::ByValue),
|
||||
ParsedType::F64(PassingStyle::ByValue),
|
||||
ParsedType::Utf8String(PassingStyle::ByValue),
|
||||
ParsedType::Vector(
|
||||
Box::new(ParsedType::U8(PassingStyle::ByValue)),
|
||||
PassingStyle::ByValue,
|
||||
),
|
||||
];
|
||||
|
||||
let outputs = Some(ParsedType::Utf8String(PassingStyle::ByValue));
|
||||
let fn_type = generate_export_fn(args, outputs);
|
||||
|
||||
let mut it_resolver = ITResolver::default();
|
||||
fn_type
|
||||
.generate_it(&mut it_resolver)
|
||||
.expect("IT generation succeeded");
|
||||
|
||||
let interfaces = it_resolver.interfaces;
|
||||
|
||||
let actual_instruction = &interfaces.adapters[0].instructions;
|
||||
|
||||
let expected_instruction = vec![
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::I32FromS8,
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::I32FromS16,
|
||||
Instruction::ArgumentGet { index: 2 },
|
||||
Instruction::I32FromS32,
|
||||
Instruction::ArgumentGet { index: 3 },
|
||||
Instruction::I64FromS64,
|
||||
Instruction::ArgumentGet { index: 4 },
|
||||
Instruction::I32FromU8,
|
||||
Instruction::ArgumentGet { index: 5 },
|
||||
Instruction::I32FromU16,
|
||||
Instruction::ArgumentGet { index: 6 },
|
||||
Instruction::I32FromU32,
|
||||
Instruction::ArgumentGet { index: 7 },
|
||||
Instruction::I64FromU64,
|
||||
Instruction::ArgumentGet { index: 8 },
|
||||
Instruction::ArgumentGet { index: 9 },
|
||||
Instruction::ArgumentGet { index: 10 },
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: 1 },
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::ArgumentGet { index: 10 },
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::ArgumentGet { index: 11 },
|
||||
Instruction::ArrayLowerMemory {
|
||||
value_type: IType::U8,
|
||||
},
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::CallCore { function_index: 3 },
|
||||
Instruction::CallCore { function_index: 2 },
|
||||
Instruction::StringLiftMemory,
|
||||
Instruction::CallCore {
|
||||
function_index: RELEASE_OBJECTS.id,
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(actual_instruction, &expected_instruction);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_arg_types_in_import() {
|
||||
let args = vec![
|
||||
ParsedType::I8(PassingStyle::ByValue),
|
||||
ParsedType::I16(PassingStyle::ByValue),
|
||||
ParsedType::I32(PassingStyle::ByValue),
|
||||
ParsedType::I64(PassingStyle::ByValue),
|
||||
ParsedType::U8(PassingStyle::ByValue),
|
||||
ParsedType::U16(PassingStyle::ByValue),
|
||||
ParsedType::U32(PassingStyle::ByValue),
|
||||
ParsedType::U64(PassingStyle::ByValue),
|
||||
ParsedType::F32(PassingStyle::ByValue),
|
||||
ParsedType::F64(PassingStyle::ByValue),
|
||||
];
|
||||
|
||||
let outputs = Some(ParsedType::I32(PassingStyle::ByValue));
|
||||
let import_fn_type = generate_import_mod(args, outputs);
|
||||
|
||||
let mut it_resolver = ITResolver::default();
|
||||
import_fn_type
|
||||
.generate_it(&mut it_resolver)
|
||||
.expect("IT generation succeeded");
|
||||
|
||||
let interfaces = it_resolver.interfaces;
|
||||
|
||||
let actual_instruction = &interfaces.adapters[0].instructions;
|
||||
|
||||
let expected_instruction = vec![
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::S8FromI32,
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::S16FromI32,
|
||||
Instruction::ArgumentGet { index: 2 },
|
||||
Instruction::S32FromI32,
|
||||
Instruction::ArgumentGet { index: 3 },
|
||||
Instruction::S64FromI64,
|
||||
Instruction::ArgumentGet { index: 4 },
|
||||
Instruction::U8FromI32,
|
||||
Instruction::ArgumentGet { index: 5 },
|
||||
Instruction::U16FromI32,
|
||||
Instruction::ArgumentGet { index: 6 },
|
||||
Instruction::U32FromI32,
|
||||
Instruction::ArgumentGet { index: 7 },
|
||||
Instruction::U64FromI64,
|
||||
Instruction::ArgumentGet { index: 8 },
|
||||
Instruction::ArgumentGet { index: 9 },
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::I32FromS32,
|
||||
];
|
||||
|
||||
assert_eq!(actual_instruction, &expected_instruction);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_arg_types_in_import() {
|
||||
let args = vec![
|
||||
ParsedType::I8(PassingStyle::ByValue),
|
||||
ParsedType::I16(PassingStyle::ByValue),
|
||||
ParsedType::I32(PassingStyle::ByValue),
|
||||
ParsedType::I64(PassingStyle::ByValue),
|
||||
ParsedType::U8(PassingStyle::ByValue),
|
||||
ParsedType::U16(PassingStyle::ByValue),
|
||||
ParsedType::U32(PassingStyle::ByValue),
|
||||
ParsedType::U64(PassingStyle::ByValue),
|
||||
ParsedType::F32(PassingStyle::ByValue),
|
||||
ParsedType::F64(PassingStyle::ByValue),
|
||||
ParsedType::Utf8String(PassingStyle::ByValue),
|
||||
ParsedType::Vector(
|
||||
Box::new(ParsedType::U8(PassingStyle::ByValue)),
|
||||
PassingStyle::ByValue,
|
||||
),
|
||||
];
|
||||
|
||||
let outputs = Some(ParsedType::Utf8String(PassingStyle::ByValue));
|
||||
let fn_type = generate_import_mod(args, outputs);
|
||||
|
||||
let mut it_resolver = ITResolver::default();
|
||||
fn_type
|
||||
.generate_it(&mut it_resolver)
|
||||
.expect("IT generation succeeded");
|
||||
|
||||
let interfaces = it_resolver.interfaces;
|
||||
|
||||
let actual_instruction = &interfaces.adapters[0].instructions;
|
||||
|
||||
let expected_instruction = vec![
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::S8FromI32,
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::S16FromI32,
|
||||
Instruction::ArgumentGet { index: 2 },
|
||||
Instruction::S32FromI32,
|
||||
Instruction::ArgumentGet { index: 3 },
|
||||
Instruction::S64FromI64,
|
||||
Instruction::ArgumentGet { index: 4 },
|
||||
Instruction::U8FromI32,
|
||||
Instruction::ArgumentGet { index: 5 },
|
||||
Instruction::U16FromI32,
|
||||
Instruction::ArgumentGet { index: 6 },
|
||||
Instruction::U32FromI32,
|
||||
Instruction::ArgumentGet { index: 7 },
|
||||
Instruction::U64FromI64,
|
||||
Instruction::ArgumentGet { index: 8 },
|
||||
Instruction::ArgumentGet { index: 9 },
|
||||
Instruction::ArgumentGet { index: 10 },
|
||||
Instruction::ArgumentGet { index: 11 },
|
||||
Instruction::StringLiftMemory,
|
||||
Instruction::ArgumentGet { index: 12 },
|
||||
Instruction::ArgumentGet { index: 13 },
|
||||
Instruction::ByteArrayLiftMemory,
|
||||
Instruction::CallCore {
|
||||
function_index: RELEASE_OBJECTS.id,
|
||||
},
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::Dup,
|
||||
Instruction::StringSize,
|
||||
Instruction::PushI32 { value: 1 },
|
||||
Instruction::CallCore { function_index: 0 },
|
||||
Instruction::Swap2,
|
||||
Instruction::StringLowerMemory,
|
||||
Instruction::CallCore { function_index: 4 },
|
||||
Instruction::CallCore { function_index: 5 },
|
||||
];
|
||||
|
||||
assert_eq!(actual_instruction, &expected_instruction);
|
||||
}
|
@ -18,8 +18,12 @@ use super::IType;
|
||||
use crate::instructions_generator::ITResolver;
|
||||
use crate::Result;
|
||||
|
||||
use marine_macro_impl::FnSignature;
|
||||
use marine_macro_impl::ParsedType;
|
||||
use marine_macro_impl::RustType;
|
||||
use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
// return error if there is no record with such name
|
||||
pub(crate) fn ptype_to_itype_checked(
|
||||
@ -102,3 +106,37 @@ pub(crate) fn wtype_to_itype(pty: &RustType) -> IType {
|
||||
RustType::F64 => IType::F64,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_it_args<'f>(
|
||||
signature: &FnSignature,
|
||||
it_resolver: &mut ITResolver<'f>,
|
||||
) -> Result<Rc<Vec<IFunctionArg>>> {
|
||||
let arguments = signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| -> Result<IFunctionArg> {
|
||||
Ok(IFunctionArg {
|
||||
name: arg.name.clone(),
|
||||
ty: ptype_to_itype_checked(&arg.ty, it_resolver)?,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let arguments = Rc::new(arguments);
|
||||
Ok(arguments)
|
||||
}
|
||||
|
||||
pub(crate) fn generate_it_output_type<'f>(
|
||||
signature: &FnSignature,
|
||||
it_resolver: &mut ITResolver<'f>,
|
||||
) -> Result<Rc<Vec<IType>>> {
|
||||
let output_types = signature
|
||||
.output_types
|
||||
.iter()
|
||||
.map(|ty| ptype_to_itype_checked(ty, it_resolver))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let output_types = Rc::new(output_types);
|
||||
|
||||
Ok(output_types)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ name = "marine_module_info_parser"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence-sdk-main = "0.6.3"
|
||||
fluence-sdk-main = "0.6.9"
|
||||
|
||||
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0" }
|
||||
|
||||
|
@ -10,7 +10,7 @@ name = "call_parameters"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
|
||||
[dev-dependencies]
|
||||
fluence-test = "0.1.7"
|
||||
|
@ -12,7 +12,7 @@ name = "greeting"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
|
||||
[dev-dependencies]
|
||||
fluence-test = "0.1.7"
|
||||
|
@ -10,5 +10,5 @@ name = "records_effector"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
test-record = { path = "../test-record" }
|
||||
|
@ -10,5 +10,5 @@ name = "records_pure"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
test-record = { path = "../test-record" }
|
||||
|
@ -10,4 +10,4 @@ name = "test_record"
|
||||
path = "src/test_record.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
|
@ -10,5 +10,5 @@ name = "sqlite_test"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
marine-sqlite-connector = "0.4.0"
|
||||
|
@ -9,7 +9,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
marine-runtime = { path = "../runtime", version = "0.5.0" }
|
||||
marine-utils = { path = "../crates/utils", version = "0.2.0" }
|
||||
fluence-sdk-main = { version = "0.6.3", features = ["logger"] }
|
||||
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
||||
fluence = { version = "0.6.3", features = ["logger"] }
|
||||
|
||||
wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
|
||||
|
@ -14,5 +14,5 @@ name = "arrays_passing_effector"
|
||||
path = "src/effector.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
safe-transmute = "0.11.0"
|
||||
|
@ -14,5 +14,5 @@ name = "records_passing_pure"
|
||||
path = "src/pure.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence = "0.6.4"
|
||||
fluence = "0.6.9"
|
||||
safe-transmute = "0.11.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "marine"
|
||||
description = "Fluence Marine command line tool"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
authors = ["Fluence Labs"]
|
||||
repository = "https://github.com/fluencelabs/marine/tools/cli"
|
||||
license = "Apache-2.0"
|
||||
|
@ -13,7 +13,7 @@ path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
fluence-app-service = { path = "../../fluence-app-service", version = "0.7.1", features = ["raw-module-api"] }
|
||||
fluence-sdk-main = { version = "0.6.3", features = ["logger"] }
|
||||
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
||||
|
||||
anyhow = "1.0.31"
|
||||
clap = "2.33.1"
|
||||
|
Loading…
Reference in New Issue
Block a user