diff --git a/src/spec/tests.rs b/src/spec/tests.rs index c75594b21..26805e51a 100644 --- a/src/spec/tests.rs +++ b/src/spec/tests.rs @@ -121,7 +121,7 @@ impl<'module> ScriptHandler for StoreCtrl<'module> { } fn module(&mut self, bytes: Vec, name: Option) { let module_wrapped = instantiate(bytes, None); - let mut result = module_wrapped.expect("Module is invalid"); + let mut result = module_wrapped.expect("Module is invalid").module; // let module: &'module Module = result.module; self.last_module = Some(result); // self.add_module(name, &mut result); diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 0ce9d16b5..8444be1cb 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -76,7 +76,7 @@ pub struct Instance { impl Instance { /// Create a new `Instance`. - pub fn new(module: &Module, data_initializers: &[DataInitializer], code_base: *const (), functions: &[usize]) -> Instance { + pub fn new(module: &Module, code_base: *const (), functions: &[usize]) -> Instance { let mut tables: Vec> = Vec::new(); let mut memories: Vec = Vec::new(); let mut globals: Vec = Vec::new(); @@ -119,7 +119,7 @@ impl Instance { let v = LinearMemory::new(memory.pages_count as u32, memory.maximum.map(|m| m as u32)); memories.push(v); } - for init in data_initializers { + for init in &module.info.data_initializers { debug_assert!(init.base.is_none(), "globalvar base not supported yet"); let mem_mut = memories[init.memory_index].as_mut(); let to_init = &mut mem_mut[init.offset..init.offset + init.data.len()]; diff --git a/src/webassembly/mod.rs b/src/webassembly/mod.rs index f8cc89373..47bd7fe57 100644 --- a/src/webassembly/mod.rs +++ b/src/webassembly/mod.rs @@ -1,10 +1,4 @@ -// pub mod module; -// pub mod compilation; -// pub mod memory; -// pub mod environ; -// pub mod instance; pub mod errors; -// pub mod execute; pub mod utils; pub mod module; pub mod memory; @@ -13,40 +7,27 @@ pub mod instance; use std::str::FromStr; use std::time::{Duration, Instant}; use std::panic; +use std::ptr; use cranelift_native; -use cranelift_codegen::isa::TargetIsa; -// use cranelift_codegen::settings; -use cranelift_codegen::settings::Configurable; - use target_lexicon::{self, Triple}; - +use wasmparser; use cranelift_codegen::isa; -use cranelift_codegen::print_errors::pretty_verifier_error; -use cranelift_codegen::settings::{self, Flags}; -use cranelift_codegen::verifier; -use cranelift_wasm::{translate_module, ReturnMode}; +// use cranelift_codegen::print_errors::pretty_verifier_error; +// use cranelift_codegen::verifier; pub use self::module::Module; pub use self::instance::Instance; - -// pub use self::compilation::{compile_module, Compilation}; -// pub use self::environ::{ModuleEnvironment}; -// pub use self::module::Module; -// pub use self::instance::Instance; pub use self::errors::{Error, ErrorKind}; -// pub use self::execute::{compile_and_link_module,execute}; -use wasmparser; +pub use self::memory::LinearMemory; -// pub struct ResultObject { -// /// A webassembly::Module object representing the compiled WebAssembly module. -// /// This Module can be instantiated again -// pub module: Module, -// /// A webassembly::Instance object that contains all the Exported WebAssembly -// /// functions. -// pub instance: Instance, - -// pub compilation: Compilation, -// } +pub struct ResultObject { + /// A webassembly::Module object representing the compiled WebAssembly module. + /// This Module can be instantiated again + pub module: Module, + /// A webassembly::Instance object that contains all the Exported WebAssembly + /// functions. + pub instance: Instance, +} pub struct ImportObject { } @@ -68,62 +49,13 @@ pub struct ImportObject { /// If the operation fails, the Result rejects with a /// webassembly::CompileError, webassembly::LinkError, or /// webassembly::RuntimeError, depending on the cause of the failure. -pub fn instantiate(buffer_source: Vec, import_object: Option) -> Result { - // TODO: This should be automatically validated when creating the Module - if !validate(&buffer_source) { - return Err(ErrorKind::CompileError("Module not valid".to_string())); - } - - let module = - Module::from_bytes(buffer_source, triple!("riscv64"), None)?; - - // let isa = isa::lookup(module.info.triple) - // .unwrap() - // .finish(module.info.flags); - - // for func in module.info.function_bodies.values() { - // verifier::verify_function(func, &*isa) - // .map_err(|errors| panic!(pretty_verifier_error(func, Some(&*isa), None, errors))) - // .unwrap(); - // }; - - Ok(module) - // Ok(environ) - // let now = Instant::now(); - // let isa = construct_isa(); - // println!("instantiate::init {:?}", now.elapsed()); - // // if !validate(&buffer_source) { - // // return Err(ErrorKind::CompileError("Module not valid".to_string())); - // // } - // println!("instantiate::validation {:?}", now.elapsed()); - // let mut module = Module::new(); - // let environ = ModuleEnvironment::new(&*isa, &mut module); - // let translation = environ.translate(&buffer_source).map_err(|e| ErrorKind::CompileError(e.to_string()))?; - // println!("instantiate::compile and link {:?}", now.elapsed()); - // let compilation = compile_and_link_module(&*isa, &translation)?; - // // let (compilation, relocations) = compile_module(&translation, &*isa)?; - // println!("instantiate::instantiate {:?}", now.elapsed()); - - // let mut instance = Instance::new( - // translation.module, - // &compilation, - // &translation.lazy.data_initializers, - // ); - // println!("instantiate::execute {:?}", now.elapsed()); - - // let x = execute(&module, &compilation, &mut instance)?; - - // // let instance = Instance { - // // tables: Vec::new(), - // // memories: Vec::new(), - // // globals: Vec::new(), - // // }; - - // Ok(ResultObject { - // module, - // compilation, - // instance: instance, - // }) +pub fn instantiate(buffer_source: Vec, import_object: Option) -> Result { + let module = compile(buffer_source)?; + let instance = Instance::new(&module, ptr::null(), &vec![]); + Ok(ResultObject{ + module, + instance + }) } /// The webassembly::compile() function compiles a webassembly::Module @@ -138,16 +70,25 @@ pub fn instantiate(buffer_source: Vec, import_object: Option) /// Errors: /// If the operation fails, the Result rejects with a /// webassembly::CompileError. -pub fn compile(buffer_source: Vec) -> Result { - unimplemented!(); - // let isa = construct_isa(); +pub fn compile(buffer_source: Vec) -> Result { + // TODO: This should be automatically validated when creating the Module + if !validate(&buffer_source) { + return Err(ErrorKind::CompileError("Module not valid".to_string())); + } + + let module = Module::from_bytes(buffer_source, triple!("riscv64"), None)?; - // let mut module = Module::new(); - // let environ = ModuleEnvironment::new(&*isa, &mut module); - // let translation = environ.translate(&buffer_source).map_err(|e| ErrorKind::CompileError(e.to_string()))?; - // // compile_module(&translation, &*isa)?; - // compile_and_link_module(&*isa, &translation)?; - // Ok(module) + // let isa = isa::lookup(module.info.triple) + // .unwrap() + // .finish(module.info.flags); + + // for func in module.info.function_bodies.values() { + // verifier::verify_function(func, &*isa) + // .map_err(|errors| panic!(pretty_verifier_error(func, Some(&*isa), None, errors))) + // .unwrap(); + // }; + + Ok(module) } /// The webassembly::validate() function validates a given typed