Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
2,451 additions
and
513 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "http-server" | ||
version = "0.1.0" | ||
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[workspace] | ||
|
||
[dependencies] | ||
kwasm-net = { path = "../../lib/kwasm-net" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#![feature(wasi_ext)] | ||
|
||
use kwasm_net::{schedule, Epoll, Tcp4Listener, TcpStream}; | ||
use std::sync::Arc; | ||
|
||
fn serve(stream: Arc<TcpStream>, mut all: Vec<u8>) { | ||
let stream2 = stream.clone(); | ||
stream.read_async( | ||
Vec::with_capacity(512), | ||
move |result| { | ||
match result { | ||
Ok(buf) => { | ||
if buf.len() == 0 { | ||
return; | ||
} | ||
all.extend_from_slice(&buf); | ||
if all.len() > 4096 { | ||
println!("header too large"); | ||
return; | ||
} | ||
let s = match ::std::str::from_utf8(&all) { | ||
Ok(x) => x, | ||
Err(e) => { | ||
println!("not utf8: {:?}", e); | ||
return; | ||
} | ||
}; | ||
if let Some(_pos) = s.find("\r\n\r\n") { | ||
let body = format!( | ||
"Hello, world!\n", | ||
).into_bytes(); | ||
let stream = stream2.clone(); | ||
stream2.write_all_async( | ||
format!( | ||
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\nContent-Length: {}\r\n\r\n", | ||
body.len() | ||
).into_bytes(), | ||
|_| { | ||
stream.write_all_async(body, |_| {}); | ||
} | ||
); | ||
} else { | ||
schedule(|| serve(stream2, all)); | ||
} | ||
} | ||
Err(code) => { | ||
println!("failed to read; code = {}", code); | ||
} | ||
} | ||
} | ||
); | ||
} | ||
|
||
fn main() { | ||
let epoll = Arc::new(Epoll::new()); | ||
let listener = Arc::new(Tcp4Listener::new("0.0.0.0", 2011, 128).unwrap()); | ||
|
||
listener.accept_async(epoll.clone(), |stream| match stream { | ||
Ok(stream) => { | ||
serve(stream, vec![]); | ||
Ok(()) | ||
} | ||
Err(code) => { | ||
println!("failed to accept; code = {}", code); | ||
Err(()) | ||
} | ||
}); | ||
println!("start epoll"); | ||
unsafe { | ||
epoll.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "pipe" | ||
version = "0.1.0" | ||
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"] | ||
edition = "2018" | ||
|
||
[workspace] | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "wasi-networking" | ||
version = "0.1.0" | ||
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"] | ||
edition = "2018" | ||
|
||
[workspace] | ||
|
||
[dependencies] | ||
kwasm-net = { path = "../../lib/kwasm-net" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#![feature(wasi_ext)] | ||
|
||
use kwasm_net::{schedule, Epoll, Tcp4Listener, TcpStream}; | ||
use std::sync::Arc; | ||
|
||
fn do_echo(stream: Arc<TcpStream>, buf: Vec<u8>) { | ||
let stream2 = stream.clone(); | ||
stream.read_async(buf, move |result| match result { | ||
Ok(buf) => { | ||
if buf.len() == 0 { | ||
return; | ||
} | ||
let stream = stream2.clone(); | ||
stream2.write_all_async(buf, move |result| match result { | ||
Ok(buf) => { | ||
schedule(|| { | ||
do_echo(stream, buf); | ||
}); | ||
} | ||
Err(code) => { | ||
println!("failed to write; code = {}", code); | ||
} | ||
}); | ||
} | ||
Err(code) => { | ||
println!("failed to read; code = {}", code); | ||
} | ||
}); | ||
} | ||
|
||
fn main() { | ||
let epoll = Arc::new(Epoll::new()); | ||
let listener = Arc::new(Tcp4Listener::new("0.0.0.0", 2001, 128).unwrap()); | ||
|
||
listener.accept_async(epoll.clone(), |stream| match stream { | ||
Ok(stream) => { | ||
do_echo(stream, Vec::with_capacity(16384)); | ||
Ok(()) | ||
} | ||
Err(code) => { | ||
println!("failed to accept; code = {}", code); | ||
Err(()) | ||
} | ||
}); | ||
println!("start epoll"); | ||
unsafe { | ||
epoll.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "wasmer-kernel-loader" | ||
version = "0.1.0" | ||
authors = ["Heyang Zhou <zhy20000919@hotmail.com>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
libc = "0.2.49" | ||
wasmer-runtime-core = { path = "../runtime-core" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
pub mod service; | ||
|
||
use service::{ImportInfo, LoadProfile, RunProfile, ServiceContext, TableEntryRequest}; | ||
use wasmer_runtime_core::{ | ||
backend::RunnableModule, | ||
loader::{self, Instance, Loader}, | ||
module::ModuleInfo, | ||
structures::TypedIndex, | ||
types::{ | ||
FuncIndex, ImportedMemoryIndex, ImportedTableIndex, LocalMemoryIndex, LocalTableIndex, | ||
Value, | ||
}, | ||
vm::{Anyfunc, Ctx, LocalGlobal, SigId}, | ||
}; | ||
|
||
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]; | ||
#[allow(clippy::cast_ptr_alignment)] | ||
{ | ||
elements = | ||
::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)) | ||
} | ||
} |
Oops, something went wrong.