Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ wasmtime-wasi = "=31.0.0"
deterministic-wasi-ctx = "=1.0.0"
anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] }
serde_json = "1.0"
serde_json = { version = "1.0", features = ["preserve_order"] }
colored = "3.0"
serde = "1.0"
rust-embed = "8.9.0"
Expand Down
18 changes: 18 additions & 0 deletions src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,21 @@ impl BytesContainer {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn json_input_preserves_object_key_order_in_raw_bytes() {
let raw = br#"{"msg":{"sq-XK":"5.00 EUR Zbritje","en":"5.00 EUR Discount"}}"#.to_vec();

let input = BytesContainer::new(BytesContainerType::Input, Codec::Json, raw.clone())
.expect("valid JSON input");

assert_eq!(
String::from_utf8(input.raw).unwrap(),
String::from_utf8(raw).unwrap()
);
}
}
21 changes: 20 additions & 1 deletion src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use wasmtime_wasi::I32Exit;

use crate::function_run_result::FunctionRunResult;
use crate::io::{IOHandler, OutputAndLogs};
pub use crate::validated_module::CompiledProvider;
use crate::validated_module::ValidatedModule;
use crate::{BytesContainer, BytesContainerType};

Expand Down Expand Up @@ -88,7 +89,21 @@ impl ResourceLimiter for MemoryLimiter {
}
}

pub fn compile_standard_provider(
module: &Module,
engine: &Engine,
) -> Result<Option<CompiledProvider>> {
ValidatedModule::compile_standard_provider(module, engine)
}

pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
run_with_compiled_provider(params, None)
}

pub fn run_with_compiled_provider(
params: FunctionRunParams,
compiled_provider: Option<&CompiledProvider>,
) -> Result<FunctionRunResult> {
let FunctionRunParams {
function_path,
input,
Expand All @@ -99,7 +114,11 @@ pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
module,
} = params;

let mut io_handler = IOHandler::new(ValidatedModule::new(module)?, input.clone());
let mut io_handler = IOHandler::new_with_compiled_provider(
ValidatedModule::new(module)?,
input.clone(),
compiled_provider.cloned(),
);

let mut error_logs: String = String::new();

Expand Down
39 changes: 32 additions & 7 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use wasmtime_wasi::{
};

use crate::{
function_run_result::FUNCTION_LOG_LIMIT, validated_module::ValidatedModule, BytesContainer,
function_run_result::FUNCTION_LOG_LIMIT,
validated_module::{CompiledProvider, ValidatedModule},
BytesContainer,
};

pub(crate) struct OutputAndLogs {
Expand All @@ -29,10 +31,15 @@ pub(crate) struct IOHandler {
strategy: IOStrategy,
module: ValidatedModule,
input: BytesContainer,
compiled_provider: Option<CompiledProvider>,
}

impl IOHandler {
pub(crate) fn new(module: ValidatedModule, input: BytesContainer) -> Self {
pub(crate) fn new_with_compiled_provider(
module: ValidatedModule,
input: BytesContainer,
compiled_provider: Option<CompiledProvider>,
) -> Self {
Self {
strategy: if module.uses_mem_io() {
IOStrategy::Memory(None)
Expand All @@ -44,6 +51,7 @@ impl IOHandler {
},
module,
input,
compiled_provider,
}
}

Expand Down Expand Up @@ -75,7 +83,13 @@ impl IOHandler {
store.set_epoch_deadline(1); // Need to make sure we don't timeout during initialization.
let old_fuel = store.get_fuel()?;
store.set_fuel(u64::MAX)?; // Make sure we have fuel for initialization.
let mem_io_instance = instantiate_imports(&self.module, engine, linker, store);
let mem_io_instance = instantiate_imports(
&self.module,
self.compiled_provider.as_ref(),
engine,
linker,
store,
);
if let IOStrategy::Memory(ref mut instance) = self.strategy {
*instance = mem_io_instance;
}
Expand Down Expand Up @@ -157,21 +171,32 @@ impl IOHandler {

fn instantiate_imports<T>(
module: &ValidatedModule,
compiled_provider: Option<&CompiledProvider>,
engine: &Engine,
linker: &mut Linker<T>,
mut store: &mut Store<T>,
) -> Option<Instance> {
let mut mem_io_instance = None;

if let Some(std_import) = module.std_import() {
let imported_module = Module::from_binary(engine, &std_import.bytes)
.unwrap_or_else(|_| panic!("Failed to load module {}", std_import.name));
let fallback_module;
let (imported_module, is_mem_io_provider) = match compiled_provider {
Some(compiled_provider) if compiled_provider.name() == std_import.name => (
compiled_provider.module(),
compiled_provider.is_mem_io_provider(),
),
_ => {
fallback_module = Module::from_binary(engine, &std_import.bytes)
.unwrap_or_else(|_| panic!("Failed to load module {}", std_import.name));
(&fallback_module, std_import.is_mem_io_provider())
}
};

let imported_module_instance = linker
.instantiate(&mut store, &imported_module)
.instantiate(&mut store, imported_module)
.expect("Failed to instantiate imported instance");

if std_import.is_mem_io_provider() {
if is_mem_io_provider {
mem_io_instance = Some(imported_module_instance);
}

Expand Down
Loading
Loading