From 7e7d23044107f752fa0d61d55b76f85cb1ff49cb Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 22 Oct 2018 12:59:21 +0200 Subject: [PATCH 01/16] Fixed main function generate context --- src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index b67c4fc64c5..9a3ede13f4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,7 +71,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { } let import_object = integrations::generate_libc_env(); - let webassembly::ResultObject { module, instance } = + let webassembly::ResultObject { module, mut instance } = webassembly::instantiate(wasm_binary, import_object) .map_err(|err| String::from(err.description()))?; let func_index = instance @@ -80,8 +80,9 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { Some(&webassembly::Export::Function(index)) => index, _ => panic!("Main function not found"), }); - let main: fn() = get_instance_function!(instance, func_index); - main(); + let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); + let context = instance.generate_context(); + main(context); Ok(()) } From 7444837d09fe16cf1f8f311c3305ca41928a37a2 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 22 Oct 2018 18:31:12 +0200 Subject: [PATCH 02/16] Moved memories, tables and globals to be Unchecked slices --- src/webassembly/instance.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 4b82d3ee536..b32a8e37ca8 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -86,20 +86,20 @@ impl VmCtx { } } -#[derive(Debug)] +// #[derive(Debug)] #[repr(C)] pub struct VmCtxData<'phantom> { pub user_data: UserData, - // globals: UncheckedSlice, - // memories: UncheckedSlice>, - // tables: UncheckedSlice>, - globals: Vec, - memories: Vec>, - tables: Vec>, + globals: UncheckedSlice, + memories: UncheckedSlice>, + tables: UncheckedSlice>, + // globals: Vec, + // memories: Vec>, + // pub tables: UncheckedSlice>, phantom: PhantomData<&'phantom ()>, } -#[derive(Debug)] +// #[derive(Debug)] #[repr(C)] pub struct UserData { // pub process: Dispatch, @@ -519,11 +519,11 @@ impl Instance { } pub fn generate_context(&mut self) -> &VmCtx { - let mut memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); + let mut memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); - let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); + let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); - let globals: Vec = self.globals[..].into(); + let globals: UncheckedSlice = self.globals[..].into(); assert!(memories.len() >= 1, "modules must have at least one memory"); // the first memory has a space of `mem::size_of::()` rounded From a625382158d72471b9da47d23c99ae3e62b33cf4 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 22 Oct 2018 18:36:51 +0200 Subject: [PATCH 03/16] Improved function pointers --- src/webassembly/instance.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index b32a8e37ca8..a45596226e5 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -49,7 +49,7 @@ fn get_function_addr( func_index: &FuncIndex, import_functions: &Vec<*const u8>, functions: &Vec>, -) -> *const u8 { +) -> *const () { let index = func_index.index(); let len = import_functions.len(); let func_pointer = if index < len { @@ -57,7 +57,7 @@ fn get_function_addr( } else { (&functions[func_index.index() - len]).as_ptr() }; - func_pointer + func_pointer as _ } // pub fn get_function_addr( @@ -468,7 +468,8 @@ impl Instance { pub fn memories(&self) -> Arc> { self.memories.clone() } - pub fn get_function_pointer(&self, func_index: FuncIndex) -> *const u8 { + + pub fn get_function_pointer(&self, func_index: FuncIndex) -> *const () { get_function_addr(&func_index, &self.import_functions, &self.functions) } From 4ab26226f9a5b71d270876881175492ce7919fde Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 22 Oct 2018 18:56:29 +0200 Subject: [PATCH 04/16] Revert "Improved function pointers" This reverts commit a625382158d72471b9da47d23c99ae3e62b33cf4. --- src/webassembly/instance.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index a45596226e5..b32a8e37ca8 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -49,7 +49,7 @@ fn get_function_addr( func_index: &FuncIndex, import_functions: &Vec<*const u8>, functions: &Vec>, -) -> *const () { +) -> *const u8 { let index = func_index.index(); let len = import_functions.len(); let func_pointer = if index < len { @@ -57,7 +57,7 @@ fn get_function_addr( } else { (&functions[func_index.index() - len]).as_ptr() }; - func_pointer as _ + func_pointer } // pub fn get_function_addr( @@ -468,8 +468,7 @@ impl Instance { pub fn memories(&self) -> Arc> { self.memories.clone() } - - pub fn get_function_pointer(&self, func_index: FuncIndex) -> *const () { + pub fn get_function_pointer(&self, func_index: FuncIndex) -> *const u8 { get_function_addr(&func_index, &self.import_functions, &self.functions) } From 037f76e3b15828de0e293c7f5d6e3542ee4c542a Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 22 Oct 2018 21:03:43 +0200 Subject: [PATCH 05/16] Improved context data --- src/main.rs | 2 +- src/webassembly/instance.rs | 73 +++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9a3ede13f4d..2d6cc3347b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,7 +82,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { }); let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); let context = instance.generate_context(); - main(context); + main(&context); Ok(()) } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index b32a8e37ca8..47019000035 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -68,27 +68,10 @@ fn get_function_addr( // (base as usize + offset) as _ // } -/// Zero-sized, non-instantiable type. -#[derive(Debug)] -pub enum VmCtx {} - -impl VmCtx { - pub fn data(&self) -> &VmCtxData { - let heap_ptr = self as *const _ as *const VmCtxData; - unsafe { &*heap_ptr.sub(1) } - } - - /// This is safe because the offset is 32 bits and thus - /// cannot extend out of the guarded wasm memory. - pub fn fastpath_offset_ptr(&self, offset: u32) -> *const T { - let heap_ptr = self as *const _ as *const u8; - unsafe { heap_ptr.add(offset as usize) as *const T } - } -} // #[derive(Debug)] #[repr(C)] -pub struct VmCtxData<'phantom> { +pub struct VmCtx<'phantom> { pub user_data: UserData, globals: UncheckedSlice, memories: UncheckedSlice>, @@ -240,9 +223,13 @@ impl Instance { }, RelocationType::CurrentMemory => { current_memory as isize + // panic!("current memory not yet implemented"); + // unimplemented!() }, RelocationType::GrowMemory => { grow_memory as isize + // panic!("Grow memory not yet implemented"); + // unimplemented!() }, _ => unimplemented!() // RelocationType::Intrinsic(name) => { @@ -518,33 +505,33 @@ impl Instance { } } - pub fn generate_context(&mut self) -> &VmCtx { + pub fn generate_context(&mut self) -> VmCtx { let mut memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); let globals: UncheckedSlice = self.globals[..].into(); - assert!(memories.len() >= 1, "modules must have at least one memory"); + // assert!(memories.len() >= 1, "modules must have at least one memory"); // the first memory has a space of `mem::size_of::()` rounded // up to the 4KiB before it. We write the VmCtxData into that. let instance = self.clone(); - let data = VmCtxData { + let data = VmCtx { globals: globals, - memories: memories[1..].into(), + memories: memories[..].into(), tables: tables[..].into(), user_data: UserData { // process, - instance, + instance: instance, }, phantom: PhantomData, }; - - let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData; - unsafe { - main_heap_ptr.sub(1).write(data); - &*(main_heap_ptr as *const VmCtx) - } + data + // let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData; + // unsafe { + // main_heap_ptr.sub(1).write(data); + // &*(main_heap_ptr as *const VmCtx) + // } } /// Returns a slice of the contents of allocated linear memory. @@ -583,8 +570,8 @@ impl Clone for Instance { } extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { - // return 0; - unimplemented!(); + return 0; + // unimplemented!(); // let instance = &vmctx // .data() // .user_data @@ -608,18 +595,24 @@ extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { } extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 { + let instance = &vmctx.user_data.instance; + let memory = &instance.memories[memory_index as usize]; + memory.current_size() as u32 + // return 0; - println!("current_memory::init {:?}", memory_index); - let instance = &vmctx.data().user_data.instance; + // unimplemented!(); - let memory = &instance.memories[memory_index as usize]; - println!( - "INSPECTED MEMORY ({:?}) {:?}", - memory.current_size(), - instance.inspect_memory(0, 0, 1) - ); + // println!("current_memory::init {:?}", memory_index); + // let instance = &vmctx.data().user_data.instance; - memory.current_size() as u32 + // let memory = &instance.memories[memory_index as usize]; + // println!( + // "INSPECTED MEMORY ({:?}) {:?}", + // memory.current_size(), + // instance.inspect_memory(0, 0, 1) + // ); + + // memory.current_size() as u32 // return 1; // let vm = unsafe { // (*vmctx) as *mut VmCtx From 2a118930c23d5b68bcf35a72282036cc7fa5f721 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 01:15:18 +0200 Subject: [PATCH 06/16] Table now working properly --- src/common/slice.rs | 10 +- src/integrations/mod.rs | 47 ++++++++- src/integrations/tests/putchar.wast | 27 +++++- src/main.rs | 28 +++++- src/webassembly/instance.rs | 24 ++--- src/webassembly/module.rs | 143 +++++++++++++++------------- 6 files changed, 190 insertions(+), 89 deletions(-) diff --git a/src/common/slice.rs b/src/common/slice.rs index 06a297c4375..81ea02d5243 100644 --- a/src/common/slice.rs +++ b/src/common/slice.rs @@ -1,21 +1,21 @@ -use core::ops::{Index, IndexMut}; -use core::ptr::NonNull; +use std::ops::{Index, IndexMut}; +use std::ptr::NonNull; #[derive(Copy, Clone)] #[repr(transparent)] pub struct UncheckedSlice { - ptr: NonNull, + pub ptr: NonNull, } impl UncheckedSlice { #[inline] - unsafe fn get_unchecked(&self, index: usize) -> &T { + pub unsafe fn get_unchecked(&self, index: usize) -> &T { let ptr = self.ptr.as_ptr(); &*ptr.add(index) } #[inline] - unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { let ptr = self.ptr.as_ptr(); &mut *(ptr.add(index) as *mut _) } diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index 857b27bded5..163226166f6 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -1,5 +1,32 @@ -use crate::webassembly::ImportObject; -use libc::putchar; +use crate::webassembly::{ImportObject, VmCtx}; +// use libc::putchar; + +extern fn putchar(a: *const u8, context: *const u8) { + println!("PUT CHAAAR original pointer {:?}", context); + let vmctx: &VmCtx = unsafe { &*(context as *const VmCtx) }; + println!("PUT CHAAAR {}", vmctx.test); + println!("PUT CHAAAR pointer {:p}", vmctx); + let x = vmctx as *const _; + let x_tables = vmctx.tables.as_ptr(); + let tables_ptr_1 = (&vmctx.tables) as *const _; + let tables_ptr_2 = unsafe { (&vmctx.tables.get_unchecked(0)) as *const _ }; + let tables_ptr_3 = &vmctx.tables as *const _ ; + let tables_ptr_4 = &vmctx.tables as *const _ ; + // let tables: &Vec> = unsafe { &*(tables_ptr_4 as *const Vec>) }; + let x_tables_serial: &Vec<*const usize> = unsafe { &*(tables_ptr_1 as *const Vec<*const usize>) }; + // let tables: &Vec<> = vmctx.tables as &Vec>; + println!("PUT CHAAAR pointer {:?}", x); + println!("PUT CHAAAR pointer 1 {:p}", &vmctx.tables); + println!("PUT CHAAAR pointer 2 {:p}", tables_ptr_1); + println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_2); + println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_3); + // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", tables_ptr_4, tables); + // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables, vmctx.tables); + // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables[0], vmctx.tables[0]); + println!("PUT CHAAAR pointer {:?} {:?}", x_tables, x_tables_serial); + let x_tables = vmctx.tables.as_ptr(); + println!("PUT CHAAAR pointer {:?}", x_tables); +} pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { let mut import_object = ImportObject::new(); @@ -12,6 +39,7 @@ mod tests { use super::generate_libc_env; use crate::webassembly::{ instantiate, ErrorKind, Export, ImportObject, Instance, Module, ResultObject, + VmCtx }; use libc::putchar; @@ -21,12 +49,21 @@ mod tests { let import_object = generate_libc_env(); let result_object = instantiate(wasm_bytes, import_object).expect("Not compiled properly"); let module = result_object.module; - let instance = result_object.instance; + let mut instance = result_object.instance; let func_index = match module.info.exports.get("main") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), }; - let main: fn() = get_instance_function!(instance, func_index); - main(); + let main: fn(&VmCtx) = get_instance_function!(instance, func_index); + let mainn_func_index = match module.info.exports.get("mainn") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let mainn: fn(&VmCtx) = get_instance_function!(instance, mainn_func_index); + let context = instance.generate_context(); + main(&context); + println!("---------MAINNN NOW---------"); + // let context = instance.generate_context(); + mainn(&context); } } diff --git a/src/integrations/tests/putchar.wast b/src/integrations/tests/putchar.wast index d61d6ada095..8ad1a58ba2b 100644 --- a/src/integrations/tests/putchar.wast +++ b/src/integrations/tests/putchar.wast @@ -1,11 +1,34 @@ (module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (import "env" "putchar" (func $putchar (param i32) (result i32))) - (table 0 anyfunc) + (elem (i32.const 0) $multiply) + (table 1 1 anyfunc) (memory $0 1) (export "memory" (memory $0)) (export "main" (func $main)) - (func $main (; 1 ;) (result i32) + (export "mainn" (func $mainn)) + (func $dispatch (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call_indirect (type $FUNCSIG$iii) + (get_local $1) + (get_local $2) + (get_local $0) + ) + ) + (func $multiply (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (i32.mul + (get_local $1) + (get_local $0) + ) + ) + (func $mainn (; 2 ;) (result i32) + (call $dispatch + (i32.const 0) + (i32.const 20) + (i32.const 30) + ) + ) + (func $main (; 3 ;) (result i32) (drop (call $putchar (i32.const 97) diff --git a/src/main.rs b/src/main.rs index 2d6cc3347b2..3ae7f388786 100644 --- a/src/main.rs +++ b/src/main.rs @@ -81,8 +81,34 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { _ => panic!("Main function not found"), }); let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); - let context = instance.generate_context(); + let mainn_func_index = match module.info.exports.get("mainn") { + Some(&webassembly::Export::Function(index)) => index, + _ => panic!("Mainn function not found"), + }; + let mainn: fn(*const u8) -> i32 = get_instance_function!(instance, mainn_func_index); + let context = &instance.generate_context(); + // println!("Context ptr {:p}", context); + // println!("Context ptr {:?}", &context as *const _); + // println!("Context ptr {:?}", &context as *const _); + // println!("Memories ptr {:?}", context.memories.as_ptr()); + // println!("Tables ptr {:?}", context.tables.as_ptr()); + // println!("Tables ptr {:?}", context.tables.as_ptr()); + // println!("Tables ptr {:?}", &context.tables as *const _); + // println!("Tables ptr {:?}", &context.tables as *const _); + // println!("User data ptr {:?}", &context.user_data as *const _); + // println!("Globals ptr {:?}", &context.globals as *const _); + // println!("Memories ptr {:?}", &context.memories as *const _); + // println!("Tables ptr {:?}", &context.tables as *const _); + // unsafe { + // println!("Tables 0 ptr {:p}", &context.tables.get_unchecked(0)); + // println!("Tables 0 ptr {:p}", &context.tables.get_unchecked(0).get(0)); + // } + let table_ptr = &context.tables as *const _; + // let table: &Ta main(&context); + println!("-------------NOW MAINN----------"); + let res = mainn(context.tables.as_ptr() as *const u8); + println!("RESULT {:?}", res); Ok(()) } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 47019000035..864c270d5a2 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -73,12 +73,13 @@ fn get_function_addr( #[repr(C)] pub struct VmCtx<'phantom> { pub user_data: UserData, - globals: UncheckedSlice, - memories: UncheckedSlice>, - tables: UncheckedSlice>, + pub globals: UncheckedSlice, + pub memories: UncheckedSlice>, + pub tables: UncheckedSlice>, + pub test: String, // globals: Vec, // memories: Vec>, - // pub tables: UncheckedSlice>, + // pub tables: Vec>, phantom: PhantomData<&'phantom ()>, } @@ -510,6 +511,8 @@ impl Instance { let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); + println!("GENERATING CONTEXT {:?}", self.tables); + let globals: UncheckedSlice = self.globals[..].into(); // assert!(memories.len() >= 1, "modules must have at least one memory"); @@ -524,6 +527,7 @@ impl Instance { // process, instance: instance, }, + test: "TEST".to_string(), phantom: PhantomData, }; data @@ -569,20 +573,18 @@ impl Clone for Instance { } } -extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { +extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 { + return 0; // unimplemented!(); - // let instance = &vmctx - // .data() - // .user_data - // .instance; + // let instance = &vmctx.user_data.instance; - // let mut memory = &mut instance.memories[memory_index as usize]; + // let mut memory = instance.memories[memory_index as usize]; // if let Some(old_size) = memory.grow(size) { // old_size as i32 // } else { - -1 + // -1 // } // unsafe { diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index 54a0c72cbc0..f80603339b0 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -409,72 +409,73 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { fn make_table(&mut self, func: &mut ir::Function, table_index: TableIndex) -> ir::Table { // OLD // Create a table whose base address is stored at `vmctx+0`. - // let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); - // let base_gv = func.create_global_value(ir::GlobalValueData::Load { - // base: vmctx, - // offset: Offset32::new(0), - // global_type: self.pointer_type(), - // }); - // let bound_gv = func.create_global_value(ir::GlobalValueData::Load { - // base: vmctx, - // offset: Offset32::new(0), - // global_type: I32, - // }); - - // func.create_table(ir::TableData { - // base_gv, - // min_size: Imm64::new(0), - // bound_gv, - // element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2), - // index_type: I32, - // }) - - let ptr_size = self.ptr_size(); - - let base = self.mod_info.tables_base.unwrap_or_else(|| { - let tables_offset = self.ptr_size() as i32 * -1; - let new_base = func.create_global_value(ir::GlobalValueData::VMContext {}); - // { - // offset: tables_offset.into(), - // }); - // self.mod_info.globals_base = Some(new_base); - new_base - }); - - let table_data_offset = (table_index as usize * ptr_size * 2) as i32; - - let new_table_addr_addr = func.create_global_value(ir::GlobalValueData::Load { - base, - offset: table_data_offset.into(), - global_type: self.pointer_type(), // Might be I32 - }); - let new_table_addr = func.create_global_value(ir::GlobalValueData::Load { - base: new_table_addr_addr, - offset: 0.into(), - global_type: self.pointer_type(), // Might be I32 - }); - - let new_table_bounds_addr = func.create_global_value(ir::GlobalValueData::Load { - base, - offset: (table_data_offset + ptr_size as i32).into(), - global_type: self.pointer_type(), // Might be I32 + let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); + let base_gv = func.create_global_value(ir::GlobalValueData::Load { + base: vmctx, + offset: Offset32::new(0), + global_type: self.pointer_type(), }); - let new_table_bounds = func.create_global_value(ir::GlobalValueData::Load { - base: new_table_bounds_addr, - offset: 0.into(), - global_type: I32, // Might be self.pointer_type() + let bound_gv = func.create_global_value(ir::GlobalValueData::Load { + base: vmctx, + offset: Offset32::new(0), + global_type: I64, }); let table = func.create_table(ir::TableData { - base_gv: new_table_addr, + base_gv: base_gv, min_size: Imm64::new(0), - // min_size: (self.mod_info.tables[table_index].size as i64).into(), - bound_gv: new_table_bounds, - element_size: (ptr_size as i64).into(), - index_type: I32, + bound_gv, + element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2), + index_type: I64, }); - + println!("FUNC {:?}", func); table + // let ptr_size = self.ptr_size(); + + // let base = self.mod_info.tables_base.unwrap_or_else(|| { + // let tables_offset = self.ptr_size() as i32 * -1; + // let new_base = func.create_global_value(ir::GlobalValueData::VMContext {}); + // // { + // // offset: tables_offset.into(), + // // }); + // // self.mod_info.globals_base = Some(new_base); + // new_base + // }); + + // let table_data_offset = (table_index as usize * ptr_size * 2) as i32; + + // let new_table_addr_addr = func.create_global_value(ir::GlobalValueData::Load { + // base, + // offset: table_data_offset.into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + // let new_table_addr = func.create_global_value(ir::GlobalValueData::Load { + // base: new_table_addr_addr, + // offset: 0.into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + + // let new_table_bounds_addr = func.create_global_value(ir::GlobalValueData::Load { + // base, + // offset: (table_data_offset + ptr_size as i32).into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + // let new_table_bounds = func.create_global_value(ir::GlobalValueData::Load { + // base: new_table_bounds_addr, + // offset: 0.into(), + // global_type: I32, // Might be self.pointer_type() + // }); + + // let table = func.create_table(ir::TableData { + // base_gv: new_table_addr, + // min_size: Imm64::new(0), + // // min_size: (self.mod_info.tables[table_index].size as i64).into(), + // bound_gv: new_table_bounds, + // element_size: (ptr_size as i64).into(), + // index_type: I32, + // }); + + // table } fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef { @@ -501,7 +502,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { &mut self, mut pos: FuncCursor, _table_index: TableIndex, - _table: ir::Table, + table: ir::Table, _sig_index: SignatureIndex, sig_ref: ir::SigRef, callee: ir::Value, @@ -518,15 +519,23 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // TODO: Generate bounds checking code. let ptr = self.pointer_type(); let callee_offset = if ptr == I32 { - pos.ins().imul_imm(callee, 4) + // pos.ins().imul_imm(callee, 4) + callee } else { let ext = pos.ins().uextend(I64, callee); - pos.ins().imul_imm(ext, 4) + ext + // pos.ins().imul_imm(ext, 4) }; + let entry_addr = pos.ins().table_addr( + self.pointer_type(), + table, + callee_offset, + 0, + ); let mut mflags = ir::MemFlags::new(); mflags.set_notrap(); mflags.set_aligned(); - let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0); + let func_ptr = pos.ins().load(ptr, mflags, entry_addr, 0); // Build a value list for the indirect call instruction containing the callee, call_args, // and the vmctx parameter. @@ -535,10 +544,14 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists); args.push(vmctx, &mut pos.func.dfg.value_lists); - Ok(pos + let inst = pos .ins() .CallIndirect(ir::Opcode::CallIndirect, INVALID, sig_ref, args) - .0) + .0; + + println!("FUNC {:?}", pos.func); + + Ok(inst) } fn translate_call( From 975b106731f8110cfa7034c338295c3adf2db4f9 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 01:44:19 +0200 Subject: [PATCH 07/16] Improved pointers --- src/main.rs | 14 ++++++++++---- src/webassembly/module.rs | 20 +++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3ae7f388786..6f71960ed67 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,13 +85,19 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { Some(&webassembly::Export::Function(index)) => index, _ => panic!("Mainn function not found"), }; - let mainn: fn(*const u8) -> i32 = get_instance_function!(instance, mainn_func_index); + let mainn: fn(*const usize) -> i32 = get_instance_function!(instance, mainn_func_index); let context = &instance.generate_context(); + let pointer_context = &context as *const _; // println!("Context ptr {:p}", context); - // println!("Context ptr {:?}", &context as *const _); + println!("Context ptr {:?}", pointer_context); // println!("Context ptr {:?}", &context as *const _); // println!("Memories ptr {:?}", context.memories.as_ptr()); - // println!("Tables ptr {:?}", context.tables.as_ptr()); + let pointer_tables = &context.tables as *const _; + println!("Tables ptr {:?}", pointer_tables); + println!("Tables ptr {:p}", pointer_tables); + let ref tables_ptr_2 = unsafe { (&*pointer_tables as *const _) }; + println!("Tables ptr {:?}", tables_ptr_2); + println!("DIFF {:?}", (pointer_tables as usize-pointer_context as usize)); // println!("Tables ptr {:?}", context.tables.as_ptr()); // println!("Tables ptr {:?}", &context.tables as *const _); // println!("Tables ptr {:?}", &context.tables as *const _); @@ -107,7 +113,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { // let table: &Ta main(&context); println!("-------------NOW MAINN----------"); - let res = mainn(context.tables.as_ptr() as *const u8); + let res = mainn(pointer_tables as *const usize); println!("RESULT {:?}", res); Ok(()) } diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index f80603339b0..a7812fa1f58 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -410,23 +410,33 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // OLD // Create a table whose base address is stored at `vmctx+0`. let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); - let base_gv = func.create_global_value(ir::GlobalValueData::Load { + let ptr_size = self.ptr_size(); + // This will be 0 when the index is 0, not sure if the offset will work regardless + let base = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, offset: Offset32::new(0), global_type: self.pointer_type(), }); + + let table_data_offset = (table_index as usize * ptr_size * 2) as i32; + + let base_gv = func.create_global_value(ir::GlobalValueData::Load { + base: base, + offset: Offset32::new(table_data_offset), + global_type: self.pointer_type(), + }); let bound_gv = func.create_global_value(ir::GlobalValueData::Load { - base: vmctx, - offset: Offset32::new(0), + base: base, + offset: Offset32::new(table_data_offset), global_type: I64, }); - + let table = func.create_table(ir::TableData { base_gv: base_gv, min_size: Imm64::new(0), bound_gv, element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2), - index_type: I64, + index_type: self.pointer_type(), }); println!("FUNC {:?}", func); table From 81ab8951c9d75ae6d50d5fde4dca347d38e7f774 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 01:52:03 +0200 Subject: [PATCH 08/16] Working fully with the context pointer --- src/main.rs | 2 +- src/webassembly/module.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6f71960ed67..4ef2fd052e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -113,7 +113,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { // let table: &Ta main(&context); println!("-------------NOW MAINN----------"); - let res = mainn(pointer_tables as *const usize); + let res = mainn(pointer_context as *const usize); println!("RESULT {:?}", res); Ok(()) } diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index a7812fa1f58..eae0f740004 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -407,19 +407,21 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { } fn make_table(&mut self, func: &mut ir::Function, table_index: TableIndex) -> ir::Table { - // OLD - // Create a table whose base address is stored at `vmctx+0`. let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_size = self.ptr_size(); - // This will be 0 when the index is 0, not sure if the offset will work regardless + + // Given a vmctx, we want to retrieve vmctx.tables + // Create a table whose base address is stored at `vmctx+120`. let base = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, - offset: Offset32::new(0), + offset: Offset32::new(120), // The offset of the vmctx.tables pointer respect to vmctx pointer global_type: self.pointer_type(), }); + // This will be 0 when the index is 0, not sure if the offset will work regardless let table_data_offset = (table_index as usize * ptr_size * 2) as i32; + // We get the pointer for our table index let base_gv = func.create_global_value(ir::GlobalValueData::Load { base: base, offset: Offset32::new(table_data_offset), From a796056c5f74f1ff15886905d68e1d1e815f41b1 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:09:57 +0200 Subject: [PATCH 09/16] Improved module docs --- src/webassembly/module.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index eae0f740004..f34e05e6abf 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -412,9 +412,10 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // Given a vmctx, we want to retrieve vmctx.tables // Create a table whose base address is stored at `vmctx+120`. + // 120 is the offset of the vmctx.tables pointer respect to vmctx pointer let base = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, - offset: Offset32::new(120), // The offset of the vmctx.tables pointer respect to vmctx pointer + offset: Offset32::new(120), global_type: self.pointer_type(), }); From 46742c9aaf6973844f6d97f9763f7473b66e8b92 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:40:17 +0200 Subject: [PATCH 10/16] Call indirect fully working --- spectests/call_indirect.wast | 779 ++++++++++++ src/build_spectests.rs | 3 +- src/integrations/mod.rs | 54 +- src/main.rs | 38 +- src/spectests/call_indirect.rs | 2028 ++++++++++++++++++++++++++++++++ src/spectests/mod.rs | 1 + src/webassembly/instance.rs | 20 +- src/webassembly/module.rs | 12 +- 8 files changed, 2856 insertions(+), 79 deletions(-) create mode 100644 spectests/call_indirect.wast create mode 100644 src/spectests/call_indirect.rs diff --git a/spectests/call_indirect.wast b/spectests/call_indirect.wast new file mode 100644 index 00000000000..32a608263c7 --- /dev/null +++ b/spectests/call_indirect.wast @@ -0,0 +1,779 @@ +;; Test `call_indirect` operator + +(module + ;; Auxiliary definitions + (type $proc (func)) + (type $out-i32 (func (result i32))) + (type $out-i64 (func (result i64))) + (type $out-f32 (func (result f32))) + (type $out-f64 (func (result f64))) + (type $over-i32 (func (param i32) (result i32))) + (type $over-i64 (func (param i64) (result i64))) + (type $over-f32 (func (param f32) (result f32))) + (type $over-f64 (func (param f64) (result f64))) + (type $f32-i32 (func (param f32 i32) (result i32))) + (type $i32-i64 (func (param i32 i64) (result i64))) + (type $f64-f32 (func (param f64 f32) (result f32))) + (type $i64-f64 (func (param i64 f64) (result f64))) + (type $over-i32-duplicate (func (param i32) (result i32))) + (type $over-i64-duplicate (func (param i64) (result i64))) + (type $over-f32-duplicate (func (param f32) (result f32))) + (type $over-f64-duplicate (func (param f64) (result f64))) + + (func $const-i32 (type $out-i32) (i32.const 0x132)) + (func $const-i64 (type $out-i64) (i64.const 0x164)) + (func $const-f32 (type $out-f32) (f32.const 0xf32)) + (func $const-f64 (type $out-f64) (f64.const 0xf64)) + + (func $id-i32 (type $over-i32) (get_local 0)) + (func $id-i64 (type $over-i64) (get_local 0)) + (func $id-f32 (type $over-f32) (get_local 0)) + (func $id-f64 (type $over-f64) (get_local 0)) + + (func $i32-i64 (type $i32-i64) (get_local 1)) + (func $i64-f64 (type $i64-f64) (get_local 1)) + (func $f32-i32 (type $f32-i32) (get_local 1)) + (func $f64-f32 (type $f64-f32) (get_local 1)) + + (func $over-i32-duplicate (type $over-i32-duplicate) (get_local 0)) + (func $over-i64-duplicate (type $over-i64-duplicate) (get_local 0)) + (func $over-f32-duplicate (type $over-f32-duplicate) (get_local 0)) + (func $over-f64-duplicate (type $over-f64-duplicate) (get_local 0)) + + (table anyfunc + (elem + $const-i32 $const-i64 $const-f32 $const-f64 + $id-i32 $id-i64 $id-f32 $id-f64 + $f32-i32 $i32-i64 $f64-f32 $i64-f64 + $fac-i64 $fib-i64 $even $odd + $runaway $mutual-runaway1 $mutual-runaway2 + $over-i32-duplicate $over-i64-duplicate + $over-f32-duplicate $over-f64-duplicate + $fac-i32 $fac-f32 $fac-f64 + $fib-i32 $fib-f32 $fib-f64 + ) + ) + + ;; Syntax + + (func + (call_indirect (i32.const 0)) + (call_indirect (param i64) (i64.const 0) (i32.const 0)) + (call_indirect (param i64) (param) (param f64 i32 i64) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + (call_indirect (result) (i32.const 0)) + (drop (i32.eqz (call_indirect (result i32) (i32.const 0)))) + (drop (i32.eqz (call_indirect (result i32) (result) (i32.const 0)))) + (drop (i32.eqz + (call_indirect (param i64) (result i32) (i64.const 0) (i32.const 0)) + )) + (drop (i32.eqz + (call_indirect + (param) (param i64) (param) (param f64 i32 i64) (param) (param) + (result) (result i32) (result) (result) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + )) + (drop (i64.eqz + (call_indirect (type $over-i64) (param i64) (result i64) + (i64.const 0) (i32.const 0) + ) + )) + ) + + ;; Typing + + (func (export "type-i32") (result i32) + (call_indirect (type $out-i32) (i32.const 0)) + ) + (func (export "type-i64") (result i64) + (call_indirect (type $out-i64) (i32.const 1)) + ) + (func (export "type-f32") (result f32) + (call_indirect (type $out-f32) (i32.const 2)) + ) + (func (export "type-f64") (result f64) + (call_indirect (type $out-f64) (i32.const 3)) + ) + + (func (export "type-index") (result i64) + (call_indirect (type $over-i64) (i64.const 100) (i32.const 5)) + ) + + (func (export "type-first-i32") (result i32) + (call_indirect (type $over-i32) (i32.const 32) (i32.const 4)) + ) + (func (export "type-first-i64") (result i64) + (call_indirect (type $over-i64) (i64.const 64) (i32.const 5)) + ) + (func (export "type-first-f32") (result f32) + (call_indirect (type $over-f32) (f32.const 1.32) (i32.const 6)) + ) + (func (export "type-first-f64") (result f64) + (call_indirect (type $over-f64) (f64.const 1.64) (i32.const 7)) + ) + + (func (export "type-second-i32") (result i32) + (call_indirect (type $f32-i32) (f32.const 32.1) (i32.const 32) (i32.const 8)) + ) + (func (export "type-second-i64") (result i64) + (call_indirect (type $i32-i64) (i32.const 32) (i64.const 64) (i32.const 9)) + ) + (func (export "type-second-f32") (result f32) + (call_indirect (type $f64-f32) (f64.const 64) (f32.const 32) (i32.const 10)) + ) + (func (export "type-second-f64") (result f64) + (call_indirect (type $i64-f64) (i64.const 64) (f64.const 64.1) (i32.const 11)) + ) + + ;; Dispatch + + (func (export "dispatch") (param i32 i64) (result i64) + (call_indirect (type $over-i64) (get_local 1) (get_local 0)) + ) + + (func (export "dispatch-structural-i64") (param i32) (result i64) + (call_indirect (type $over-i64-duplicate) (i64.const 9) (get_local 0)) + ) + (func (export "dispatch-structural-i32") (param i32) (result i32) + (call_indirect (type $over-i32-duplicate) (i32.const 9) (get_local 0)) + ) + (func (export "dispatch-structural-f32") (param i32) (result f32) + (call_indirect (type $over-f32-duplicate) (f32.const 9.0) (get_local 0)) + ) + (func (export "dispatch-structural-f64") (param i32) (result f64) + (call_indirect (type $over-f64-duplicate) (f64.const 9.0) (get_local 0)) + ) + + ;; Recursion + + (func $fac-i64 (export "fac-i64") (type $over-i64) + (if (result i64) (i64.eqz (get_local 0)) + (then (i64.const 1)) + (else + (i64.mul + (get_local 0) + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 1)) + (i32.const 12) + ) + ) + ) + ) + ) + + (func $fib-i64 (export "fib-i64") (type $over-i64) + (if (result i64) (i64.le_u (get_local 0) (i64.const 1)) + (then (i64.const 1)) + (else + (i64.add + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 2)) + (i32.const 13) + ) + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 1)) + (i32.const 13) + ) + ) + ) + ) + ) + + (func $fac-i32 (export "fac-i32") (type $over-i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 1)) + (else + (i32.mul + (get_local 0) + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 23) + ) + ) + ) + ) + ) + + (func $fac-f32 (export "fac-f32") (type $over-f32) + (if (result f32) (f32.eq (get_local 0) (f32.const 0.0)) + (then (f32.const 1.0)) + (else + (f32.mul + (get_local 0) + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 1.0)) + (i32.const 24) + ) + ) + ) + ) + ) + + (func $fac-f64 (export "fac-f64") (type $over-f64) + (if (result f64) (f64.eq (get_local 0) (f64.const 0.0)) + (then (f64.const 1.0)) + (else + (f64.mul + (get_local 0) + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 1.0)) + (i32.const 25) + ) + ) + ) + ) + ) + + (func $fib-i32 (export "fib-i32") (type $over-i32) + (if (result i32) (i32.le_u (get_local 0) (i32.const 1)) + (then (i32.const 1)) + (else + (i32.add + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 2)) + (i32.const 26) + ) + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 26) + ) + ) + ) + ) + ) + + (func $fib-f32 (export "fib-f32") (type $over-f32) + (if (result f32) (f32.le (get_local 0) (f32.const 1.0)) + (then (f32.const 1.0)) + (else + (f32.add + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 2.0)) + (i32.const 27) + ) + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 1.0)) + (i32.const 27) + ) + ) + ) + ) + ) + + (func $fib-f64 (export "fib-f64") (type $over-f64) + (if (result f64) (f64.le (get_local 0) (f64.const 1.0)) + (then (f64.const 1.0)) + (else + (f64.add + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 2.0)) + (i32.const 28) + ) + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 1.0)) + (i32.const 28) + ) + ) + ) + ) + ) + + (func $even (export "even") (param i32) (result i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 44)) + (else + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 15) + ) + ) + ) + ) + (func $odd (export "odd") (param i32) (result i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 99)) + (else + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 14) + ) + ) + ) + ) + + ;; Stack exhaustion + + ;; Implementations are required to have every call consume some abstract + ;; resource towards exhausting some abstract finite limit, such that + ;; infinitely recursive test cases reliably trap in finite time. This is + ;; because otherwise applications could come to depend on it on those + ;; implementations and be incompatible with implementations that don't do + ;; it (or don't do it under the same circumstances). + + (func $runaway (export "runaway") (call_indirect (type $proc) (i32.const 16))) + + (func $mutual-runaway1 (export "mutual-runaway") (call_indirect (type $proc) (i32.const 18))) + (func $mutual-runaway2 (call_indirect (type $proc) (i32.const 17))) + + ;; As parameter of control constructs and instructions + + (memory 1) + + (func (export "as-select-first") (result i32) + (select (call_indirect (type $out-i32) (i32.const 0)) (i32.const 2) (i32.const 3)) + ) + (func (export "as-select-mid") (result i32) + (select (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (i32.const 3)) + ) + (func (export "as-select-last") (result i32) + (select (i32.const 2) (i32.const 3) (call_indirect (type $out-i32) (i32.const 0))) + ) + + (func (export "as-if-condition") (result i32) + (if (result i32) (call_indirect (type $out-i32) (i32.const 0)) (then (i32.const 1)) (else (i32.const 2))) + ) + + (func (export "as-br_if-first") (result i64) + (block (result i64) (br_if 0 (call_indirect (type $out-i64) (i32.const 1)) (i32.const 2))) + ) + (func (export "as-br_if-last") (result i32) + (block (result i32) (br_if 0 (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)))) + ) + + (func (export "as-br_table-first") (result f32) + (block (result f32) (call_indirect (type $out-f32) (i32.const 2)) (i32.const 2) (br_table 0 0)) + ) + (func (export "as-br_table-last") (result i32) + (block (result i32) (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (br_table 0 0)) + ) + + (func (export "as-store-first") + (call_indirect (type $out-i32) (i32.const 0)) (i32.const 1) (i32.store) + ) + (func (export "as-store-last") + (i32.const 10) (call_indirect (type $out-f64) (i32.const 3)) (f64.store) + ) + + (func (export "as-memory.grow-value") (result i32) + (memory.grow (call_indirect (type $out-i32) (i32.const 0))) + ) + (func (export "as-return-value") (result i32) + (call_indirect (type $over-i32) (i32.const 1) (i32.const 4)) (return) + ) + (func (export "as-drop-operand") + (call_indirect (type $over-i64) (i64.const 1) (i32.const 5)) (drop) + ) + (func (export "as-br-value") (result f32) + (block (result f32) (br 0 (call_indirect (type $over-f32) (f32.const 1) (i32.const 6)))) + ) + (func (export "as-set_local-value") (result f64) + (local f64) (set_local 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (get_local 0) + ) + (func (export "as-load-operand") (result i32) + (i32.load (call_indirect (type $out-i32) (i32.const 0))) + ) +) + +(assert_return (invoke "type-i32") (i32.const 0x132)) +(assert_return (invoke "type-i64") (i64.const 0x164)) +(assert_return (invoke "type-f32") (f32.const 0xf32)) +(assert_return (invoke "type-f64") (f64.const 0xf64)) + +(assert_return (invoke "type-index") (i64.const 100)) + +(assert_return (invoke "type-first-i32") (i32.const 32)) +(assert_return (invoke "type-first-i64") (i64.const 64)) +(assert_return (invoke "type-first-f32") (f32.const 1.32)) +(assert_return (invoke "type-first-f64") (f64.const 1.64)) + +(assert_return (invoke "type-second-i32") (i32.const 32)) +(assert_return (invoke "type-second-i64") (i64.const 64)) +(assert_return (invoke "type-second-f32") (f32.const 32)) +(assert_return (invoke "type-second-f64") (f64.const 64.1)) + +(assert_return (invoke "dispatch" (i32.const 5) (i64.const 2)) (i64.const 2)) +(assert_return (invoke "dispatch" (i32.const 5) (i64.const 5)) (i64.const 5)) +(assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120)) +(assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8)) +(assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2)) +(assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch") +(assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch") +(assert_trap (invoke "dispatch" (i32.const 29) (i64.const 2)) "undefined element") +(assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element") +(assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element") + +(assert_return (invoke "dispatch-structural-i64" (i32.const 5)) (i64.const 9)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 12)) (i64.const 362880)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 13)) (i64.const 55)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 20)) (i64.const 9)) +(assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-i32" (i32.const 4)) (i32.const 9)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 23)) (i32.const 362880)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 26)) (i32.const 55)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 19)) (i32.const 9)) +(assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-f32" (i32.const 6)) (f32.const 9.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 24)) (f32.const 362880.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 27)) (f32.const 55.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 21)) (f32.const 9.0)) +(assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-f64" (i32.const 7)) (f64.const 9.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 25)) (f64.const 362880.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 28)) (f64.const 55.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 22)) (f64.const 9.0)) +(assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch") + +(assert_return (invoke "fac-i64" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "fac-i64" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "fac-i64" (i64.const 5)) (i64.const 120)) +(assert_return (invoke "fac-i64" (i64.const 25)) (i64.const 7034535277573963776)) + +(assert_return (invoke "fac-i32" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "fac-i32" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "fac-i32" (i32.const 5)) (i32.const 120)) +(assert_return (invoke "fac-i32" (i32.const 10)) (i32.const 3628800)) + +(assert_return (invoke "fac-f32" (f32.const 0.0)) (f32.const 1.0)) +(assert_return (invoke "fac-f32" (f32.const 1.0)) (f32.const 1.0)) +(assert_return (invoke "fac-f32" (f32.const 5.0)) (f32.const 120.0)) +(assert_return (invoke "fac-f32" (f32.const 10.0)) (f32.const 3628800.0)) + +(assert_return (invoke "fac-f64" (f64.const 0.0)) (f64.const 1.0)) +(assert_return (invoke "fac-f64" (f64.const 1.0)) (f64.const 1.0)) +(assert_return (invoke "fac-f64" (f64.const 5.0)) (f64.const 120.0)) +(assert_return (invoke "fac-f64" (f64.const 10.0)) (f64.const 3628800.0)) + +(assert_return (invoke "fib-i64" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "fib-i64" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "fib-i64" (i64.const 2)) (i64.const 2)) +(assert_return (invoke "fib-i64" (i64.const 5)) (i64.const 8)) +(assert_return (invoke "fib-i64" (i64.const 20)) (i64.const 10946)) + +(assert_return (invoke "fib-i32" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "fib-i32" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "fib-i32" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "fib-i32" (i32.const 5)) (i32.const 8)) +(assert_return (invoke "fib-i32" (i32.const 20)) (i32.const 10946)) + +(assert_return (invoke "fib-f32" (f32.const 0.0)) (f32.const 1.0)) +(assert_return (invoke "fib-f32" (f32.const 1.0)) (f32.const 1.0)) +(assert_return (invoke "fib-f32" (f32.const 2.0)) (f32.const 2.0)) +(assert_return (invoke "fib-f32" (f32.const 5.0)) (f32.const 8.0)) +(assert_return (invoke "fib-f32" (f32.const 20.0)) (f32.const 10946.0)) + +(assert_return (invoke "fib-f64" (f64.const 0.0)) (f64.const 1.0)) +(assert_return (invoke "fib-f64" (f64.const 1.0)) (f64.const 1.0)) +(assert_return (invoke "fib-f64" (f64.const 2.0)) (f64.const 2.0)) +(assert_return (invoke "fib-f64" (f64.const 5.0)) (f64.const 8.0)) +(assert_return (invoke "fib-f64" (f64.const 20.0)) (f64.const 10946.0)) + +(assert_return (invoke "even" (i32.const 0)) (i32.const 44)) +(assert_return (invoke "even" (i32.const 1)) (i32.const 99)) +(assert_return (invoke "even" (i32.const 100)) (i32.const 44)) +(assert_return (invoke "even" (i32.const 77)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 0)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 1)) (i32.const 44)) +(assert_return (invoke "odd" (i32.const 200)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 77)) (i32.const 44)) + +(assert_exhaustion (invoke "runaway") "call stack exhausted") +(assert_exhaustion (invoke "mutual-runaway") "call stack exhausted") + +(assert_return (invoke "as-select-first") (i32.const 0x132)) +(assert_return (invoke "as-select-mid") (i32.const 2)) +(assert_return (invoke "as-select-last") (i32.const 2)) + +(assert_return (invoke "as-if-condition") (i32.const 1)) + +(assert_return (invoke "as-br_if-first") (i64.const 0x164)) +(assert_return (invoke "as-br_if-last") (i32.const 2)) + +(assert_return (invoke "as-br_table-first") (f32.const 0xf32)) +(assert_return (invoke "as-br_table-last") (i32.const 2)) + +;; (assert_return (invoke "as-store-first")) +;; (assert_return (invoke "as-store-last")) + +;; (assert_return (invoke "as-memory.grow-value") (i32.const 1)) +(assert_return (invoke "as-return-value") (i32.const 1)) +(assert_return (invoke "as-drop-operand")) +(assert_return (invoke "as-br-value") (f32.const 1)) +(assert_return (invoke "as-set_local-value") (f64.const 1)) +;; (assert_return (invoke "as-load-operand") (i32.const 1)) + +;; Invalid syntax + +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (type $sig) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (result i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (type $sig) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "unexpected token" +) + +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func" + " (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32 i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (param i32) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "inline function type" +) + +;; Invalid typing + +(assert_invalid + (module + (type (func)) + (func $no-table (call_indirect (type 0) (i32.const 0))) + ) + "unknown table" +) + +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (result i64))) + (table 0 anyfunc) + (func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param f64 i32))) + (table 0 anyfunc) + (func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $arity-2-vs-0 + (call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1))) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32 i32))) + (table 0 anyfunc) + (func $type-first-void-vs-num + (call_indirect (type 0) (nop) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32 i32))) + (table 0 anyfunc) + (func $type-second-void-vs-num + (call_indirect (type 0) (i32.const 1) (nop) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32 f64))) + (table 0 anyfunc) + (func $type-first-num-vs-num + (call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param f64 i32))) + (table 0 anyfunc) + (func $type-second-num-vs-num + (call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) + + +;; Unbound type + +(assert_invalid + (module + (table 0 anyfunc) + (func $unbound-type (call_indirect (type 1) (i32.const 0))) + ) + "unknown type" +) +(assert_invalid + (module + (table 0 anyfunc) + (func $large-type (call_indirect (type 1012321300) (i32.const 0))) + ) + "unknown type" +) + + +;; Unbound function in table + +(assert_invalid + (module (table anyfunc (elem 0 0))) + "unknown function 0" +) diff --git a/src/build_spectests.rs b/src/build_spectests.rs index e2860f107ea..7a55f6de23b 100644 --- a/src/build_spectests.rs +++ b/src/build_spectests.rs @@ -8,9 +8,10 @@ use wabt::wasm2wat; static BANNER: &str = "// Rust test file autogenerated with cargo build (src/build_spectests.rs). // Please do NOT modify it by hand, as it will be reseted on next build.\n"; -const TESTS: [&str; 6] = [ +const TESTS: [&str; 7] = [ "spectests/br_if.wast", "spectests/call.wast", + "spectests/call_indirect.wast", "spectests/i32_.wast", "spectests/memory.wast", "spectests/set_local.wast", diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index 163226166f6..b4edc78431f 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -1,32 +1,32 @@ use crate::webassembly::{ImportObject, VmCtx}; -// use libc::putchar; +use libc::putchar; -extern fn putchar(a: *const u8, context: *const u8) { - println!("PUT CHAAAR original pointer {:?}", context); - let vmctx: &VmCtx = unsafe { &*(context as *const VmCtx) }; - println!("PUT CHAAAR {}", vmctx.test); - println!("PUT CHAAAR pointer {:p}", vmctx); - let x = vmctx as *const _; - let x_tables = vmctx.tables.as_ptr(); - let tables_ptr_1 = (&vmctx.tables) as *const _; - let tables_ptr_2 = unsafe { (&vmctx.tables.get_unchecked(0)) as *const _ }; - let tables_ptr_3 = &vmctx.tables as *const _ ; - let tables_ptr_4 = &vmctx.tables as *const _ ; - // let tables: &Vec> = unsafe { &*(tables_ptr_4 as *const Vec>) }; - let x_tables_serial: &Vec<*const usize> = unsafe { &*(tables_ptr_1 as *const Vec<*const usize>) }; - // let tables: &Vec<> = vmctx.tables as &Vec>; - println!("PUT CHAAAR pointer {:?}", x); - println!("PUT CHAAAR pointer 1 {:p}", &vmctx.tables); - println!("PUT CHAAAR pointer 2 {:p}", tables_ptr_1); - println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_2); - println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_3); - // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", tables_ptr_4, tables); - // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables, vmctx.tables); - // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables[0], vmctx.tables[0]); - println!("PUT CHAAAR pointer {:?} {:?}", x_tables, x_tables_serial); - let x_tables = vmctx.tables.as_ptr(); - println!("PUT CHAAAR pointer {:?}", x_tables); -} +// extern fn putchar(a: *const u8, context: *const u8) { +// println!("PUT CHAAAR original pointer {:?}", context); +// let vmctx: &VmCtx = unsafe { &*(context as *const VmCtx) }; +// println!("PUT CHAAAR {}", vmctx.test); +// println!("PUT CHAAAR pointer {:p}", vmctx); +// let x = vmctx as *const _; +// let x_tables = vmctx.tables.as_ptr(); +// let tables_ptr_1 = (&vmctx.tables) as *const _; +// let tables_ptr_2 = unsafe { (&vmctx.tables.get_unchecked(0)) as *const _ }; +// let tables_ptr_3 = &vmctx.tables as *const _ ; +// let tables_ptr_4 = &vmctx.tables as *const _ ; +// // let tables: &Vec> = unsafe { &*(tables_ptr_4 as *const Vec>) }; +// let x_tables_serial: &Vec<*const usize> = unsafe { &*(tables_ptr_1 as *const Vec<*const usize>) }; +// // let tables: &Vec<> = vmctx.tables as &Vec>; +// println!("PUT CHAAAR pointer {:?}", x); +// println!("PUT CHAAAR pointer 1 {:p}", &vmctx.tables); +// println!("PUT CHAAAR pointer 2 {:p}", tables_ptr_1); +// println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_2); +// println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_3); +// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", tables_ptr_4, tables); +// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables, vmctx.tables); +// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables[0], vmctx.tables[0]); +// println!("PUT CHAAAR pointer {:?} {:?}", x_tables, x_tables_serial); +// let x_tables = vmctx.tables.as_ptr(); +// println!("PUT CHAAAR pointer {:?}", x_tables); +// } pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { let mut import_object = ImportObject::new(); diff --git a/src/main.rs b/src/main.rs index 4ef2fd052e0..7c9807b38b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,10 @@ extern crate target_lexicon; extern crate spin; use std::time::{Duration, Instant}; +use std::alloc::System; + +// #[global_allocator] +// static A: System = System; // #[macro_use] extern crate log; @@ -81,40 +85,8 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { _ => panic!("Main function not found"), }); let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); - let mainn_func_index = match module.info.exports.get("mainn") { - Some(&webassembly::Export::Function(index)) => index, - _ => panic!("Mainn function not found"), - }; - let mainn: fn(*const usize) -> i32 = get_instance_function!(instance, mainn_func_index); - let context = &instance.generate_context(); - let pointer_context = &context as *const _; - // println!("Context ptr {:p}", context); - println!("Context ptr {:?}", pointer_context); - // println!("Context ptr {:?}", &context as *const _); - // println!("Memories ptr {:?}", context.memories.as_ptr()); - let pointer_tables = &context.tables as *const _; - println!("Tables ptr {:?}", pointer_tables); - println!("Tables ptr {:p}", pointer_tables); - let ref tables_ptr_2 = unsafe { (&*pointer_tables as *const _) }; - println!("Tables ptr {:?}", tables_ptr_2); - println!("DIFF {:?}", (pointer_tables as usize-pointer_context as usize)); - // println!("Tables ptr {:?}", context.tables.as_ptr()); - // println!("Tables ptr {:?}", &context.tables as *const _); - // println!("Tables ptr {:?}", &context.tables as *const _); - // println!("User data ptr {:?}", &context.user_data as *const _); - // println!("Globals ptr {:?}", &context.globals as *const _); - // println!("Memories ptr {:?}", &context.memories as *const _); - // println!("Tables ptr {:?}", &context.tables as *const _); - // unsafe { - // println!("Tables 0 ptr {:p}", &context.tables.get_unchecked(0)); - // println!("Tables 0 ptr {:p}", &context.tables.get_unchecked(0).get(0)); - // } - let table_ptr = &context.tables as *const _; - // let table: &Ta + let context = instance.generate_context(); main(&context); - println!("-------------NOW MAINN----------"); - let res = mainn(pointer_context as *const usize); - println!("RESULT {:?}", res); Ok(()) } diff --git a/src/spectests/call_indirect.rs b/src/spectests/call_indirect.rs new file mode 100644 index 00000000000..4a6f0dce4b9 --- /dev/null +++ b/src/spectests/call_indirect.rs @@ -0,0 +1,2028 @@ +// Rust test file autogenerated with cargo build (src/build_spectests.rs). +// Please do NOT modify it by hand, as it will be reseted on next build. +// Test based on spectests/call_indirect.wast + +use crate::webassembly::{instantiate, compile, ImportObject, ResultObject, VmCtx, Export}; +use wabt::wat2wasm; + + +// Line 3 +fn create_module_1() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + (type (;2;) (func (result i64))) + (type (;3;) (func (result f32))) + (type (;4;) (func (result f64))) + (type (;5;) (func (param i32) (result i32))) + (type (;6;) (func (param i64) (result i64))) + (type (;7;) (func (param f32) (result f32))) + (type (;8;) (func (param f64) (result f64))) + (type (;9;) (func (param f32 i32) (result i32))) + (type (;10;) (func (param i32 i64) (result i64))) + (type (;11;) (func (param f64 f32) (result f32))) + (type (;12;) (func (param i64 f64) (result f64))) + (type (;13;) (func (param i32) (result i32))) + (type (;14;) (func (param i64) (result i64))) + (type (;15;) (func (param f32) (result f32))) + (type (;16;) (func (param f64) (result f64))) + (type (;17;) (func (param i64))) + (type (;18;) (func (param i64 f64 i32 i64))) + (type (;19;) (func (param i64) (result i32))) + (type (;20;) (func (param i64 f64 i32 i64) (result i32))) + (type (;21;) (func (param i32) (result i64))) + (type (;22;) (func (param i32) (result f32))) + (type (;23;) (func (param i32) (result f64))) + (func (;0;) (type 1) (result i32) + i32.const 306) + (func (;1;) (type 2) (result i64) + i64.const 356) + (func (;2;) (type 3) (result f32) + f32.const 0x1.e64p+11 (;=3890;)) + (func (;3;) (type 4) (result f64) + f64.const 0x1.ec8p+11 (;=3940;)) + (func (;4;) (type 5) (param i32) (result i32) + get_local 0) + (func (;5;) (type 6) (param i64) (result i64) + get_local 0) + (func (;6;) (type 7) (param f32) (result f32) + get_local 0) + (func (;7;) (type 8) (param f64) (result f64) + get_local 0) + (func (;8;) (type 10) (param i32 i64) (result i64) + get_local 1) + (func (;9;) (type 12) (param i64 f64) (result f64) + get_local 1) + (func (;10;) (type 9) (param f32 i32) (result i32) + get_local 1) + (func (;11;) (type 11) (param f64 f32) (result f32) + get_local 1) + (func (;12;) (type 13) (param i32) (result i32) + get_local 0) + (func (;13;) (type 14) (param i64) (result i64) + get_local 0) + (func (;14;) (type 15) (param f32) (result f32) + get_local 0) + (func (;15;) (type 16) (param f64) (result f64) + get_local 0) + (func (;16;) (type 0) + i32.const 0 + call_indirect (type 0) + i64.const 0 + i32.const 0 + call_indirect (type 17) + i64.const 0 + f64.const 0x0p+0 (;=0;) + i32.const 0 + i64.const 0 + i32.const 0 + call_indirect (type 18) + i32.const 0 + call_indirect (type 0) + i32.const 0 + call_indirect (type 1) + i32.eqz + drop + i32.const 0 + call_indirect (type 1) + i32.eqz + drop + i64.const 0 + i32.const 0 + call_indirect (type 19) + i32.eqz + drop + i64.const 0 + f64.const 0x0p+0 (;=0;) + i32.const 0 + i64.const 0 + i32.const 0 + call_indirect (type 20) + i32.eqz + drop + i64.const 0 + i32.const 0 + call_indirect (type 6) + i64.eqz + drop) + (func (;17;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1)) + (func (;18;) (type 2) (result i64) + i32.const 1 + call_indirect (type 2)) + (func (;19;) (type 3) (result f32) + i32.const 2 + call_indirect (type 3)) + (func (;20;) (type 4) (result f64) + i32.const 3 + call_indirect (type 4)) + (func (;21;) (type 2) (result i64) + i64.const 100 + i32.const 5 + call_indirect (type 6)) + (func (;22;) (type 1) (result i32) + i32.const 32 + i32.const 4 + call_indirect (type 5)) + (func (;23;) (type 2) (result i64) + i64.const 64 + i32.const 5 + call_indirect (type 6)) + (func (;24;) (type 3) (result f32) + f32.const 0x1.51eb86p+0 (;=1.32;) + i32.const 6 + call_indirect (type 7)) + (func (;25;) (type 4) (result f64) + f64.const 0x1.a3d70a3d70a3dp+0 (;=1.64;) + i32.const 7 + call_indirect (type 8)) + (func (;26;) (type 1) (result i32) + f32.const 0x1.00ccccp+5 (;=32.1;) + i32.const 32 + i32.const 8 + call_indirect (type 9)) + (func (;27;) (type 2) (result i64) + i32.const 32 + i64.const 64 + i32.const 9 + call_indirect (type 10)) + (func (;28;) (type 3) (result f32) + f64.const 0x1p+6 (;=64;) + f32.const 0x1p+5 (;=32;) + i32.const 10 + call_indirect (type 11)) + (func (;29;) (type 4) (result f64) + i64.const 64 + f64.const 0x1.0066666666666p+6 (;=64.1;) + i32.const 11 + call_indirect (type 12)) + (func (;30;) (type 10) (param i32 i64) (result i64) + get_local 1 + get_local 0 + call_indirect (type 6)) + (func (;31;) (type 21) (param i32) (result i64) + i64.const 9 + get_local 0 + call_indirect (type 14)) + (func (;32;) (type 5) (param i32) (result i32) + i32.const 9 + get_local 0 + call_indirect (type 13)) + (func (;33;) (type 22) (param i32) (result f32) + f32.const 0x1.2p+3 (;=9;) + get_local 0 + call_indirect (type 15)) + (func (;34;) (type 23) (param i32) (result f64) + f64.const 0x1.2p+3 (;=9;) + get_local 0 + call_indirect (type 16)) + (func (;35;) (type 6) (param i64) (result i64) + get_local 0 + i64.eqz + if (result i64) ;; label = @1 + i64.const 1 + else + get_local 0 + get_local 0 + i64.const 1 + i64.sub + i32.const 12 + call_indirect (type 6) + i64.mul + end) + (func (;36;) (type 6) (param i64) (result i64) + get_local 0 + i64.const 1 + i64.le_u + if (result i64) ;; label = @1 + i64.const 1 + else + get_local 0 + i64.const 2 + i64.sub + i32.const 13 + call_indirect (type 6) + get_local 0 + i64.const 1 + i64.sub + i32.const 13 + call_indirect (type 6) + i64.add + end) + (func (;37;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 1 + else + get_local 0 + get_local 0 + i32.const 1 + i32.sub + i32.const 23 + call_indirect (type 5) + i32.mul + end) + (func (;38;) (type 7) (param f32) (result f32) + get_local 0 + f32.const 0x0p+0 (;=0;) + f32.eq + if (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + else + get_local 0 + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.sub + i32.const 24 + call_indirect (type 7) + f32.mul + end) + (func (;39;) (type 8) (param f64) (result f64) + get_local 0 + f64.const 0x0p+0 (;=0;) + f64.eq + if (result f64) ;; label = @1 + f64.const 0x1p+0 (;=1;) + else + get_local 0 + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.sub + i32.const 25 + call_indirect (type 8) + f64.mul + end) + (func (;40;) (type 5) (param i32) (result i32) + get_local 0 + i32.const 1 + i32.le_u + if (result i32) ;; label = @1 + i32.const 1 + else + get_local 0 + i32.const 2 + i32.sub + i32.const 26 + call_indirect (type 5) + get_local 0 + i32.const 1 + i32.sub + i32.const 26 + call_indirect (type 5) + i32.add + end) + (func (;41;) (type 7) (param f32) (result f32) + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.le + if (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + else + get_local 0 + f32.const 0x1p+1 (;=2;) + f32.sub + i32.const 27 + call_indirect (type 7) + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.sub + i32.const 27 + call_indirect (type 7) + f32.add + end) + (func (;42;) (type 8) (param f64) (result f64) + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.le + if (result f64) ;; label = @1 + f64.const 0x1p+0 (;=1;) + else + get_local 0 + f64.const 0x1p+1 (;=2;) + f64.sub + i32.const 28 + call_indirect (type 8) + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.sub + i32.const 28 + call_indirect (type 8) + f64.add + end) + (func (;43;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 44 + else + get_local 0 + i32.const 1 + i32.sub + i32.const 15 + call_indirect (type 5) + end) + (func (;44;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 99 + else + get_local 0 + i32.const 1 + i32.sub + i32.const 14 + call_indirect (type 5) + end) + (func (;45;) (type 0) + i32.const 16 + call_indirect (type 0)) + (func (;46;) (type 0) + i32.const 18 + call_indirect (type 0)) + (func (;47;) (type 0) + i32.const 17 + call_indirect (type 0)) + (func (;48;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + i32.const 2 + i32.const 3 + select) + (func (;49;) (type 1) (result i32) + i32.const 2 + i32.const 0 + call_indirect (type 1) + i32.const 3 + select) + (func (;50;) (type 1) (result i32) + i32.const 2 + i32.const 3 + i32.const 0 + call_indirect (type 1) + select) + (func (;51;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + if (result i32) ;; label = @1 + i32.const 1 + else + i32.const 2 + end) + (func (;52;) (type 2) (result i64) + block (result i64) ;; label = @1 + i32.const 1 + call_indirect (type 2) + i32.const 2 + br_if 0 (;@1;) + end) + (func (;53;) (type 1) (result i32) + block (result i32) ;; label = @1 + i32.const 2 + i32.const 0 + call_indirect (type 1) + br_if 0 (;@1;) + end) + (func (;54;) (type 3) (result f32) + block (result f32) ;; label = @1 + i32.const 2 + call_indirect (type 3) + i32.const 2 + br_table 0 (;@1;) 0 (;@1;) + end) + (func (;55;) (type 1) (result i32) + block (result i32) ;; label = @1 + i32.const 2 + i32.const 0 + call_indirect (type 1) + br_table 0 (;@1;) 0 (;@1;) + end) + (func (;56;) (type 0) + i32.const 0 + call_indirect (type 1) + i32.const 1 + i32.store) + (func (;57;) (type 0) + i32.const 10 + i32.const 3 + call_indirect (type 4) + f64.store) + (func (;58;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + memory.grow) + (func (;59;) (type 1) (result i32) + i32.const 1 + i32.const 4 + call_indirect (type 5) + return) + (func (;60;) (type 0) + i64.const 1 + i32.const 5 + call_indirect (type 6) + drop) + (func (;61;) (type 3) (result f32) + block (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + i32.const 6 + call_indirect (type 7) + br 0 (;@1;) + end) + (func (;62;) (type 4) (result f64) + (local f64) + f64.const 0x1p+0 (;=1;) + i32.const 7 + call_indirect (type 8) + set_local 0 + get_local 0) + (func (;63;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + i32.load) + (table (;0;) 29 29 anyfunc) + (memory (;0;) 1) + (export \"type-i32\" (func 17)) + (export \"type-i64\" (func 18)) + (export \"type-f32\" (func 19)) + (export \"type-f64\" (func 20)) + (export \"type-index\" (func 21)) + (export \"type-first-i32\" (func 22)) + (export \"type-first-i64\" (func 23)) + (export \"type-first-f32\" (func 24)) + (export \"type-first-f64\" (func 25)) + (export \"type-second-i32\" (func 26)) + (export \"type-second-i64\" (func 27)) + (export \"type-second-f32\" (func 28)) + (export \"type-second-f64\" (func 29)) + (export \"dispatch\" (func 30)) + (export \"dispatch-structural-i64\" (func 31)) + (export \"dispatch-structural-i32\" (func 32)) + (export \"dispatch-structural-f32\" (func 33)) + (export \"dispatch-structural-f64\" (func 34)) + (export \"fac-i64\" (func 35)) + (export \"fib-i64\" (func 36)) + (export \"fac-i32\" (func 37)) + (export \"fac-f32\" (func 38)) + (export \"fac-f64\" (func 39)) + (export \"fib-i32\" (func 40)) + (export \"fib-f32\" (func 41)) + (export \"fib-f64\" (func 42)) + (export \"even\" (func 43)) + (export \"odd\" (func 44)) + (export \"runaway\" (func 45)) + (export \"mutual-runaway\" (func 46)) + (export \"as-select-first\" (func 48)) + (export \"as-select-mid\" (func 49)) + (export \"as-select-last\" (func 50)) + (export \"as-if-condition\" (func 51)) + (export \"as-br_if-first\" (func 52)) + (export \"as-br_if-last\" (func 53)) + (export \"as-br_table-first\" (func 54)) + (export \"as-br_table-last\" (func 55)) + (export \"as-store-first\" (func 56)) + (export \"as-store-last\" (func 57)) + (export \"as-memory.grow-value\" (func 58)) + (export \"as-return-value\" (func 59)) + (export \"as-drop-operand\" (func 60)) + (export \"as-br-value\" (func 61)) + (export \"as-set_local-value\" (func 62)) + (export \"as-load-operand\" (func 63)) + (elem (i32.const 0) 0 1 2 3 4 5 6 7 10 8 11 9 35 36 43 44 45 46 47 12 13 14 15 37 38 39 40 41 42)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, ImportObject::new()).expect("WASM can't be instantiated") +} + +// Line 379 +#[test] +fn l379_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 306 as i32); +} + +// Line 380 +#[test] +fn l380_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 356 as i64); +} + +// Line 381 +#[test] +fn l381_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3890.0 as f32); +} + +// Line 382 +#[test] +fn l382_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3940.0 as f64); +} + +// Line 384 +#[test] +fn l384_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-index") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 100 as i64); +} + +// Line 386 +#[test] +fn l386_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32 as i32); +} + +// Line 387 +#[test] +fn l387_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64 as i64); +} + +// Line 388 +#[test] +fn l388_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.32 as f32); +} + +// Line 389 +#[test] +fn l389_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.64 as f64); +} + +// Line 391 +#[test] +fn l391_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32 as i32); +} + +// Line 392 +#[test] +fn l392_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64 as i64); +} + +// Line 393 +#[test] +fn l393_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32.0 as f32); +} + +// Line 394 +#[test] +fn l394_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64.1 as f64); +} + +// Line 396 +#[test] +fn l396_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, 2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 397 +#[test] +fn l397_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, 5 as i64, &vm_context); + assert_eq!(result, 5 as i64); +} + +// Line 398 +#[test] +fn l398_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(12 as i32, 5 as i64, &vm_context); + assert_eq!(result, 120 as i64); +} + +// Line 399 +#[test] +fn l399_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(13 as i32, 5 as i64, &vm_context); + assert_eq!(result, 8 as i64); +} + +// Line 400 +#[test] +fn l400_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, 2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 401 + +// Line 402 + +// Line 403 + +// Line 404 + +// Line 405 + +// Line 407 +#[test] +fn l407_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 9 as i64); +} + +// Line 408 +#[test] +fn l408_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(12 as i32, &vm_context); + assert_eq!(result, 362880 as i64); +} + +// Line 409 +#[test] +fn l409_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(13 as i32, &vm_context); + assert_eq!(result, 55 as i64); +} + +// Line 410 +#[test] +fn l410_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, &vm_context); + assert_eq!(result, 9 as i64); +} + +// Line 411 + +// Line 412 + +// Line 414 +#[test] +fn l414_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(4 as i32, &vm_context); + assert_eq!(result, 9 as i32); +} + +// Line 415 +#[test] +fn l415_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(23 as i32, &vm_context); + assert_eq!(result, 362880 as i32); +} + +// Line 416 +#[test] +fn l416_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(26 as i32, &vm_context); + assert_eq!(result, 55 as i32); +} + +// Line 417 +#[test] +fn l417_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(19 as i32, &vm_context); + assert_eq!(result, 9 as i32); +} + +// Line 418 + +// Line 419 + +// Line 421 +#[test] +fn l421_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(6 as i32, &vm_context); + assert_eq!(result, 9.0 as f32); +} + +// Line 422 +#[test] +fn l422_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(24 as i32, &vm_context); + assert_eq!(result, 362880.0 as f32); +} + +// Line 423 +#[test] +fn l423_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(27 as i32, &vm_context); + assert_eq!(result, 55.0 as f32); +} + +// Line 424 +#[test] +fn l424_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(21 as i32, &vm_context); + assert_eq!(result, 9.0 as f32); +} + +// Line 425 + +// Line 426 + +// Line 428 +#[test] +fn l428_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(7 as i32, &vm_context); + assert_eq!(result, 9.0 as f64); +} + +// Line 429 +#[test] +fn l429_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(25 as i32, &vm_context); + assert_eq!(result, 362880.0 as f64); +} + +// Line 430 +#[test] +fn l430_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(28 as i32, &vm_context); + assert_eq!(result, 55.0 as f64); +} + +// Line 431 +#[test] +fn l431_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(22 as i32, &vm_context); + assert_eq!(result, 9.0 as f64); +} + +// Line 432 + +// Line 433 + +// Line 435 +#[test] +fn l435_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 436 +#[test] +fn l436_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 437 +#[test] +fn l437_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i64, &vm_context); + assert_eq!(result, 120 as i64); +} + +// Line 438 +#[test] +fn l438_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(25 as i64, &vm_context); + assert_eq!(result, 7034535277573963776 as i64); +} + +// Line 440 +#[test] +fn l440_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 441 +#[test] +fn l441_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 442 +#[test] +fn l442_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 120 as i32); +} + +// Line 443 +#[test] +fn l443_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10 as i32, &vm_context); + assert_eq!(result, 3628800 as i32); +} + +// Line 445 +#[test] +fn l445_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 446 +#[test] +fn l446_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 447 +#[test] +fn l447_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f32, &vm_context); + assert_eq!(result, 120.0 as f32); +} + +// Line 448 +#[test] +fn l448_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10.0 as f32, &vm_context); + assert_eq!(result, 3628800.0 as f32); +} + +// Line 450 +#[test] +fn l450_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 451 +#[test] +fn l451_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 452 +#[test] +fn l452_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f64, &vm_context); + assert_eq!(result, 120.0 as f64); +} + +// Line 453 +#[test] +fn l453_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10.0 as f64, &vm_context); + assert_eq!(result, 3628800.0 as f64); +} + +// Line 455 +#[test] +fn l455_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 456 +#[test] +fn l456_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 457 +#[test] +fn l457_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 458 +#[test] +fn l458_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i64, &vm_context); + assert_eq!(result, 8 as i64); +} + +// Line 459 +#[test] +fn l459_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i64, &vm_context); + assert_eq!(result, 10946 as i64); +} + +// Line 461 +#[test] +fn l461_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 462 +#[test] +fn l462_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 463 +#[test] +fn l463_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2 as i32, &vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 464 +#[test] +fn l464_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 8 as i32); +} + +// Line 465 +#[test] +fn l465_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, &vm_context); + assert_eq!(result, 10946 as i32); +} + +// Line 467 +#[test] +fn l467_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 468 +#[test] +fn l468_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 469 +#[test] +fn l469_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2.0 as f32, &vm_context); + assert_eq!(result, 2.0 as f32); +} + +// Line 470 +#[test] +fn l470_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f32, &vm_context); + assert_eq!(result, 8.0 as f32); +} + +// Line 471 +#[test] +fn l471_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20.0 as f32, &vm_context); + assert_eq!(result, 10946.0 as f32); +} + +// Line 473 +#[test] +fn l473_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 474 +#[test] +fn l474_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 475 +#[test] +fn l475_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2.0 as f64, &vm_context); + assert_eq!(result, 2.0 as f64); +} + +// Line 476 +#[test] +fn l476_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f64, &vm_context); + assert_eq!(result, 8.0 as f64); +} + +// Line 477 +#[test] +fn l477_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20.0 as f64, &vm_context); + assert_eq!(result, 10946.0 as f64); +} + +// Line 479 +#[test] +fn l479_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 480 +#[test] +fn l480_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 481 +#[test] +fn l481_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(100 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 482 +#[test] +fn l482_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(77 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 483 +#[test] +fn l483_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 484 +#[test] +fn l484_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 485 +#[test] +fn l485_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(200 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 486 +#[test] +fn l486_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(77 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 488 + +// Line 489 + +// Line 491 +#[test] +fn l491_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 306 as i32); +} + +// Line 492 +#[test] +fn l492_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-mid") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 493 +#[test] +fn l493_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 495 +#[test] +fn l495_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-if-condition") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 497 +#[test] +fn l497_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_if-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 356 as i64); +} + +// Line 498 +#[test] +fn l498_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_if-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 500 +#[test] +fn l500_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_table-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3890.0 as f32); +} + +// Line 501 +#[test] +fn l501_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_table-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 507 +#[test] +fn l507_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-return-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 508 +#[test] +fn l508_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-drop-operand") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, ()); +} + +// Line 509 +#[test] +fn l509_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 510 +#[test] +fn l510_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-set_local-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 516 + +#[test] +fn l516_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 528 + +#[test] +fn l528_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 540 + +#[test] +fn l540_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 552 + +#[test] +fn l552_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 564 + +#[test] +fn l564_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 576 + +#[test] +fn l576_assert_malformed() { + let wasm_binary = [40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 586 + +#[test] +fn l586_assert_malformed() { + let wasm_binary = [40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 36, 120, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 593 + +#[test] +fn l593_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 603 + +#[test] +fn l603_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 613 + +#[test] +fn l613_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 623 + +#[test] +fn l623_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 638 + +#[test] +fn l638_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 646 + +#[test] +fn l646_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 0, 17, 0, 0, 69, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 654 + +#[test] +fn l654_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 0, 1, 126, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 0, 17, 0, 0, 69, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 663 + +#[test] +fn l663_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 671 + +#[test] +fn l671_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 124, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 679 + +#[test] +fn l679_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 11, 1, 9, 0, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 687 + +#[test] +fn l687_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 68, 0, 0, 0, 0, 0, 0, 0, 64, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 698 + +#[test] +fn l698_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 1, 1, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 706 + +#[test] +fn l706_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 11, 1, 9, 0, 65, 0, 66, 1, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 715 + +#[test] +fn l715_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 12, 1, 10, 0, 1, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 725 + +#[test] +fn l725_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 12, 1, 10, 0, 65, 1, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 735 + +#[test] +fn l735_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 124, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 68, 0, 0, 0, 0, 0, 0, 240, 63, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 745 + +#[test] +fn l745_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 124, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 65, 1, 68, 0, 0, 0, 0, 0, 0, 240, 63, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 759 + +#[test] +fn l759_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 1, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 766 + +#[test] +fn l766_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 13, 1, 11, 0, 65, 0, 17, 148, 152, 219, 226, 3, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 777 + +#[test] +fn l777_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 5, 1, 112, 1, 2, 2, 9, 8, 1, 0, 65, 0, 11, 2, 0, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} diff --git a/src/spectests/mod.rs b/src/spectests/mod.rs index fb5eefd3234..6cab11e17d7 100644 --- a/src/spectests/mod.rs +++ b/src/spectests/mod.rs @@ -3,6 +3,7 @@ mod br_if; mod call; +mod call_indirect; mod i32_; mod memory; mod set_local; diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 864c270d5a2..f775fb05db6 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -70,13 +70,12 @@ fn get_function_addr( // #[derive(Debug)] -#[repr(C)] +#[repr(C, packed)] pub struct VmCtx<'phantom> { pub user_data: UserData, - pub globals: UncheckedSlice, - pub memories: UncheckedSlice>, - pub tables: UncheckedSlice>, - pub test: String, + globals: UncheckedSlice, + memories: UncheckedSlice>, + tables: UncheckedSlice>, // globals: Vec, // memories: Vec>, // pub tables: Vec>, @@ -84,7 +83,7 @@ pub struct VmCtx<'phantom> { } // #[derive(Debug)] -#[repr(C)] +#[repr(C, packed)] pub struct UserData { // pub process: Dispatch, pub instance: Instance, @@ -507,14 +506,12 @@ impl Instance { } pub fn generate_context(&mut self) -> VmCtx { - let mut memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); - + let memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); - - println!("GENERATING CONTEXT {:?}", self.tables); - let globals: UncheckedSlice = self.globals[..].into(); + // println!("GENERATING CONTEXT {:?}", self.tables); + // assert!(memories.len() >= 1, "modules must have at least one memory"); // the first memory has a space of `mem::size_of::()` rounded // up to the 4KiB before it. We write the VmCtxData into that. @@ -527,7 +524,6 @@ impl Instance { // process, instance: instance, }, - test: "TEST".to_string(), phantom: PhantomData, }; data diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index f34e05e6abf..49352229e90 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -411,11 +411,11 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { let ptr_size = self.ptr_size(); // Given a vmctx, we want to retrieve vmctx.tables - // Create a table whose base address is stored at `vmctx+120`. - // 120 is the offset of the vmctx.tables pointer respect to vmctx pointer + // Create a table whose base address is stored at `vmctx+112`. + // 112 is the offset of the vmctx.tables pointer respect to vmctx pointer let base = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, - offset: Offset32::new(120), + offset: Offset32::new(112), global_type: self.pointer_type(), }); @@ -438,10 +438,10 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { base_gv: base_gv, min_size: Imm64::new(0), bound_gv, - element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2), + element_size: Imm64::new(i64::from(self.pointer_bytes())), index_type: self.pointer_type(), }); - println!("FUNC {:?}", func); + // println!("FUNC {:?}", func); table // let ptr_size = self.ptr_size(); @@ -562,7 +562,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { .CallIndirect(ir::Opcode::CallIndirect, INVALID, sig_ref, args) .0; - println!("FUNC {:?}", pos.func); + // println!("FUNC {:?}", pos.func); Ok(inst) } From ba74488f7d928f25e5124adb2dfd3c86a4a918e2 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:40:31 +0200 Subject: [PATCH 11/16] Added call indirect example --- examples/call_indirect.wast | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 examples/call_indirect.wast diff --git a/examples/call_indirect.wast b/examples/call_indirect.wast new file mode 100644 index 00000000000..af69ba778b7 --- /dev/null +++ b/examples/call_indirect.wast @@ -0,0 +1,30 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (table 1 1 anyfunc) + (elem (i32.const 0) $multiply) + (memory $0 1) + (export "memory" (memory $0)) + (export "dispatch" (func $dispatch)) + (export "multiply" (func $multiply)) + (export "main" (func $main)) + (func $dispatch (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call_indirect (type $FUNCSIG$iii) + (get_local $1) + (get_local $2) + (get_local $0) + ) + ) + (func $multiply (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (i32.mul + (get_local $1) + (get_local $0) + ) + ) + (func $main (; 2 ;) (result i32) + (call $dispatch + (i32.const 0) + (i32.const 20) + (i32.const 30) + ) + ) +) From 837e67999ff1f095e97d00b7fe88c147b537e0ba Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:41:55 +0200 Subject: [PATCH 12/16] Show result --- src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7c9807b38b6..617b7b50792 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,9 +84,10 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { Some(&webassembly::Export::Function(index)) => index, _ => panic!("Main function not found"), }); - let main: fn(&webassembly::VmCtx) = get_instance_function!(instance, func_index); + let main: fn(&webassembly::VmCtx) -> i32 = get_instance_function!(instance, func_index); let context = instance.generate_context(); - main(&context); + let result = main(&context); + println!("RESULT {}", result); Ok(()) } From 3f5091780d1c08ac2dbbd7e08320a8ec2ce5df91 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:43:43 +0200 Subject: [PATCH 13/16] Improved formatting --- src/integrations/mod.rs | 3 +-- src/main.rs | 10 ++++++---- src/webassembly/instance.rs | 8 ++++---- src/webassembly/memory.rs | 9 +++++---- src/webassembly/module.rs | 13 +++++-------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index b4edc78431f..fc17cb14e97 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -38,8 +38,7 @@ pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { mod tests { use super::generate_libc_env; use crate::webassembly::{ - instantiate, ErrorKind, Export, ImportObject, Instance, Module, ResultObject, - VmCtx + instantiate, ErrorKind, Export, ImportObject, Instance, Module, ResultObject, VmCtx, }; use libc::putchar; diff --git a/src/main.rs b/src/main.rs index 617b7b50792..492d31d48d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,8 @@ extern crate wabt; extern crate target_lexicon; extern crate spin; -use std::time::{Duration, Instant}; use std::alloc::System; +use std::time::{Duration, Instant}; // #[global_allocator] // static A: System = System; @@ -75,9 +75,11 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { } let import_object = integrations::generate_libc_env(); - let webassembly::ResultObject { module, mut instance } = - webassembly::instantiate(wasm_binary, import_object) - .map_err(|err| String::from(err.description()))?; + let webassembly::ResultObject { + module, + mut instance, + } = webassembly::instantiate(wasm_binary, import_object) + .map_err(|err| String::from(err.description()))?; let func_index = instance .start_func .unwrap_or_else(|| match module.info.exports.get("main") { diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index f775fb05db6..24b9936e247 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -68,7 +68,6 @@ fn get_function_addr( // (base as usize + offset) as _ // } - // #[derive(Debug)] #[repr(C, packed)] pub struct VmCtx<'phantom> { @@ -506,8 +505,10 @@ impl Instance { } pub fn generate_context(&mut self) -> VmCtx { - let memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); - let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); + let memories: Vec> = + self.memories.iter().map(|mem| mem[..].into()).collect(); + let tables: Vec> = + self.tables.iter().map(|table| table[..].into()).collect(); let globals: UncheckedSlice = self.globals[..].into(); // println!("GENERATING CONTEXT {:?}", self.tables); @@ -570,7 +571,6 @@ impl Clone for Instance { } extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 { - return 0; // unimplemented!(); // let instance = &vmctx.user_data.instance; diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs index dcc5b816ec6..307ad6d59b3 100644 --- a/src/webassembly/memory.rs +++ b/src/webassembly/memory.rs @@ -36,10 +36,11 @@ impl LinearMemory { initial, maximum ); - let len: u64 = PAGE_SIZE as u64 * match maximum { - Some(val) => val as u64, - None => initial as u64, - }; + let len: u64 = PAGE_SIZE as u64 + * match maximum { + Some(val) => val as u64, + None => initial as u64, + }; let len = if len == 0 { PAGE_SIZE as u64 } else { len }; let mmap = MmapMut::map_anon(len as usize).unwrap(); diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index 49352229e90..5848e9bacb8 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -409,7 +409,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { fn make_table(&mut self, func: &mut ir::Function, table_index: TableIndex) -> ir::Table { let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_size = self.ptr_size(); - + // Given a vmctx, we want to retrieve vmctx.tables // Create a table whose base address is stored at `vmctx+112`. // 112 is the offset of the vmctx.tables pointer respect to vmctx pointer @@ -433,7 +433,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { offset: Offset32::new(table_data_offset), global_type: I64, }); - + let table = func.create_table(ir::TableData { base_gv: base_gv, min_size: Imm64::new(0), @@ -539,12 +539,9 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { ext // pos.ins().imul_imm(ext, 4) }; - let entry_addr = pos.ins().table_addr( - self.pointer_type(), - table, - callee_offset, - 0, - ); + let entry_addr = pos + .ins() + .table_addr(self.pointer_type(), table, callee_offset, 0); let mut mflags = ir::MemFlags::new(); mflags.set_notrap(); mflags.set_aligned(); From 138d5a6bf4b66ddf332d44d55761a4d10eda2c4a Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:49:26 +0200 Subject: [PATCH 14/16] Restored integration tests back as it was before --- src/integrations/mod.rs | 35 ----------------------------- src/integrations/tests/putchar.wast | 27 ++-------------------- 2 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index fc17cb14e97..f0d2436f1f2 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -1,33 +1,6 @@ use crate::webassembly::{ImportObject, VmCtx}; use libc::putchar; -// extern fn putchar(a: *const u8, context: *const u8) { -// println!("PUT CHAAAR original pointer {:?}", context); -// let vmctx: &VmCtx = unsafe { &*(context as *const VmCtx) }; -// println!("PUT CHAAAR {}", vmctx.test); -// println!("PUT CHAAAR pointer {:p}", vmctx); -// let x = vmctx as *const _; -// let x_tables = vmctx.tables.as_ptr(); -// let tables_ptr_1 = (&vmctx.tables) as *const _; -// let tables_ptr_2 = unsafe { (&vmctx.tables.get_unchecked(0)) as *const _ }; -// let tables_ptr_3 = &vmctx.tables as *const _ ; -// let tables_ptr_4 = &vmctx.tables as *const _ ; -// // let tables: &Vec> = unsafe { &*(tables_ptr_4 as *const Vec>) }; -// let x_tables_serial: &Vec<*const usize> = unsafe { &*(tables_ptr_1 as *const Vec<*const usize>) }; -// // let tables: &Vec<> = vmctx.tables as &Vec>; -// println!("PUT CHAAAR pointer {:?}", x); -// println!("PUT CHAAAR pointer 1 {:p}", &vmctx.tables); -// println!("PUT CHAAAR pointer 2 {:p}", tables_ptr_1); -// println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_2); -// println!("PUT CHAAAR pointer 3 (0) {:p}", tables_ptr_3); -// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", tables_ptr_4, tables); -// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables, vmctx.tables); -// // println!("PUT CHAAAR pointer 4 (0) {:p} {:?}", &vmctx.tables[0], vmctx.tables[0]); -// println!("PUT CHAAAR pointer {:?} {:?}", x_tables, x_tables_serial); -// let x_tables = vmctx.tables.as_ptr(); -// println!("PUT CHAAAR pointer {:?}", x_tables); -// } - pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { let mut import_object = ImportObject::new(); import_object.set("env", "putchar", putchar as *const u8); @@ -54,15 +27,7 @@ mod tests { _ => panic!("Function not found"), }; let main: fn(&VmCtx) = get_instance_function!(instance, func_index); - let mainn_func_index = match module.info.exports.get("mainn") { - Some(&Export::Function(index)) => index, - _ => panic!("Function not found"), - }; - let mainn: fn(&VmCtx) = get_instance_function!(instance, mainn_func_index); let context = instance.generate_context(); main(&context); - println!("---------MAINNN NOW---------"); - // let context = instance.generate_context(); - mainn(&context); } } diff --git a/src/integrations/tests/putchar.wast b/src/integrations/tests/putchar.wast index 8ad1a58ba2b..d61d6ada095 100644 --- a/src/integrations/tests/putchar.wast +++ b/src/integrations/tests/putchar.wast @@ -1,34 +1,11 @@ (module - (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (import "env" "putchar" (func $putchar (param i32) (result i32))) - (elem (i32.const 0) $multiply) - (table 1 1 anyfunc) + (table 0 anyfunc) (memory $0 1) (export "memory" (memory $0)) (export "main" (func $main)) - (export "mainn" (func $mainn)) - (func $dispatch (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (call_indirect (type $FUNCSIG$iii) - (get_local $1) - (get_local $2) - (get_local $0) - ) - ) - (func $multiply (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) - (i32.mul - (get_local $1) - (get_local $0) - ) - ) - (func $mainn (; 2 ;) (result i32) - (call $dispatch - (i32.const 0) - (i32.const 20) - (i32.const 30) - ) - ) - (func $main (; 3 ;) (result i32) + (func $main (; 1 ;) (result i32) (drop (call $putchar (i32.const 97) From 6cb78439e34b9791b43ad72e3c02fa78b8db5af0 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:49:38 +0200 Subject: [PATCH 15/16] Improved call indirect example --- examples/call_indirect.wast | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/call_indirect.wast b/examples/call_indirect.wast index af69ba778b7..613b5bfb4fe 100644 --- a/examples/call_indirect.wast +++ b/examples/call_indirect.wast @@ -1,5 +1,5 @@ (module - (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $multiply_signature (func (param i32 i32) (result i32))) (table 1 1 anyfunc) (elem (i32.const 0) $multiply) (memory $0 1) @@ -8,13 +8,13 @@ (export "multiply" (func $multiply)) (export "main" (func $main)) (func $dispatch (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (call_indirect (type $FUNCSIG$iii) + (call_indirect (type $multiply_signature) (get_local $1) (get_local $2) (get_local $0) ) ) - (func $multiply (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $multiply (; 1 ;) (type $multiply_signature) (param $0 i32) (param $1 i32) (result i32) (i32.mul (get_local $1) (get_local $0) From 10eff5f3c3c8cdab7ca037c2d6ff396b4e739c13 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 23 Oct 2018 11:55:54 +0200 Subject: [PATCH 16/16] Fixed slice public pointers --- src/common/slice.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/slice.rs b/src/common/slice.rs index 81ea02d5243..f104edf49a5 100644 --- a/src/common/slice.rs +++ b/src/common/slice.rs @@ -4,18 +4,18 @@ use std::ptr::NonNull; #[derive(Copy, Clone)] #[repr(transparent)] pub struct UncheckedSlice { - pub ptr: NonNull, + ptr: NonNull, } impl UncheckedSlice { #[inline] - pub unsafe fn get_unchecked(&self, index: usize) -> &T { + unsafe fn get_unchecked(&self, index: usize) -> &T { let ptr = self.ptr.as_ptr(); &*ptr.add(index) } #[inline] - pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { let ptr = self.ptr.as_ptr(); &mut *(ptr.add(index) as *mut _) }