From efdfd31aab30bf4aaca000c044d07b8f4b66f4b5 Mon Sep 17 00:00:00 2001 From: Alex Snaps Date: Mon, 5 Jun 2023 12:57:08 -0400 Subject: [PATCH] API changes to newer wasmtime Signed-off-by: Alex Snaps --- Cargo.toml | 8 +- src/hostcalls.rs | 637 +++++++++++++++++++++++++---------------------- src/tester.rs | 415 +++++++++++++++++------------- src/utility.rs | 2 +- 4 files changed, 580 insertions(+), 482 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 73aa990..b636495 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "2482bd80c24a6b23ac1a259df77c61d5cc9c93a9" } -anyhow = "1.0.31" +wasmtime = "11.0.0" +anyhow = "1.0.72" lazy_static = "1.4.0" -more-asserts = "0.2.1" -rand = "0.7.3" +more-asserts = "0.3.1" +rand = "0.8.5" structopt = "0.3.16" diff --git a/src/hostcalls.rs b/src/hostcalls.rs index d4a90d3..54cb163 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -39,9 +39,9 @@ pub fn get_status() -> ExpectStatus { } pub fn get_abi_version(module: &Module) -> AbiVersion { - if module.get_export("proxy_abi_version_0_1_0") != None { + if module.get_export("proxy_abi_version_0_1_0").is_some() { AbiVersion::ProxyAbiVersion0_1_0 - } else if module.get_export("proxy_abi_version_0_2_0") != None { + } else if module.get_export("proxy_abi_version_0_2_0").is_some() { AbiVersion::ProxyAbiVersion0_2_0 } else { panic!("Error: test-framework does not support proxy-wasm modules of this abi version"); @@ -49,7 +49,7 @@ pub fn get_abi_version(module: &Module) -> AbiVersion { } pub fn generate_import_list( - store: &Store, + store: &mut Store<()>, module: &Module, func_vec: Arc>>, ) -> (Arc>, Arc>) { @@ -57,7 +57,7 @@ pub fn generate_import_list( HOST.lock().unwrap().staged.set_abi_version(abi_version); let imports = module.imports(); for import in imports { - match get_hostfunc(&store, abi_version, &import) { + match get_hostfunc(store, abi_version, &import) { Some(func) => (*func_vec).lock().unwrap().push(func.into()), None => panic!("Error: failed to acquire \"{}\"", import.name()), } @@ -65,13 +65,20 @@ pub fn generate_import_list( (HOST.clone(), EXPECT.clone()) } -fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> Option { +fn get_hostfunc( + store: &mut Store<()>, + _abi_version: AbiVersion, + import: &ImportType, +) -> Option { match import.name() { /* ---------------------------------- Configuration and Status ---------------------------------- */ "proxy_get_configuration" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _return_buffer_data: i32, _return_buffer_size: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, + _return_buffer_data: i32, + _return_buffer_size: i32| + -> i32 { // Default Function: // Expectation: assert_eq!( @@ -90,8 +97,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_get_status" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _status_code_ptr: i32, _message_ptr: i32, _message_size: i32| @@ -114,8 +121,12 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Logging ---------------------------------- */ "proxy_log" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, level: i32, message_data: i32, message_size: i32| -> i32 { + store, + |mut caller: Caller<'_, ()>, + level: i32, + message_data: i32, + message_size: i32| + -> i32 { // Default Function: retrieve and display log message from proxy-wasm module // Expectation: ensure the log level and the message data are as expected let mem = match caller.get_export("memory") { @@ -130,32 +141,30 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } }; - unsafe { - let data = mem - .data_unchecked() - .get(message_data as u32 as usize..) - .and_then(|arr| arr.get(..message_size as u32 as usize)); - - let string_msg = - data.map(|string_msg| std::str::from_utf8(string_msg).unwrap()); - let string_msg = match string_msg { - Some(s) => s, - _ => "invalid utf-8 slice", - }; + let data = mem + .data(&mut caller) + .get(message_data as u32 as usize..) + .and_then(|arr| arr.get(..message_size as u32 as usize)); - EXPECT - .lock() - .unwrap() - .staged - .get_expect_log(level, string_msg); - println!( - "[vm->host] proxy_log(level={}, message_data=\"{}\") status: {:?}", - level, - string_msg, - get_status() - ); - // println!("[vm<-host] proxy_log(...) return: {:?}", Status::Ok) - } + let string_msg = + data.map(|string_msg| std::str::from_utf8(string_msg).unwrap()); + let string_msg = match string_msg { + Some(s) => s, + _ => "invalid utf-8 slice", + }; + + EXPECT + .lock() + .unwrap() + .staged + .get_expect_log(level, string_msg); + println!( + "[vm->host] proxy_log(level={}, message_data=\"{}\") status: {:?}", + level, + string_msg, + get_status() + ); + // println!("[vm<-host] proxy_log(...) return: {:?}", Status::Ok) assert_ne!(get_status(), ExpectStatus::Failed); set_status(ExpectStatus::Unexpected); return Status::Ok as i32; @@ -165,8 +174,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_get_log_level" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _level: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, _level: i32| -> i32 { // Default Function: // Expectation: println!( @@ -185,8 +194,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Timer ---------------------------------- */ "proxy_set_tick_period_milliseconds" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, period: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, period: i32| -> i32 { // Default Function: receive and store tick period from proxy-wasm module // Expectation: assert received tick period is equal to expected HOST.lock() @@ -218,8 +227,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Time ---------------------------------- */ "proxy_get_current_time_nanoseconds" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, return_time: i32| -> i32 { + store, + |mut caller: Caller<'_, ()>, return_time: i32| -> i32 { // Default Function: respond to proxy-wasm module with the current time // Expectation: respond with a pre-set expected time let mem = match caller.get_export("memory") { @@ -245,7 +254,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; unsafe { - let data = mem.data_unchecked_mut().get_unchecked_mut( + let data = mem.data_mut(&mut caller).get_unchecked_mut( return_time as u32 as usize..return_time as u32 as usize + 8, ); @@ -269,8 +278,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- State Accessors ---------------------------------- */ "proxy_get_property" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _path_data: i32, _path_size: i32, _return_value_data: i32, @@ -290,8 +299,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_set_property" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _path_data: i32, _path_size: i32, _value_data: i32, @@ -311,7 +320,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Continue/Close/Reply/Route ---------------------------------- */ "proxy_continue_stream" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: assert_eq!( @@ -333,7 +342,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_close_stream" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: assert_eq!( @@ -349,7 +358,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_continue_request" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: assert_eq!( @@ -371,7 +380,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_continue_response" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: assert_eq!( @@ -394,8 +403,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_send_local_response" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, status_code: i32, _status_code_details_data: i32, _status_code_details_size: i32, @@ -425,14 +434,14 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> let mut string_body: Option<&str> = None; if body_size > 0 { let body_data_ptr = mem - .data_unchecked() + .data(&caller) .get(body_data as u32 as usize..) .and_then(|arr| arr.get(..body_size as u32 as usize)); string_body = body_data_ptr .map(|string_msg| std::str::from_utf8(string_msg).unwrap()); } - let header_data_ptr = mem.data_unchecked().get_unchecked( + let header_data_ptr = mem.data(&caller).get_unchecked( headers_data as u32 as usize ..headers_data as u32 as usize + headers_size as u32 as usize, ); @@ -469,7 +478,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_clear_route_cache" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!( @@ -487,8 +496,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- SharedData ---------------------------------- */ "proxy_get_shared_data" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _key_data: i32, _key_size: i32, _return_value_data: i32, @@ -506,8 +515,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_set_shared_data" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _key_data: i32, _key_size: i32, _value_data: i32, @@ -529,8 +538,12 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- SharedQueue ---------------------------------- */ "proxy_register_shared_queue" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _name_data: i32, _name_size: i32, _return_id: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, + _name_data: i32, + _name_size: i32, + _return_id: i32| + -> i32 { // Default Function: // Expectation: println!("[vm->host] proxy_register_shared_queue(name_data, name_size) -> (...) status: {:?}", get_status()); @@ -545,8 +558,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_resolve_shared_queue" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _vm_id_data: i32, _vm_id_size: i32, _name_data: i32, @@ -567,8 +580,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_dequeue_shared_queue" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _queue_id: i32, _payload_data: i32, _payload_size: i32| @@ -587,8 +600,12 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_enqueue_shared_queue" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _queue_id: i32, _value_data: i32, _value_size: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, + _queue_id: i32, + _value_data: i32, + _value_size: i32| + -> i32 { // Default Function: // Expectation: println!("[vm->host] proxy_enqueue_shared_queue(queue_id, value_data, value_size) status: {:?}", get_status()); @@ -604,8 +621,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Headers/Trailers/Metadata Maps ---------------------------------- */ "proxy_get_header_map_size" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _map_type: i32, _map_size: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, _map_type: i32, _map_size: i32| -> i32 { // Default Function: // Expectation: println!( @@ -623,8 +640,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_get_header_map_pairs" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, map_type: i32, return_map_data: i32, return_map_size: i32| @@ -643,7 +660,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; let malloc = match caller.get_export("malloc") { - Some(Extern::Func(func)) => func.get1::().unwrap(), + Some(Extern::Func(func)) => func, _ => { println!( "Error: proxy_get_header_map_pairs cannot get export \"malloc\"" @@ -664,22 +681,30 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; let serial_map_size = serial_map.len(); - unsafe { - let return_map_size_ptr = mem.data_unchecked_mut().get_unchecked_mut( - return_map_size as u32 as usize..return_map_size as u32 as usize + 4, - ); - - let return_map_data_ptr = mem.data_unchecked_mut().get_unchecked_mut( - return_map_data as u32 as usize..return_map_data as u32 as usize + 4, - ); + let map_data_add = { + let mut result = [Val::I32(0)]; + malloc + .call( + &mut caller, + &[Val::I32(serial_map_size as i32)], + &mut result, + ) + .unwrap(); + result[0].i32().unwrap() as u32 as usize + }; - let map_data_add = malloc(serial_map_size as i32).unwrap() as u32 as usize; + unsafe { let map_data_ptr = mem - .data_unchecked_mut() + .data_mut(&mut caller) .get_unchecked_mut(map_data_add..map_data_add + serial_map_size); map_data_ptr.copy_from_slice(&serial_map); - + let return_map_data_ptr = mem.data_mut(&mut caller).get_unchecked_mut( + return_map_data as u32 as usize..return_map_data as u32 as usize + 4, + ); return_map_data_ptr.copy_from_slice(&(map_data_add as u32).to_le_bytes()); + let return_map_size_ptr = mem.data_mut(&mut caller).get_unchecked_mut( + return_map_size as u32 as usize..return_map_size as u32 as usize + 4, + ); return_map_size_ptr .copy_from_slice(&(serial_map_size as u32).to_le_bytes()); } @@ -698,8 +723,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_set_header_map_pairs" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, map_type: i32, map_data: i32, map_size: i32| -> i32 { + store, + |mut caller: Caller<'_, ()>, map_type: i32, map_data: i32, map_size: i32| -> i32 { // Default Function: Reads and sets the according header map as the simulator default for the given map type // Expectation: asserts that the received header map and header map type corresponds to the expected one let mem = match caller.get_export("memory") { @@ -717,7 +742,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; unsafe { - let header_map_ptr = mem.data_unchecked().get_unchecked( + let header_map_ptr = mem.data(&mut caller).get_unchecked( map_data as u32 as usize..(map_data + map_size) as u32 as usize, ); @@ -750,8 +775,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_get_header_map_value" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, map_type: i32, key_data: i32, key_size: i32, @@ -773,7 +798,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; let malloc = match caller.get_export("malloc") { - Some(Extern::Func(func)) => func.get1::().unwrap(), + Some(Extern::Func(func)) => func, _ => { println!( "Error: proxy_get_header_map_value cannot get export \"malloc\"" @@ -784,47 +809,59 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; unsafe { - let key_data_ptr = mem - .data_unchecked() - .get(key_data as u32 as usize..) - .and_then(|arr| arr.get(..key_size as u32 as usize)); - let string_key = key_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); + let (string_key, string_value) = { + let key_data_ptr = mem + .data(&caller) + .get(key_data as u32 as usize..) + .and_then(|arr| arr.get(..key_size as u32 as usize)); + let string_key = key_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); + + let string_value = match EXPECT + .lock() + .unwrap() + .staged + .get_expect_get_header_map_value(map_type, string_key) + { + Some(expect_string_value) => expect_string_value, + None => { + match HOST.lock().unwrap().staged.get_header_map_value(map_type, &string_key) { + Some(host_string_value) => host_string_value, + None => panic!("Error: proxy_get_header_map_value | no header map value for key {}", string_key)} + } + }; + (string_key.to_string(), string_value) + }; - let string_value = match EXPECT - .lock() - .unwrap() - .staged - .get_expect_get_header_map_value(map_type, string_key) - { - Some(expect_string_value) => expect_string_value, - None => { - match HOST.lock().unwrap().staged.get_header_map_value(map_type, &string_key) { - Some(host_string_value) => host_string_value, - None => panic!("Error: proxy_get_header_map_value | no header map value for key {}", string_key)} - } + let value_data_add = { + let mut result = [Val::I32(0)]; + malloc + .call( + &mut caller, + &[Val::I32(string_value.len() as i32)], + &mut result, + ) + .unwrap(); + result[0].i32().unwrap() as u32 as usize }; - let value_data_add = - malloc(string_value.len() as i32).unwrap() as u32 as usize; let value_data_ptr = mem - .data_unchecked_mut() + .data_mut(&mut caller) .get_unchecked_mut(value_data_add..value_data_add + string_value.len()); value_data_ptr.copy_from_slice((&string_value).as_bytes()); - let return_value_data_ptr = mem.data_unchecked_mut().get_unchecked_mut( + let return_value_data_ptr = mem.data_mut(&mut caller).get_unchecked_mut( return_value_data as u32 as usize ..return_value_data as u32 as usize + 4, ); + return_value_data_ptr + .copy_from_slice(&(value_data_add as u32).to_le_bytes()); - let return_value_size_ptr = mem.data_unchecked_mut().get_unchecked_mut( + let return_value_size_ptr = mem.data_mut(&mut caller).get_unchecked_mut( return_value_size as u32 as usize ..return_value_size as u32 as usize + 4, ); - - return_value_data_ptr - .copy_from_slice(&(value_data_add as u32).to_le_bytes()); return_value_size_ptr .copy_from_slice(&(string_value.len() as u32).to_le_bytes()); @@ -844,8 +881,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_replace_header_map_value" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, map_type: i32, key_data: i32, key_size: i32, @@ -866,41 +903,35 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } }; - unsafe { - let key_data_ptr = mem - .data_unchecked() - .get(key_data as u32 as usize..) - .and_then(|arr| arr.get(..key_size as u32 as usize)); - let string_key = key_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); + let key_data_ptr = mem + .data(&caller) + .get(key_data as u32 as usize..) + .and_then(|arr| arr.get(..key_size as u32 as usize)); + let string_key = key_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); + + let value_data_ptr = mem + .data(&caller) + .get(value_data as u32 as usize..) + .and_then(|arr| arr.get(..value_size as u32 as usize)); + let string_value = value_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); - let value_data_ptr = mem - .data_unchecked() - .get(value_data as u32 as usize..) - .and_then(|arr| arr.get(..value_size as u32 as usize)); - let string_value = value_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); - - EXPECT - .lock() - .unwrap() - .staged - .get_expect_replace_header_map_value( - map_type, - string_key, - string_value, - ); - HOST.lock().unwrap().staged.replace_header_map_value( - map_type, - string_key, - string_value, - ); - println!("[vm->host] proxy_replace_header_map_value(map_type={}, key_data={}, key_size={}, value_data={}, value_size={}) status: {:?}", - map_type, string_key, string_key.len(), string_value, string_value.len(), get_status() - ); - } + EXPECT + .lock() + .unwrap() + .staged + .get_expect_replace_header_map_value(map_type, string_key, string_value); + HOST.lock().unwrap().staged.replace_header_map_value( + map_type, + string_key, + string_value, + ); + println!("[vm->host] proxy_replace_header_map_value(map_type={}, key_data={}, key_size={}, value_data={}, value_size={}) status: {:?}", + map_type, string_key, string_key.len(), string_value, string_value.len(), get_status() + ); println!( "[vm<-host] proxy_replace_header_map_value(...) return: {:?}", Status::Ok @@ -914,8 +945,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_remove_header_map_value" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, map_type: i32, key_data: i32, key_size: i32| -> i32 { + store, + |mut caller: Caller<'_, ()>, map_type: i32, key_data: i32, key_size: i32| -> i32 { // Default Function: remove the specified key-value pair in the default host environment if it exists // Expectation: assert that the received key is as expected let mem = match caller.get_export("memory") { @@ -932,28 +963,26 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } }; - unsafe { - let key_data_ptr = mem - .data_unchecked() - .get(key_data as u32 as usize..) - .and_then(|arr| arr.get(..key_size as u32 as usize)); - let string_key = key_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); + let key_data_ptr = mem + .data(&mut caller) + .get(key_data as u32 as usize..) + .and_then(|arr| arr.get(..key_size as u32 as usize)); + let string_key = key_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); - EXPECT - .lock() - .unwrap() - .staged - .get_expect_remove_header_map_value(map_type, string_key); - HOST.lock() - .unwrap() - .staged - .remove_header_map_value(map_type, string_key); - println!("[vm->host] proxy_remove_header_map_value(map_type={}, key_data={}, key_size={}) status: {:?}", - map_type, string_key, string_key.len(), get_status() - ); - } + EXPECT + .lock() + .unwrap() + .staged + .get_expect_remove_header_map_value(map_type, string_key); + HOST.lock() + .unwrap() + .staged + .remove_header_map_value(map_type, string_key); + println!("[vm->host] proxy_remove_header_map_value(map_type={}, key_data={}, key_size={}) status: {:?}", + map_type, string_key, string_key.len(), get_status() + ); println!( "[vm<-host] proxy_remove_header_map_value(...) return: {:?}", Status::Ok @@ -967,8 +996,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_add_header_map_value" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, map_type: i32, key_data: i32, key_size: i32, @@ -991,37 +1020,35 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } }; - unsafe { - let key_data_ptr = mem - .data_unchecked() - .get(key_data as u32 as usize..) - .and_then(|arr| arr.get(..key_size as u32 as usize)); - let string_key = key_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); - - let value_data_ptr = mem - .data_unchecked() - .get(value_data as u32 as usize..) - .and_then(|arr| arr.get(..value_size as u32 as usize)); - let string_value = value_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); + let key_data_ptr = mem + .data(&caller) + .get(key_data as u32 as usize..) + .and_then(|arr| arr.get(..key_size as u32 as usize)); + let string_key = key_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); + + let value_data_ptr = mem + .data(&caller) + .get(value_data as u32 as usize..) + .and_then(|arr| arr.get(..value_size as u32 as usize)); + let string_value = value_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); - EXPECT - .lock() - .unwrap() - .staged - .get_expect_add_header_map_value(map_type, string_key, string_value); - HOST.lock().unwrap().staged.add_header_map_value( - map_type, - string_key, - string_value, - ); - println!("[vm->host] proxy_add_header_map_value(map_type={}, key_data={}, key_size={}, value_data={}, value_size={}) status: {:?}", - map_type, string_key, string_key.len(), string_value, string_value.len(), get_status() - ); - } + EXPECT + .lock() + .unwrap() + .staged + .get_expect_add_header_map_value(map_type, string_key, string_value); + HOST.lock().unwrap().staged.add_header_map_value( + map_type, + string_key, + string_value, + ); + println!("[vm->host] proxy_add_header_map_value(map_type={}, key_data={}, key_size={}, value_data={}, value_size={}) status: {:?}", + map_type, string_key, string_key.len(), string_value, string_value.len(), get_status() + ); println!( "[vm<-host] proxy_add_header_map_value(...) return: {:?}", Status::Ok @@ -1036,8 +1063,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Buffer ---------------------------------- */ "proxy_get_buffer_status" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _buffer_type: i32, _length_ptr: i32, _flags_ptr: i32| @@ -1059,8 +1086,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_get_buffer_bytes" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, buffer_type: i32, start: i32, max_size: i32, @@ -1079,7 +1106,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; let malloc = match caller.get_export("malloc") { - Some(Extern::Func(func)) => func.get1::().unwrap(), + Some(Extern::Func(func)) => func, _ => { println!("Error: proxy_get_buffer_bytes cannot get export \"malloc\""); println!("[vm<-host] proxy_get_buffer_bytes(...) -> (return_buffer_data, return_buffer_size) return: {:?}", Status::InternalFailure); @@ -1115,26 +1142,32 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; unsafe { - let return_buffer_size_ptr = mem.data_unchecked_mut().get_unchecked_mut( - return_buffer_size as u32 as usize - ..return_buffer_size as u32 as usize + 4, - ); - - let return_buffer_data_ptr = mem.data_unchecked_mut().get_unchecked_mut( - return_buffer_data as u32 as usize - ..return_buffer_data as u32 as usize + 4, - ); - // allocate memory and store buffer bytes - let buffer_data_add = - malloc(response_body.len() as i32).unwrap() as u32 as usize; - let buffer_data_ptr = mem.data_unchecked_mut().get_unchecked_mut( + let mut result = [Val::I32(0)]; + malloc + .call( + &mut caller, + &[Val::I32(response_body.len() as i32)], + &mut result, + ) + .unwrap(); + let buffer_data_add = result[0].i32().unwrap() as u32 as usize; + + let buffer_data_ptr = mem.data_mut(&mut caller).get_unchecked_mut( buffer_data_add..buffer_data_add + response_body.len(), ); buffer_data_ptr.copy_from_slice(&response_body); + let return_buffer_size_ptr = mem.data_mut(&mut caller).get_unchecked_mut( + return_buffer_size as u32 as usize + ..return_buffer_size as u32 as usize + 4, + ); return_buffer_size_ptr .copy_from_slice(&(response_body.len() as u32).to_le_bytes()); + let return_buffer_data_ptr = mem.data_mut(&mut caller).get_unchecked_mut( + return_buffer_data as u32 as usize + ..return_buffer_data as u32 as usize + 4, + ); return_buffer_data_ptr .copy_from_slice(&(buffer_data_add as u32).to_le_bytes()); } @@ -1154,8 +1187,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_set_buffer_bytes" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, buffer_type: i32, start: i32, size: i32, @@ -1177,7 +1210,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> }; unsafe { - let buffer_data_ptr = mem.data_unchecked().get_unchecked( + let buffer_data_ptr = mem.data(&mut caller).get_unchecked( buffer_data as u32 as usize ..(buffer_data + buffer_size) as u32 as usize, ); @@ -1220,8 +1253,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- HTTP ---------------------------------- */ "proxy_http_call" => { Some(Func::wrap( - &store, - |caller: Caller<'_>, + store, + |mut caller: Caller<'_, ()>, upstream_data: i32, upstream_size: i32, headers_data: i32, @@ -1249,64 +1282,74 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> // expectation description not implemented yet unsafe { - let upstream_data_ptr = mem - .data_unchecked() - .get(upstream_data as u32 as usize..) - .and_then(|arr| arr.get(..upstream_size as u32 as usize)); - let string_upstream = upstream_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) - .unwrap(); - - let mut string_body: Option<&str> = None; - if body_size > 0 { - let body_data_ptr = mem - .data_unchecked() - .get(body_data as u32 as usize..) - .and_then(|arr| arr.get(..body_size as u32 as usize)); - string_body = body_data_ptr - .map(|string_msg| std::str::from_utf8(string_msg).unwrap()); - } + let (string_body, deserialized_header, deserialized_trailer, token_id) = { + let upstream_data_ptr = mem + .data(&caller) + .get(upstream_data as u32 as usize..) + .and_then(|arr| arr.get(..upstream_size as u32 as usize)); + let string_upstream = upstream_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()) + .unwrap(); + + let mut string_body: Option<&str> = None; + if body_size > 0 { + let body_data_ptr = mem + .data(&caller) + .get(body_data as u32 as usize..) + .and_then(|arr| arr.get(..body_size as u32 as usize)); + string_body = body_data_ptr + .map(|string_msg| std::str::from_utf8(string_msg).unwrap()); + } - let header_data_ptr = mem.data_unchecked().get_unchecked( - headers_data as u32 as usize - ..headers_data as u32 as usize + headers_size as u32 as usize, - ); - let deserialized_header = serial_utils::deserialize_map(header_data_ptr); + let header_data_ptr = mem.data(&caller).get_unchecked( + headers_data as u32 as usize + ..headers_data as u32 as usize + headers_size as u32 as usize, + ); + let deserialized_header = + serial_utils::deserialize_map(header_data_ptr); - let trailer_data_ptr = mem.data_unchecked().get_unchecked( - trailers_data as u32 as usize - ..trailers_data as u32 as usize + trailers_size as u32 as usize, - ); - let deserialized_trailer = serial_utils::deserialize_map(trailer_data_ptr); - - let token_id = match EXPECT.lock().unwrap().staged.get_expect_http_call( - string_upstream, - header_data_ptr, - string_body, - trailer_data_ptr, - timeout, - ) { - Some(expect_token) => expect_token, - None => 0, + let trailer_data_ptr = mem.data(&caller).get_unchecked( + trailers_data as u32 as usize + ..trailers_data as u32 as usize + trailers_size as u32 as usize, + ); + let deserialized_trailer = + serial_utils::deserialize_map(trailer_data_ptr); + let token_id = match EXPECT.lock().unwrap().staged.get_expect_http_call( + string_upstream, + header_data_ptr, + string_body, + trailer_data_ptr, + timeout, + ) { + Some(expect_token) => expect_token, + None => 0, + }; + println!( + "[vm->host] proxy_http_call(upstream_data={:?}, upstream_size={}", + string_upstream, + string_upstream.len() + ); + ( + string_body.map(|s| s.to_string()), + deserialized_header, + deserialized_trailer, + token_id, + ) }; - let return_token_add = mem.data_unchecked_mut().get_unchecked_mut( + let return_token_add = mem.data_mut(&mut caller).get_unchecked_mut( return_token as u32 as usize..return_token as u32 as usize + 4, ); return_token_add.copy_from_slice(&token_id.to_le_bytes()); - println!( - "[vm->host] proxy_http_call(upstream_data={:?}, upstream_size={}", - string_upstream, - string_upstream.len() - ); + println!( " headers_data={:?}, headers_size={}", deserialized_header, headers_size ); + let body_len = string_body.as_ref().map_or(0, |data| data.len()); println!( - " body_data={}, body_size={}", - string_body.unwrap_or("None"), - string_body.map_or(0, |data| data.len()) + " body_data={}, body_size={body_len}", + string_body.unwrap_or("None".to_string()) ); println!( " trailers_data={:?}, trailers_size={}", @@ -1332,8 +1375,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- gRPC ---------------------------------- */ "proxy_grpc_call" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _service_ptr: i32, _service_size: i32, _service_name_ptr: i32, @@ -1364,8 +1407,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_grpc_stream" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _service_ptr: i32, _service_size: i32, _service_name_ptr: i32, @@ -1393,8 +1436,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_grpc_cancel" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _token: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, _token: i32| -> i32 { // Default Function: // Expectation: println!( @@ -1412,8 +1455,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_grpc_close" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, _token: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, _token: i32| -> i32 { // Default Function: // Expectation: println!( @@ -1431,8 +1474,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> "proxy_grpc_send" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _token: i32, _message_ptr: i32, _message_size: i32, @@ -1455,7 +1498,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- Metrics ---------------------------------- */ "proxy_define_metric" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!( @@ -1471,7 +1514,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_increment_metric" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!( @@ -1487,7 +1530,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_record_metric" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!( @@ -1503,7 +1546,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_get_metric" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!( @@ -1521,8 +1564,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> /* ---------------------------------- System ---------------------------------- */ "proxy_set_effective_context" => { Some(Func::wrap( - &store, - |_caller: Caller<'_>, context_id: i32| -> i32 { + store, + |_caller: Caller<'_, ()>, context_id: i32| -> i32 { // Default Function: // Expectation: println!( @@ -1546,7 +1589,7 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_done" => { - Some(Func::wrap(&store, |_caller: Caller<'_>| -> i32 { + Some(Func::wrap(store, |_caller: Caller<'_, ()>| -> i32 { // Default Function: // Expectation: println!("[vm->host] proxy_done() status: {:?}", get_status()); @@ -1559,8 +1602,8 @@ fn get_hostfunc(store: &Store, _abi_version: AbiVersion, import: &ImportType) -> } "proxy_call_foreign_function" => Some(Func::wrap( - &store, - |_caller: Caller<'_>, + store, + |_caller: Caller<'_, ()>, _function_name: i32, _function_name_size: i32, _arguments: i32, @@ -1659,7 +1702,7 @@ pub mod serial_utils { let mut rng = rand::thread_rng(); let random_string: String = (0..string_len) .map(|_| { - let idx = rng.gen_range(0, CHARSET.len()); + let idx = rng.gen_range(0..CHARSET.len()); CHARSET[idx] as char }) .collect(); diff --git a/src/tester.rs b/src/tester.rs index c12cc4c..57c2846 100644 --- a/src/tester.rs +++ b/src/tester.rs @@ -40,20 +40,21 @@ pub struct MockSettings { pub fn mock(mock_settings: MockSettings) -> Result { // initialize wasm engine and shared cache - let store = Store::default(); + let mut store = Store::<()>::default(); let module = Module::from_file(store.engine(), &mock_settings.wasm_path)?; // generate and link host function implementations let abi_version = get_abi_version(&module); let imports: Arc>> = Arc::new(Mutex::new(Vec::new())); let (host_settings, expectations): (Arc>, Arc>) = - generate_import_list(&store, &module, imports.clone()); - let instance = Instance::new(&store, &module, &(*imports).lock().unwrap()[..])?; + generate_import_list(&mut store, &module, imports.clone()); + let instance = Instance::new(&mut store, &module, &(*imports).lock().unwrap()[..])?; // create mock test proxy-wasm object let tester = Tester::new( abi_version, mock_settings, + store, instance, host_settings, expectations, @@ -104,6 +105,7 @@ enum FunctionType { pub struct Tester { abi_version: AbiVersion, mock_settings: MockSettings, + store: Store<()>, instance: Instance, defaults: Arc>, expect: Arc>, @@ -115,16 +117,18 @@ impl Tester { fn new( abi_version: AbiVersion, mock_settings: MockSettings, + store: Store<()>, instance: Instance, host_settings: Arc>, expect: Arc>, ) -> Tester { let mut tester = Tester { - abi_version: abi_version, - mock_settings: mock_settings, - instance: instance, + abi_version, + mock_settings, + store, + instance, defaults: host_settings, - expect: expect, + expect, function_call: vec![], function_type: vec![], }; @@ -358,30 +362,27 @@ impl Tester { let mut return_wasm: Option = None; match self.function_call.remove(0) { FunctionCall::Start() => { - let _start = self - .instance - .get_func("_start") - .ok_or(anyhow::format_err!( - "Error: failed to find `_start` function export" - ))? - .get0::<()>()?; println!("[host->vm] _start()"); - _start()?; + self.instance + .get_typed_func::<(), ()>(&mut self.store, "_start") + .or(Err(anyhow::format_err!( + "Error: failed to find `_start` function export" + )))? + .call(&mut self.store, ())?; } FunctionCall::ProxyOnVmStart(context_id, vm_configuration_size) => { - let proxy_on_vm_start = self - .instance - .get_func("proxy_on_vm_start") - .ok_or(anyhow::format_err!( - "Error: failed to find `proxy_on_vm_start` function export" - ))? - .get2::()?; println!( "[host->vm] proxy_on_vm_start(context_id={}, vm_configuration_size={})", context_id, vm_configuration_size ); - let success = proxy_on_vm_start(context_id, vm_configuration_size)?; + let success = self + .instance + .get_typed_func::<(i32, i32), i32>(&mut self.store, "proxy_on_vm_start") + .or(Err(anyhow::format_err!( + "Error: failed to find `proxy_on_vm_start` function export" + )))? + .call(&mut self.store, (context_id, vm_configuration_size))?; println!("[host<-vm] proxy_on_vm_start return: success={}", success); return_wasm = Some(success); } @@ -389,16 +390,19 @@ impl Tester { FunctionCall::ProxyValidateConfiguration(root_context_id, configuration_size) => { let proxy_validate_configuration = self .instance - .get_func("proxy_validate_configuration") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>( + &mut self.store, + "proxy_validate_configuration", + ) + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_validate_configuration` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_validate_configuration(root_context_id={}, configuration_size={})", root_context_id, configuration_size ); - let success = proxy_validate_configuration(root_context_id, configuration_size)?; + let success = proxy_validate_configuration + .call(&mut self.store, (root_context_id, configuration_size))?; println!( "[host<-vm] proxy_validate_configuration return: success={}", success @@ -409,16 +413,16 @@ impl Tester { FunctionCall::ProxyOnConfigure(context_id, plugin_configuration_size) => { let proxy_on_configure = self .instance - .get_func("proxy_on_configure") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>(&mut self.store, "proxy_on_configure") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_configure' function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_configure(context_id={}, plugin_configuration_size={})", context_id, plugin_configuration_size ); - let success = proxy_on_configure(context_id, plugin_configuration_size)?; + let success = proxy_on_configure + .call(&mut self.store, (context_id, plugin_configuration_size))?; println!("[host<-vm] proxy_on_configure return: success={}", success); return_wasm = Some(success); } @@ -426,27 +430,29 @@ impl Tester { FunctionCall::ProxyOnTick(context_id) => { let proxy_on_tick = self .instance - .get_func("proxy_on_tick") - .ok_or(anyhow::format_err!( + .get_typed_func::(&mut self.store, "proxy_on_tick") + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_tick` function export" - ))? - .get1::()?; + )))?; println!("[host->vm] proxy_on_tick(context_id={})", context_id); - proxy_on_tick(context_id)?; + proxy_on_tick.call(&mut self.store, context_id)?; } FunctionCall::ProxyOnForeignFunction(root_context_id, function_id, data_size) => { assert_eq!(self.abi_version, AbiVersion::ProxyAbiVersion0_2_0); let proxy_on_foreign_function = self .instance - .get_func("proxy_on_foreign_function") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_foreign_function", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_foreign_function' function export" - ))? - .get3::()?; - println!("[host->vm] proxy_on_foreign_function(root_context_id={}, function_id={}, data_size={})", + )))?; + println!("[host->vm] proxy_on_foreign_function(root_context_id={}, function_id={}, data_size={})", root_context_id, function_id, data_size); - let action = proxy_on_foreign_function(root_context_id, function_id, data_size)?; + let action = proxy_on_foreign_function + .call(&mut self.store, (root_context_id, function_id, data_size))?; println!( "[host<-vm] proxy_on_foreign_function return: action={}", action @@ -457,47 +463,45 @@ impl Tester { FunctionCall::ProxyOnQueueReady(context_id, queue_id) => { let proxy_on_queue_ready = self .instance - .get_func("proxy_on_queue_ready") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), ()>(&mut self.store, "proxy_on_queue_ready") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_queue_ready' function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_queue_ready(context_id={}, queue_id={})", context_id, queue_id ); - proxy_on_queue_ready(context_id, queue_id)?; + proxy_on_queue_ready.call(&mut self.store, (context_id, queue_id))?; } // Stream calls FunctionCall::ProxyOnContextCreate(root_context_id, parent_context_id) => { let proxy_on_context_create = self .instance - .get_func("proxy_on_context_create") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), ()>(&mut self.store, "proxy_on_context_create") + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_context_create` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_context_create(root_context_id={}, parent_context_id={})", root_context_id, parent_context_id ); - proxy_on_context_create(root_context_id, parent_context_id)?; + proxy_on_context_create + .call(&mut self.store, (root_context_id, parent_context_id))?; } FunctionCall::ProxyOnNewConnection(context_id) => { let proxy_on_new_connection = self .instance - .get_func("proxy_on_new_connection") - .ok_or(anyhow::format_err!( + .get_typed_func::(&mut self.store, "proxy_on_new_connection") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_new_connection' function export" - ))? - .get1::()?; + )))?; println!( "[host->vm] proxy_on_new_connection(context_id={})", context_id ); - let action = proxy_on_new_connection(context_id)?; + let action = proxy_on_new_connection.call(&mut self.store, context_id)?; println!( "[host<-vm] proxy_on_new_connection return: action={}", action @@ -508,16 +512,21 @@ impl Tester { FunctionCall::ProxyOnDownstreamData(context_id, data_size, end_of_stream) => { let proxy_on_downstream_data = self .instance - .get_func("proxy_on_downstream_data") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_downstream_data", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_downstream_data' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_downstream_data(context_id={}, data_size={}, end_of_stream={})", context_id, data_size, end_of_stream ); - let action = proxy_on_downstream_data(context_id, data_size, end_of_stream as i32)?; + let action = proxy_on_downstream_data.call( + &mut self.store, + (context_id, data_size, end_of_stream as i32), + )?; println!( "[host<-vm] proxy_on_downstream_data return: action={}", action @@ -528,31 +537,36 @@ impl Tester { FunctionCall::ProxyOnDownstreamConnectionClose(context_id, peer_type) => { let proxy_on_downstream_connection_close = self .instance - .get_func("proxy_on_downstream_connection_close") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), ()>(&mut self.store, "proxy_on_downstream_connection_close") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_downstream_connection_close' function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_downstream_connection_close(context_id={}, peer_data={})", context_id, peer_type as i32 ); - proxy_on_downstream_connection_close(context_id, peer_type)?; + proxy_on_downstream_connection_close + .call(&mut self.store, (context_id, peer_type))?; } FunctionCall::ProxyOnUpstreamData(context_id, data_size, end_of_stream) => { let proxy_on_upstream_data = self .instance - .get_func("proxy_on_upstream_data") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_upstream_data", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_upstream_data' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_upstream_data(context_id={}, data_size={}, end_of_stream={})", context_id, data_size, end_of_stream ); - let action = proxy_on_upstream_data(context_id, data_size, end_of_stream as i32)?; + let action = proxy_on_upstream_data.call( + &mut self.store, + (context_id, data_size, end_of_stream as i32), + )?; println!( "[host<-vm] proxy_on_upstream_data return: action={}", action @@ -563,39 +577,54 @@ impl Tester { FunctionCall::ProxyOnUpstreamConnectionClose(context_id, peer_type) => { let proxy_on_upstream_connection_close = self .instance - .get_func("proxy_on_upstream_connection_close") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), ()>( + &mut self.store, + "proxy_on_upstream_connection_close", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_upstream_connection_close' function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_upstream_connection_close(context_id={}, peer_data={})", context_id, peer_type as i32 ); - proxy_on_upstream_connection_close(context_id, peer_type)?; + proxy_on_upstream_connection_close + .call(&mut self.store, (context_id, peer_type))?; } FunctionCall::ProxyOnRequestHeaders(context_id, num_headers, end_of_stream) => { - let proxy_on_request_headers = self - .instance - .get_func("proxy_on_request_headers") - .ok_or(anyhow::format_err!( - "Error: failed to find `proxy_on_request_headers` function export" - ))?; println!( "[host->vm] proxy_on_request_headers(context_id={}, num_headers={}, end_of_stream={})", context_id, num_headers, end_of_stream ); let action = match self.abi_version { AbiVersion::ProxyAbiVersion0_1_0 => { - proxy_on_request_headers.get2::()?(context_id, num_headers)? + let proxy_on_request_headers = self + .instance + .get_typed_func::<(i32, i32), i32>( + &mut self.store, + "proxy_on_request_headers", + ) + .or(Err(anyhow::format_err!( + "Error: failed to find `proxy_on_request_headers` function export" + )))?; + proxy_on_request_headers.call(&mut self.store, (context_id, num_headers))? + } + AbiVersion::ProxyAbiVersion0_2_0 => { + let proxy_on_request_headers = self + .instance + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_request_headers", + ) + .or(Err(anyhow::format_err!( + "Error: failed to find `proxy_on_request_headers` function export" + )))?; + proxy_on_request_headers.call( + &mut self.store, + (context_id, num_headers, end_of_stream as i32), + )? } - AbiVersion::ProxyAbiVersion0_2_0 => proxy_on_request_headers - .get3::()?( - context_id, - num_headers, - end_of_stream as i32, - )?, _ => panic!( "Error: proxy_on_request_headers not supported for {:?}", self.abi_version @@ -612,16 +641,21 @@ impl Tester { FunctionCall::ProxyOnRequestBody(context_id, body_size, end_of_stream) => { let proxy_on_request_body = self .instance - .get_func("proxy_on_request_body") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_request_body", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_request_body' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_request_body(context_id={}, body_size={}, end_of_stream={})", context_id, body_size, end_of_stream ); - let action = proxy_on_request_body(context_id, body_size, end_of_stream as i32)?; + let action = proxy_on_request_body.call( + &mut self.store, + (context_id, body_size, end_of_stream as i32), + )?; println!("[host<-vm] proxy_on_request_body return: action={}", action); return_wasm = Some(action); } @@ -629,16 +663,16 @@ impl Tester { FunctionCall::ProxyOnRequestTrailers(context_id, num_trailers) => { let proxy_on_request_trailers = self .instance - .get_func("proxy_on_request_trailers") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>(&mut self.store, "proxy_on_request_trailers") + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_request_trailers` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_request_trailers(context_id={}, num_trailers={})", context_id, num_trailers ); - let action = proxy_on_request_trailers(context_id, num_trailers)?; + let action = + proxy_on_request_trailers.call(&mut self.store, (context_id, num_trailers))?; println!( "[host<-vm] proxy_on_request_trailers return: action={}", action @@ -649,16 +683,16 @@ impl Tester { FunctionCall::ProxyOnRequestMetadata(context_id, nelements) => { let proxy_on_request_metadata = self .instance - .get_func("proxy_on_request_metadata") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>(&mut self.store, "proxy_on_request_metadata") + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_request_metadata` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_request_metadata(context_id={}, nelements={})", context_id, nelements ); - let action = proxy_on_request_metadata(context_id, nelements)?; + let action = + proxy_on_request_metadata.call(&mut self.store, (context_id, nelements))?; println!( "[host<-vm] proxy_on_request_metadata return: action={}", action @@ -667,26 +701,39 @@ impl Tester { } FunctionCall::ProxyOnResponseHeaders(context_id, num_headers, end_of_stream) => { - let proxy_on_response_headers = self - .instance - .get_func("proxy_on_response_headers") - .ok_or(anyhow::format_err!( - "Error: failed to find `proxy_on_response_headers` function export" - ))?; println!( "[host->vm] proxy_on_response_headers(context_id={}, num_headers={}, end_of_stream={})", context_id, num_headers, end_of_stream ); let action = match self.abi_version { AbiVersion::ProxyAbiVersion0_1_0 => { - proxy_on_response_headers.get2::()?(context_id, num_headers)? + let proxy_on_response_headers = self + .instance + .get_typed_func::<(i32, i32), i32>( + &mut self.store, + "proxy_on_response_headers", + ) + .or(Err(anyhow::format_err!( + "Error: failed to find `proxy_on_response_headers` function export" + )))?; + proxy_on_response_headers + .call(&mut self.store, (context_id, num_headers))? + } + AbiVersion::ProxyAbiVersion0_2_0 => { + let proxy_on_response_headers = self + .instance + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_response_headers", + ) + .or(Err(anyhow::format_err!( + "Error: failed to find `proxy_on_response_headers` function export" + )))?; + proxy_on_response_headers.call( + &mut self.store, + (context_id, num_headers, end_of_stream as i32), + )? } - AbiVersion::ProxyAbiVersion0_2_0 => proxy_on_response_headers - .get3::()?( - context_id, - num_headers, - end_of_stream as i32, - )?, _ => panic!( "Error: proxy_on_response_headers not supported for {:?}", self.abi_version @@ -702,16 +749,21 @@ impl Tester { FunctionCall::ProxyOnResponseBody(context_id, body_size, end_of_stream) => { let proxy_on_response_body = self .instance - .get_func("proxy_on_response_body") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), i32>( + &mut self.store, + "proxy_on_response_body", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_response_body' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_response_body(context_id={}, body_size={}, end_of_stream={})", context_id, body_size, end_of_stream ); - let action = proxy_on_response_body(context_id, body_size, end_of_stream as i32)?; + let action = proxy_on_response_body.call( + &mut self.store, + (context_id, body_size, end_of_stream as i32), + )?; println!("[host<-vm] function return: action -> {}", action); return_wasm = Some(action); } @@ -719,16 +771,19 @@ impl Tester { FunctionCall::ProxyOnResponseTrailers(context_id, num_trailers) => { let proxy_on_response_trailers = self .instance - .get_func("proxy_on_response_trailers") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>( + &mut self.store, + "proxy_on_response_trailers", + ) + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_response_trailers` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] proxy_on_response_trailers(context_id={}, num_trailers={})", context_id, num_trailers ); - let action = proxy_on_response_trailers(context_id, num_trailers)?; + let action = + proxy_on_response_trailers.call(&mut self.store, (context_id, num_trailers))?; println!( "[host<-vm] proxy_on_response_body return: action={}", action @@ -739,16 +794,19 @@ impl Tester { FunctionCall::ProxyOnResponseMetadata(context_id, nelements) => { let proxy_on_response_metadata = self .instance - .get_func("proxy_on_response_metadata") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32), i32>( + &mut self.store, + "proxy_on_response_metadata", + ) + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_response_metadata` function export" - ))? - .get2::()?; + )))?; println!( "[host->vm] call_proxy_on_response_metadata(context_id={}, nelements={})", context_id, nelements ); - let action = proxy_on_response_metadata(context_id, nelements)?; + let action = + proxy_on_response_metadata.call(&mut self.store, (context_id, nelements))?; println!( "[host<-vm] proxy_on_response_metadata return: action={}", action @@ -766,11 +824,13 @@ impl Tester { ) => { let proxy_on_http_call_response = self .instance - .get_func("proxy_on_http_call_response") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32, i32, i32), ()>( + &mut self.store, + "proxy_on_http_call_response", + ) + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_http_call_response` function export" - ))? - .get5::()?; + )))?; println!( "[host->vm] proxy_on_http_call_response(context_id={}, callout_id={}, num_headers={}", context_id, callout_id, num_headers @@ -779,83 +839,80 @@ impl Tester { " body_size={}, num_trailers={})", body_size, num_trailers ); - proxy_on_http_call_response( - context_id, - callout_id, - num_headers, - body_size, - num_trailers, + proxy_on_http_call_response.call( + &mut self.store, + (context_id, callout_id, num_headers, body_size, num_trailers), )?; } FunctionCall::ProxyOnGrpcReceiveInitialMetadata(context_id, token, headers) => { let proxy_on_grpc_receive_initial_metadata = self .instance - .get_func("proxy_on_grpc_receive_initial_metadata") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), ()>(&mut self.store, "proxy_on_grpc_receive_initial_metadata") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_grpc_receive_initial_metadata' function export" - ))? - .get3::()?; + )))?; println!("[host->vm] proxy_on_grpc_receive_initial_metadata(context_id={}, token={}, headers={})", context_id, token, headers); - proxy_on_grpc_receive_initial_metadata(context_id, token, headers)?; + proxy_on_grpc_receive_initial_metadata + .call(&mut self.store, (context_id, token, headers))?; } FunctionCall::ProxyOnGrpcReceiveTrailingMetadata(context_id, token, trailers) => { let proxy_on_grpc_trailing_metadata = self .instance - .get_func("proxy_on_grpc_receive_trailing_metadata") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), ()>( + &mut self.store, + "proxy_on_grpc_receive_trailing_metadata", + ) + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_grpc_trailing_metadata' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_grpc_receive_trailing_metadata(context_id={}, token={}, trailers={})", context_id, token, trailers ); - proxy_on_grpc_trailing_metadata(context_id, token, trailers)?; + proxy_on_grpc_trailing_metadata + .call(&mut self.store, (context_id, token, trailers))?; } FunctionCall::ProxyOnGrpcReceive(context_id, token, response_size) => { let proxy_on_grpc_receive = self .instance - .get_func("proxy_on_grpc_receive") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), ()>(&mut self.store, "proxy_on_grpc_receive") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_grpc_receive' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_grpc_receive(context_id={}, token={}, response_size={})", context_id, token, response_size ); - proxy_on_grpc_receive(context_id, token, response_size)?; + proxy_on_grpc_receive.call(&mut self.store, (context_id, token, response_size))?; } FunctionCall::ProxyOnGrpcClose(context_id, token, status_code) => { let proxy_on_grpc_close = self .instance - .get_func("proxy_on_grpc_close") - .ok_or(anyhow::format_err!( + .get_typed_func::<(i32, i32, i32), ()>(&mut self.store, "proxy_on_grpc_close") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_grpc_close' function export" - ))? - .get3::()?; + )))?; println!( "[host->vm] proxy_on_grpc_close(context_id={}, token={}, status_code={})", context_id, token, status_code ); - proxy_on_grpc_close(context_id, token, status_code)?; + proxy_on_grpc_close.call(&mut self.store, (context_id, token, status_code))?; } // The stream/vm has completed FunctionCall::ProxyOnDone(context_id) => { let proxy_on_done = self .instance - .get_func("proxy_on_done") - .ok_or(anyhow::format_err!( + .get_typed_func::(&mut self.store, "proxy_on_done") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_done' function export" - ))? - .get1::()?; + )))?; println!("[host->vm] proxy_on_done(context_id={})", context_id); - let is_done = proxy_on_done(context_id)?; + let is_done = proxy_on_done.call(&mut self.store, context_id)?; println!("[host<-vm] proxy_on_done return: is_done={}", is_done); return_wasm = Some(is_done); } @@ -863,25 +920,23 @@ impl Tester { FunctionCall::ProxyOnLog(context_id) => { let proxy_on_log = self .instance - .get_func("proxy_on_log") - .ok_or(anyhow::format_err!( + .get_typed_func::(&mut self.store, "proxy_on_log") + .or(Err(anyhow::format_err!( "Error: failed to find `proxy_on_log` function export" - ))? - .get1::()?; + )))?; println!("[host->vm] proxy_on_log(context_id={})", context_id); - proxy_on_log(context_id)?; + proxy_on_log.call(&mut self.store, context_id)?; } FunctionCall::ProxyOnDelete(context_id) => { let proxy_on_delete = self .instance - .get_func("proxy_on_delete") - .ok_or(anyhow::format_err!( + .get_typed_func::(&mut self.store, "proxy_on_delete") + .or(Err(anyhow::format_err!( "Error: failed to find 'proxy_on_delete' function export" - ))? - .get1::()?; + )))?; println!("[host->vm] proxy_on_delete(context_id={})", context_id); - proxy_on_delete(context_id)?; + proxy_on_delete.call(&mut self.store, context_id)?; } } diff --git a/src/utility.rs b/src/utility.rs index 0519a75..0854840 100644 --- a/src/utility.rs +++ b/src/utility.rs @@ -16,7 +16,7 @@ use anyhow::Result; use wasmtime::*; pub fn print_boundary(wasm_file: &str) -> Result<()> { - let store = Store::default(); + let store: Store<()> = Store::default(); let module = Module::from_file(store.engine(), wasm_file)?; print_imports(&module); print_exports(&module);