From a590d7cd078c73fa206a9ac773570601caac3922 Mon Sep 17 00:00:00 2001 From: Heyang Zhou Date: Sat, 4 May 2019 09:56:52 -0700 Subject: [PATCH] Tables --- lib/kwasm-loader/src/lib.rs | 40 ++++++++++++++++++++++++++++---- lib/kwasm-loader/src/service.rs | 21 +++++++++++++---- lib/runtime-core/src/instance.rs | 2 +- lib/runtime-core/src/loader.rs | 6 ++--- lib/runtime-core/src/vm.rs | 9 ++++++- 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/lib/kwasm-loader/src/lib.rs b/lib/kwasm-loader/src/lib.rs index 3213a18e7..2afea2ce7 100644 --- a/lib/kwasm-loader/src/lib.rs +++ b/lib/kwasm-loader/src/lib.rs @@ -3,12 +3,12 @@ pub mod service; use wasmer_runtime_core::{ loader::{self, Loader, Instance}, backend::RunnableModule, - vm::{InternalCtx, LocalGlobal}, + vm::{Ctx, LocalGlobal, SigId, Anyfunc}, module::ModuleInfo, - types::{Value, LocalMemoryIndex, ImportedMemoryIndex}, + types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex}, structures::TypedIndex, }; -use service::{ServiceContext, RunProfile}; +use service::{ServiceContext, RunProfile, TableEntryRequest}; pub struct KernelLoader; @@ -16,7 +16,8 @@ impl Loader for KernelLoader { type Instance = KernelInstance; type Error = String; - fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result { + fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, full_ctx: &Ctx) -> Result { + let ctx = &full_ctx.internal; let code = rm.get_code().unwrap(); let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) { Some(unsafe { @@ -27,6 +28,29 @@ impl Loader for KernelLoader { } else { None }; + let table: Option> = if let Some(_) = module.tables.get(LocalTableIndex::new(0)) { + Some(unsafe { + let table = &**ctx.tables; + let elements: &[Anyfunc] = ::std::slice::from_raw_parts(table.base as *const Anyfunc, table.count); + let base_addr = code.as_ptr() as usize; + let end_addr = base_addr + code.len(); + elements.iter().map(|x| { + let func_addr = x.func as usize; + TableEntryRequest { + offset: if x.func.is_null() || func_addr < base_addr || func_addr >= end_addr { + ::std::usize::MAX + } else { + x.func as usize - base_addr + }, + sig_id: x.sig_id.0, + } + }).collect() + }) + } else if let Some(_) = module.imported_tables.get(ImportedTableIndex::new(0)) { + return Err("imported table is not supported".into()); + } else { + None + }; if module.imported_globals.len() > 0 { return Err("imported globals are not supported".into()); } @@ -43,9 +67,13 @@ impl Loader for KernelLoader { context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?, code: code.to_vec(), memory: memory, + table: table, globals: globals, offsets: rm.get_offsets().unwrap(), import_names: import_names, + dynamic_sigindices: unsafe { + ::std::slice::from_raw_parts(ctx.dynamic_sigindices, full_ctx.dynamic_sigindice_count()) + }.iter().map(|x| x.0).collect(), }) } } @@ -54,9 +82,11 @@ pub struct KernelInstance { context: ServiceContext, code: Vec, memory: Option>, + table: Option>, globals: Vec, offsets: Vec, import_names: Vec, + dynamic_sigindices: Vec, } impl Instance for KernelInstance { @@ -72,6 +102,8 @@ impl Instance for KernelInstance { params: &args, entry_offset: self.offsets[id] as u32, imports: &self.import_names, + dynamic_sigindices: &self.dynamic_sigindices, + table: self.table.as_ref().map(|x| x.as_slice()), }).map_err(|x| format!("{:?}", x))?; Ok(ret as u64) } diff --git a/lib/kwasm-loader/src/service.rs b/lib/kwasm-loader/src/service.rs index 194c639e3..8cac49c8e 100644 --- a/lib/kwasm-loader/src/service.rs +++ b/lib/kwasm-loader/src/service.rs @@ -48,7 +48,7 @@ struct RunCodeRequest { memory: *const u8, memory_len: u32, memory_max: u32, - table: *const u32, + table: *const TableEntryRequest, table_count: u32, globals: *const u64, global_count: u32, @@ -56,6 +56,9 @@ struct RunCodeRequest { imported_funcs: *const ImportRequest, imported_func_count: u32, + dynamic_sigindices: *const u32, + dynamic_sigindice_count: u32, + entry_offset: u32, params: *const u64, param_count: u32, @@ -66,6 +69,12 @@ struct ImportRequest { name: [u8; 64], } +#[repr(C)] +pub struct TableEntryRequest { + pub offset: usize, + pub sig_id: u32, +} + pub struct RunProfile<'a> { pub code: &'a [u8], pub memory: Option<&'a [u8]>, @@ -73,7 +82,9 @@ pub struct RunProfile<'a> { pub globals: &'a [u64], pub params: &'a [u64], pub entry_offset: u32, - pub imports: &'a [String] + pub imports: &'a [String], + pub dynamic_sigindices: &'a [u32], + pub table: Option<&'a [TableEntryRequest]>, } pub struct ServiceContext { @@ -104,12 +115,14 @@ impl ServiceContext { memory: run.memory.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), memory_len: run.memory.map(|x| x.len() as u32).unwrap_or(0), memory_max: run.memory_max as u32, - table: ::std::ptr::null(), - table_count: 0, + table: run.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), + table_count: run.table.map(|x| x.len() as u32).unwrap_or(0), globals: run.globals.as_ptr(), global_count: run.globals.len() as u32, imported_funcs: imports.as_ptr(), imported_func_count: imports.len() as u32, + dynamic_sigindices: run.dynamic_sigindices.as_ptr(), + dynamic_sigindice_count: run.dynamic_sigindices.len() as u32, params: run.params.as_ptr(), param_count: run.params.len() as u32, entry_offset: run.entry_offset, diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index d82699973..f6d6a7a0c 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -130,7 +130,7 @@ impl Instance { } pub fn load(&self, loader: T) -> ::std::result::Result { - loader.load(&*self.module.runnable_module, &self.module.info, unsafe { &(*self.inner.vmctx).internal }) + loader.load(&*self.module.runnable_module, &self.module.info, unsafe { &*self.inner.vmctx }) } /// Through generic magic and the awe-inspiring power of traits, we bring you... diff --git a/lib/runtime-core/src/loader.rs b/lib/runtime-core/src/loader.rs index 57885891a..b109ddb14 100644 --- a/lib/runtime-core/src/loader.rs +++ b/lib/runtime-core/src/loader.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::{ backend::RunnableModule, - vm::InternalCtx, + vm::Ctx, module::ModuleInfo, types::Value, }; @@ -17,7 +17,7 @@ pub trait Loader { type Instance: Instance; type Error: Debug; - fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result; + fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &Ctx) -> Result; } pub trait Instance { @@ -31,7 +31,7 @@ impl Loader for LocalLoader { type Instance = LocalInstance; type Error = String; - fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result { + fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &Ctx) -> Result { let code = rm.get_code().unwrap(); let mut code_mem = CodeMemory::new(code.len()); code_mem[..code.len()].copy_from_slice(code); diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 7d9039b7d..2ef51c869 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -16,7 +16,7 @@ use hashbrown::HashMap; #[repr(C)] pub struct Ctx { // `internal` must be the first field of `Ctx`. - pub(crate) internal: InternalCtx, + pub internal: InternalCtx, pub(crate) local_functions: *const *const Func, @@ -163,6 +163,13 @@ impl Ctx { pub unsafe fn borrow_symbol_map(&self) -> &Option> { &(*self.module).info.em_symbol_map } + + /// Returns the number of dynamic sigindices. + pub fn dynamic_sigindice_count(&self) -> usize { + unsafe { + (*self.local_backing).dynamic_sigindices.len() + } + } } #[doc(hidden)]