Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote code loading framework. #416

Merged
merged 46 commits into from May 16, 2019
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
14bfd75
Code loader framework.
losfair May 2, 2019
af58ea5
Kernel mode code loading.
losfair May 4, 2019
7a4b217
Remove runtime dependence for BrTable
losfair May 4, 2019
af0b147
Add emit_u64 to Emitter API
losfair May 4, 2019
c4e4efc
kwasm imports
losfair May 4, 2019
a590d7c
Tables
losfair May 4, 2019
46e4cb0
Get memory intrinsics at runtime.
losfair May 4, 2019
3c64bd0
Kernel mode example.
losfair May 4, 2019
cc01e40
Split load/run
losfair May 5, 2019
7bc09ee
kwasmd.
losfair May 5, 2019
61510f8
Enforce runtime memory and stack bound check when using kernel loader.
losfair May 6, 2019
b343fd4
Pass in param count for import functions in kernel loader.
losfair May 6, 2019
0895dc6
Check param count.
losfair May 6, 2019
0bbd6e6
Fix function offset.
losfair May 7, 2019
accb80b
Pipe example
losfair May 7, 2019
620a6dd
Disable memory bound checking for kernel loader.
losfair May 8, 2019
af1ac9a
Improve performance of memory access.
losfair May 13, 2019
3bcdfb4
Asynchronous networking extension.
losfair May 13, 2019
884a7e1
kwasm-net fixes and optimizations.
losfair May 13, 2019
4f77f4d
HTTP server example.
losfair May 14, 2019
2963b0a
Make `schedule()` faster.
losfair May 14, 2019
9df3e4a
Fix http server example.
losfair May 14, 2019
db9705f
Merge remote-tracking branch 'origin/master' into feature/remote-code…
losfair May 14, 2019
2a160c7
Fix wasmer-runtime-core dependency version.
losfair May 14, 2019
722ea39
Cleanup loader code.
losfair May 14, 2019
32f9aee
Cargo fmt
losfair May 14, 2019
1e7a928
Add comments.
losfair May 14, 2019
d60e237
Only compile kwasm-net for wasm32-wasi.
losfair May 14, 2019
98dd2c0
Fix wasm example crates.
losfair May 14, 2019
ee09209
Fix clippy error.
losfair May 14, 2019
d641909
Fix clippy error
losfair May 14, 2019
5ec931e
Fix kwasmd compilation
losfair May 14, 2019
fac4c45
Fix LLVM backend.
losfair May 14, 2019
d75a292
Fix compilation issue on Windows.
losfair May 14, 2019
d72abf3
Rename `kwasm-loader` to `wasmer-kernel-loader`.
losfair May 15, 2019
6df4e40
Cargo fmt
losfair May 15, 2019
a1a58d4
Merge remote-tracking branch 'origin/master' into feature/remote-code…
losfair May 15, 2019
13b4fe3
Temporarily disable caching for macos test.
losfair May 15, 2019
408f89c
Rename `loader:kwasm` to `loader:kernel` for consistency.
losfair May 15, 2019
3bbf775
Renamed kwasm-net to wasmer-kernel-net
syrusakbary May 15, 2019
720d984
Make kernel loader available by default
syrusakbary May 15, 2019
82bf7ea
Improved error messages when running on a specific loader
syrusakbary May 15, 2019
0ab8a04
Re-enable circleci cache
syrusakbary May 15, 2019
b289929
Rename `wasmer-kernel-net` to `kernel-net`.
losfair May 16, 2019
a177954
Rename `wasi-networking` to `echo-server`.
losfair May 16, 2019
100039a
Merge remote-tracking branch 'origin/master' into feature/remote-code…
losfair May 16, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 21 additions & 3 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Expand Up @@ -19,6 +19,7 @@ include = [
]

[dependencies]
byteorder = "1.3.1"
errno = "0.2.4"
structopt = "0.2.11"
wabt = "0.7.2"
Expand All @@ -32,9 +33,10 @@ wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" }
wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true }
wasmer-wasi = { path = "lib/wasi", optional = true }
kwasm-loader = { path = "lib/kwasm-loader" }

[workspace]
members = ["lib/clif-backend", "lib/singlepass-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend", "lib/wasi", "lib/middleware-common", "examples/plugin-for-example"]
members = ["lib/clif-backend", "lib/singlepass-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend", "lib/wasi", "lib/middleware-common", "lib/kwasm-loader", "examples/kernel/hello_world", "examples/pipe", "examples/plugin-for-example"]

[build-dependencies]
wabt = "0.7.2"
Expand Down
10 changes: 10 additions & 0 deletions examples/kernel/hello_world/Cargo.toml
@@ -0,0 +1,10 @@
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
14 changes: 14 additions & 0 deletions examples/kernel/hello_world/src/lib.rs
@@ -0,0 +1,14 @@
extern "C" {
fn print_str(base: *const u8, len: usize) -> i32;
}

#[no_mangle]
pub extern "C" fn main() -> i32 {
let v: Vec<i32> = (0..10).collect();
let s = format!("Hello world from WebAssembly. Some heap allocated integers: {:?}", v);
let s = s.as_bytes();
unsafe {
print_str(s.as_ptr(), s.len());
}
return 0;
}
7 changes: 7 additions & 0 deletions examples/pipe/Cargo.toml
@@ -0,0 +1,7 @@
[package]
name = "pipe"
version = "0.1.0"
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"]
edition = "2018"

[dependencies]
13 changes: 13 additions & 0 deletions examples/pipe/src/main.rs
@@ -0,0 +1,13 @@
use std::io::{Read, Write};

fn main() {
let mut stdin = ::std::io::stdin();
let mut stdout = ::std::io::stdout();
let mut buf: Vec<u8> = vec![0; 512];
let mut total: u64 = 0;
while total < 1048576u64 * 2048 {
let n = stdin.read(&mut buf).unwrap();
stdout.write_all(&buf[..n]).unwrap();
total += n as u64;
}
}
9 changes: 9 additions & 0 deletions lib/kwasm-loader/Cargo.toml
@@ -0,0 +1,9 @@
[package]
name = "kwasm-loader"
version = "0.1.0"
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"]
edition = "2018"

[dependencies]
libc = "0.2.49"
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
126 changes: 126 additions & 0 deletions lib/kwasm-loader/src/lib.rs
@@ -0,0 +1,126 @@
pub mod service;

use wasmer_runtime_core::{
loader::{self, Loader, Instance},
backend::RunnableModule,
vm::{Ctx, LocalGlobal, SigId, Anyfunc},
module::ModuleInfo,
types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex, FuncIndex},
structures::TypedIndex,
};
use service::{ServiceContext, LoadProfile, RunProfile, TableEntryRequest, ImportInfo};

pub struct KernelLoader;

impl Loader for KernelLoader {
type Instance = KernelInstance;
type Error = String;

fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, full_ctx: &Ctx) -> Result<Self::Instance, Self::Error> {
let ctx = &full_ctx.internal;
let code = rm.get_code().unwrap();
let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) {
Some(unsafe {
::std::slice::from_raw_parts((**ctx.memories).base, (**ctx.memories).bound)
})
} else if let Some(_) = module.imported_memories.get(ImportedMemoryIndex::new(0)) {
return Err("imported memory is not supported".into());
} else {
None
};
let table: Option<Vec<TableEntryRequest>> = 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());
}
let globals: Vec<u64> = unsafe {
let globals: &[*mut LocalGlobal] = ::std::slice::from_raw_parts(ctx.globals, module.globals.len());
globals.iter().map(|x| (**x).data).collect()
};
let mut import_names: Vec<ImportInfo> = vec![];
for (idx, import) in &module.imported_functions {
let name = format!("{}##{}", module.namespace_table.get(import.namespace_index), module.name_table.get(import.name_index));
let sig = module.signatures.get(
*module.func_assoc.get(FuncIndex::new(idx.index())).unwrap()
).unwrap();
import_names.push(ImportInfo {
name: name,
param_count: sig.params().len(),
});
}
let dynamic_sigindices: &[u32] = unsafe {
::std::mem::transmute::<&[SigId], &[u32]>(
::std::slice::from_raw_parts(ctx.dynamic_sigindices, full_ctx.dynamic_sigindice_count())
)
};
let param_counts: Vec<usize> = (0..module.func_assoc.len())
.map(|x| module.signatures.get(*module.func_assoc.get(FuncIndex::new(x)).unwrap()).unwrap().params().len())
.collect();
let profile = LoadProfile {
code: code,
memory: memory,
memory_max: 0,
globals: &globals,
imports: &import_names,
dynamic_sigindices: dynamic_sigindices,
table: table.as_ref().map(|x| x.as_slice()),
};
let sc = ServiceContext::new(profile).map_err(|x| format!("{:?}", x))?;
Ok(KernelInstance {
context: sc,
offsets: rm.get_offsets().unwrap(),
param_counts: param_counts,
})
}
}

pub struct KernelInstance {
context: ServiceContext,
offsets: Vec<usize>,
param_counts: Vec<usize>, // FIXME: Full signature check
}

impl Instance for KernelInstance {
type Error = String;
fn call(&mut self, id: usize, args: &[Value]) -> Result<u64, String> {
if args.len() != self.param_counts[id] {
return Err("param count mismatch".into());
}
let args: Vec<u64> = args.iter().map(|x| x.to_u64()).collect();

let ret = self.context.run_code(RunProfile {
entry_offset: self.offsets[id] as u32,
params: &args,
}).map_err(|x| format!("{:?}", x))?;
Ok(ret)
}

fn read_memory(&mut self, offset: u32, len: u32) -> Result<Vec<u8>, String> {
self.context.read_memory(offset, len).map_err(|x| format!("{:?}", x))
}

fn write_memory(&mut self, offset: u32, len: u32, buf: &[u8]) -> Result<(), String> {
self.context.write_memory(offset, len, buf).map_err(|x| format!("{:?}", x))
}
}