Cargo fmt

This commit is contained in:
losfair
2019-05-14 16:04:08 +08:00
parent 722ea39877
commit 32f9aee6fe
14 changed files with 408 additions and 305 deletions

View File

@ -1,6 +1,6 @@
#![feature(wasi_ext)]
use kwasm_net::{Epoll, Tcp4Listener, TcpStream, schedule};
use kwasm_net::{schedule, Epoll, Tcp4Listener, TcpStream};
use std::sync::Arc;
fn serve(stream: Arc<TcpStream>, mut all: Vec<u8>) {
@ -55,17 +55,15 @@ 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 {
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 {

View File

@ -1,34 +1,30 @@
#![feature(wasi_ext)]
use kwasm_net::{Epoll, Tcp4Listener, TcpStream, schedule};
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 {
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 {
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);
}
}
});
}
@ -36,17 +32,15 @@ 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 {
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 {

View File

@ -1,14 +1,17 @@
pub mod service;
use service::{ImportInfo, LoadProfile, RunProfile, ServiceContext, TableEntryRequest};
use wasmer_runtime_core::{
loader::{self, Loader, Instance},
backend::RunnableModule,
vm::{Ctx, LocalGlobal, SigId, Anyfunc},
loader::{self, Instance, Loader},
module::ModuleInfo,
types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex, FuncIndex},
structures::TypedIndex,
types::{
FuncIndex, ImportedMemoryIndex, ImportedTableIndex, LocalMemoryIndex, LocalTableIndex,
Value,
},
vm::{Anyfunc, Ctx, LocalGlobal, SigId},
};
use service::{ServiceContext, LoadProfile, RunProfile, TableEntryRequest, ImportInfo};
pub struct KernelLoader;
@ -16,7 +19,12 @@ 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> {
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)) {
@ -28,23 +36,31 @@ impl Loader for KernelLoader {
} else {
None
};
let table: Option<Vec<TableEntryRequest>> = if let Some(_) = module.tables.get(LocalTableIndex::new(0)) {
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 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| {
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 {
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()
})
.collect()
})
} else if let Some(_) = module.imported_tables.get(ImportedTableIndex::new(0)) {
return Err("imported table is not supported".into());
@ -55,27 +71,41 @@ impl Loader for KernelLoader {
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());
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();
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())
)
::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())
.map(|x| {
module
.signatures
.get(*module.func_assoc.get(FuncIndex::new(x)).unwrap())
.unwrap()
.params()
.len()
})
.collect();
let profile = LoadProfile {
code: code,
@ -109,18 +139,25 @@ impl Instance for KernelInstance {
}
let args: Vec<u64> = args.iter().map(|x| x.to_u64()).collect();
let ret = self.context.run_code(RunProfile {
let ret = self
.context
.run_code(RunProfile {
entry_offset: self.offsets[id] as u32,
params: &args,
}).map_err(|x| format!("{:?}", x))?;
})
.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))
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))
self.context
.write_memory(offset, len, buf)
.map_err(|x| format!("{:?}", x))
}
}

View File

@ -1,6 +1,6 @@
use std::error::Error;
use std::fs::File;
use std::io;
use std::error::Error;
use std::os::unix::io::AsRawFd;
macro_rules! impl_debug_display {
@ -10,7 +10,7 @@ macro_rules! impl_debug_display {
<Self as ::std::fmt::Debug>::fmt(self, f)
}
}
}
};
}
#[repr(i32)]
@ -26,7 +26,7 @@ pub enum ServiceError {
Io(io::Error),
Code(i32),
InvalidInput,
Rejected
Rejected,
}
pub type ServiceResult<T> = Result<T, ServiceError>;
@ -125,13 +125,16 @@ pub struct RunProfile<'a> {
}
pub struct ServiceContext {
dev: File
dev: File,
}
impl ServiceContext {
pub fn new(load: LoadProfile) -> ServiceResult<ServiceContext> {
let dev = File::open("/dev/wasmctl")?;
let imports: Vec<ImportRequest> = load.imports.iter().map(|x| {
let imports: Vec<ImportRequest> = load
.imports
.iter()
.map(|x| {
let mut req = ImportRequest {
name: [0u8; 64],
param_count: x.param_count as u32,
@ -143,11 +146,15 @@ impl ServiceContext {
}
req.name[..count].copy_from_slice(&name[..count]);
req
}).collect();
})
.collect();
let req = LoadCodeRequest {
code: load.code.as_ptr(),
code_len: load.code.len() as u32,
memory: load.memory.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()),
memory: load
.memory
.map(|x| x.as_ptr())
.unwrap_or(::std::ptr::null()),
memory_len: load.memory.map(|x| x.len() as u32).unwrap_or(0),
memory_max: load.memory_max as u32,
table: load.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()),
@ -164,15 +171,13 @@ impl ServiceContext {
::libc::ioctl(
fd,
Command::LoadCode as i32 as ::libc::c_ulong,
&req as *const _ as ::libc::c_ulong
&req as *const _ as ::libc::c_ulong,
)
};
if ret != 0 {
Err(ServiceError::Code(ret))
} else {
Ok(ServiceContext {
dev: dev,
})
Ok(ServiceContext { dev: dev })
}
}
@ -189,7 +194,7 @@ impl ServiceContext {
::libc::ioctl(
fd,
Command::RunCode as i32 as ::libc::c_ulong,
&mut req as *mut _ as ::libc::c_ulong
&mut req as *mut _ as ::libc::c_ulong,
)
};
if err < 0 {
@ -217,7 +222,7 @@ impl ServiceContext {
::libc::ioctl(
fd,
Command::ReadMemory as i32 as ::libc::c_ulong,
&req as *const _ as ::libc::c_ulong
&req as *const _ as ::libc::c_ulong,
)
};
if err < 0 {
@ -238,7 +243,7 @@ impl ServiceContext {
::libc::ioctl(
fd,
Command::WriteMemory as i32 as ::libc::c_ulong,
&req as *const _ as ::libc::c_ulong
&req as *const _ as ::libc::c_ulong,
)
};
if err < 0 {

View File

@ -1,10 +1,10 @@
#![feature(wasi_ext)]
use std::fs::File;
use std::os::wasi::io::FromRawFd;
use std::net::{Ipv4Addr, AddrParseError};
use std::sync::{Arc, Mutex};
use std::cell::RefCell;
use std::fs::File;
use std::net::{AddrParseError, Ipv4Addr};
use std::os::wasi::io::FromRawFd;
use std::sync::{Arc, Mutex};
const AF_INET: i32 = 2;
const SOCK_STREAM: i32 = 1;
@ -26,27 +26,27 @@ extern "C" {
fn _bind(fd: i32, sa: *const SockaddrIn, sa_len: usize) -> i32;
fn _listen(fd: i32, backlog: i32) -> i32;
fn _accept4(fd: i32, sa: *mut SockaddrIn, sa_len: *mut usize, flags: u32) -> i32;
fn _sendto(fd: i32, buf: *const u8, buf_len: usize, flags: u32, addr: *const SockaddrIn, addr_len: usize) -> i32;
fn _recvfrom(fd: i32, buf: *mut u8, buf_len: usize, flags: u32, addr: *mut SockaddrIn, addr_len: *mut usize) -> i32;
fn _sendto(
fd: i32,
buf: *const u8,
buf_len: usize,
flags: u32,
addr: *const SockaddrIn,
addr_len: usize,
) -> i32;
fn _recvfrom(
fd: i32,
buf: *mut u8,
buf_len: usize,
flags: u32,
addr: *mut SockaddrIn,
addr_len: *mut usize,
) -> i32;
fn _eventfd_sem(initial: u32) -> i32;
fn _epoll_create() -> i32;
fn _epoll_ctl(
epfd: i32,
op: i32,
fd: i32,
event: *const EpollEvent,
) -> i32;
fn _epoll_wait(
epfd: i32,
events: *mut EpollEvent,
maxevents: usize,
timeout: i32,
) -> i32;
fn _fcntl(
fd: i32,
cmd: i32,
arg: u32,
) -> i32;
fn _epoll_ctl(epfd: i32, op: i32, fd: i32, event: *const EpollEvent) -> i32;
fn _epoll_wait(epfd: i32, events: *mut EpollEvent, maxevents: usize, timeout: i32) -> i32;
fn _fcntl(fd: i32, cmd: i32, arg: u32) -> i32;
}
thread_local! {
@ -67,9 +67,7 @@ pub struct Epoll {
impl Epoll {
pub fn new() -> Epoll {
let fd = unsafe {
_epoll_create()
};
let fd = unsafe { _epoll_create() };
assert!(fd >= 0);
Epoll {
fd: fd,
@ -85,10 +83,11 @@ impl Epoll {
GLOBAL_EPOLL.with(|x| {
*x.borrow_mut() = Some(self.clone());
});
let mut events: Vec<EpollEvent> = vec! [ EpollEvent::default(); 32 ];
let mut events: Vec<EpollEvent> = vec![EpollEvent::default(); 32];
loop {
loop {
let imm_queue = ::std::mem::replace(&mut *self.imm_queue.lock().unwrap(), Vec::new());
let imm_queue =
::std::mem::replace(&mut *self.imm_queue.lock().unwrap(), Vec::new());
if imm_queue.len() == 0 {
break;
}
@ -128,11 +127,15 @@ impl Drop for Epoll {
#[derive(Copy, Clone, Debug)]
pub enum EpollDirection {
In,
Out
Out,
}
fn get_async_state() -> Box<AsyncState> {
ASYNC_STATE_POOL.with(|pool| pool.borrow_mut().pop().unwrap_or_else(|| Box::new(AsyncState::default())))
ASYNC_STATE_POOL.with(|pool| {
pool.borrow_mut()
.pop()
.unwrap_or_else(|| Box::new(AsyncState::default()))
})
}
fn put_async_state(mut x: Box<AsyncState>) {
@ -147,7 +150,11 @@ pub fn schedule<F: FnOnce() + 'static>(f: F) {
epoll.schedule(f);
}
fn get_async_io_payload<T: 'static, P: FnMut(i32) -> Result<T, i32> + 'static, F: FnOnce(Result<T, i32>) + 'static>(
fn get_async_io_payload<
T: 'static,
P: FnMut(i32) -> Result<T, i32> + 'static,
F: FnOnce(Result<T, i32>) + 'static,
>(
epoll: Arc<Epoll>,
fd: i32,
direction: EpollDirection,
@ -157,7 +164,11 @@ fn get_async_io_payload<T: 'static, P: FnMut(i32) -> Result<T, i32> + 'static, F
__get_async_io_payload(epoll, fd, direction, poll_action, on_ready, false)
}
fn __get_async_io_payload<T: 'static, P: FnMut(i32) -> Result<T, i32> + 'static, F: FnOnce(Result<T, i32>) + 'static>(
fn __get_async_io_payload<
T: 'static,
P: FnMut(i32) -> Result<T, i32> + 'static,
F: FnOnce(Result<T, i32>) + 'static,
>(
epoll: Arc<Epoll>,
fd: i32,
direction: EpollDirection,
@ -173,7 +184,14 @@ fn __get_async_io_payload<T: 'static, P: FnMut(i32) -> Result<T, i32> + 'static,
match ret {
Err(x) if x == -EAGAIN || x == -EWOULDBLOCK => {
let mut state = get_async_state();
state.callback = Some(__get_async_io_payload(epoll.clone(), fd, direction, poll_action, on_ready, true));
state.callback = Some(__get_async_io_payload(
epoll.clone(),
fd,
direction,
poll_action,
on_ready,
true,
));
state._epoll = Some(epoll);
let direction_flag = match direction {
EpollDirection::In => EPOLLIN,
@ -184,22 +202,14 @@ fn __get_async_io_payload<T: 'static, P: FnMut(i32) -> Result<T, i32> + 'static,
data: Box::into_raw(state) as usize as _,
};
//println!("Alloc event {:?}", ev.data as usize as *mut AsyncState);
let ret = unsafe { _epoll_ctl(
epfd,
EPOLL_CTL_ADD,
fd,
&ev
) };
let ret = unsafe { _epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) };
assert!(ret >= 0);
},
}
x => {
if registered {
assert!(unsafe { _epoll_ctl(
epfd,
EPOLL_CTL_DEL,
fd,
::std::ptr::null(),
) } >= 0);
assert!(
unsafe { _epoll_ctl(epfd, EPOLL_CTL_DEL, fd, ::std::ptr::null(),) } >= 0
);
}
on_ready(x); // fast path
}
@ -264,23 +274,19 @@ impl Tcp4Listener {
let sa = SockaddrIn {
sin_family: AF_INET as _,
sin_port: invert_byteorder_u16(port),
sin_addr: InAddr { s_addr: unsafe { ::std::mem::transmute(addr.octets()) } },
sin_addr: InAddr {
s_addr: unsafe { ::std::mem::transmute(addr.octets()) },
},
sin_zero: [0; 8],
};
let fd = unsafe {
_socket(AF_INET, SOCK_STREAM, 0)
};
let fd = unsafe { _socket(AF_INET, SOCK_STREAM, 0) };
if fd < 0 {
return Err(SocketError::SocketCreate);
}
if unsafe {
_bind(fd, &sa, ::std::mem::size_of::<SockaddrIn>())
} < 0 {
if unsafe { _bind(fd, &sa, ::std::mem::size_of::<SockaddrIn>()) } < 0 {
return Err(SocketError::Bind);
}
if unsafe {
_listen(fd, backlog as _)
} < 0 {
if unsafe { _listen(fd, backlog as _) } < 0 {
return Err(SocketError::Listen);
}
@ -297,14 +303,20 @@ impl Tcp4Listener {
})
}
pub fn accept_async<F: Fn(Result<Arc<TcpStream>, i32>) -> Result<(), ()> + 'static>(self: Arc<Self>, ep: Arc<Epoll>, cb: F) {
pub fn accept_async<F: Fn(Result<Arc<TcpStream>, i32>) -> Result<(), ()> + 'static>(
self: Arc<Self>,
ep: Arc<Epoll>,
cb: F,
) {
let ep2 = ep.clone();
(get_async_io_payload(ep.clone(), self.fd, EpollDirection::In, move |fd| -> Result<Arc<TcpStream>, i32> {
(get_async_io_payload(
ep.clone(),
self.fd,
EpollDirection::In,
move |fd| -> Result<Arc<TcpStream>, i32> {
let mut incoming_sa: SockaddrIn = unsafe { ::std::mem::uninitialized() };
let mut real_len: usize = ::std::mem::size_of::<SockaddrIn>();
let conn = unsafe {
_accept4(fd, &mut incoming_sa, &mut real_len, O_NONBLOCK)
};
let conn = unsafe { _accept4(fd, &mut incoming_sa, &mut real_len, O_NONBLOCK) };
if conn >= 0 {
unsafe {
let mut socket_flags = _fcntl(conn, F_GETFL, 0) as u32;
@ -318,13 +330,15 @@ impl Tcp4Listener {
} else {
Err(conn)
}
}, move |x| {
},
move |x| {
schedule(|| {
if let Ok(()) = cb(x) {
self.accept_async(ep2, cb);
}
});
}))();
},
))();
}
}
@ -334,7 +348,12 @@ pub struct TcpStream {
}
impl TcpStream {
pub fn __write_async(self: Arc<Self>, data: Vec<u8>, offset: usize, cb: impl FnOnce(Result<(usize, Vec<u8>), i32>) + 'static) {
pub fn __write_async(
self: Arc<Self>,
data: Vec<u8>,
offset: usize,
cb: impl FnOnce(Result<(usize, Vec<u8>), i32>) + 'static,
) {
let mut data = Some(data);
(get_async_io_payload(
@ -344,9 +363,8 @@ impl TcpStream {
move |fd| -> Result<(usize, Vec<u8>), i32> {
let _data = data.as_ref().unwrap();
let _data = &_data[offset..];
let ret = unsafe {
_sendto(fd, _data.as_ptr(), _data.len(), 0, ::std::ptr::null(), 0)
};
let ret =
unsafe { _sendto(fd, _data.as_ptr(), _data.len(), 0, ::std::ptr::null(), 0) };
if ret >= 0 {
Ok((ret as usize, data.take().unwrap()))
} else {
@ -356,19 +374,31 @@ impl TcpStream {
move |x| {
drop(self);
cb(x);
}
},
))();
}
pub fn write_async(self: Arc<Self>, data: Vec<u8>, cb: impl FnOnce(Result<(usize, Vec<u8>), i32>) + 'static) {
pub fn write_async(
self: Arc<Self>,
data: Vec<u8>,
cb: impl FnOnce(Result<(usize, Vec<u8>), i32>) + 'static,
) {
self.__write_async(data, 0, cb)
}
pub fn write_all_async(self: Arc<Self>, data: Vec<u8>, cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static) {
fn inner(me: Arc<TcpStream>, data: Vec<u8>, offset: usize, cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static) {
pub fn write_all_async(
self: Arc<Self>,
data: Vec<u8>,
cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static,
) {
fn inner(
me: Arc<TcpStream>,
data: Vec<u8>,
offset: usize,
cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static,
) {
let me2 = me.clone();
me.__write_async(data, offset, move |result| {
match result {
me.__write_async(data, offset, move |result| match result {
Ok((len, data)) => {
let new_offset = offset + len;
if new_offset == data.len() {
@ -380,13 +410,16 @@ impl TcpStream {
Err(code) => {
cb(Err(code));
}
}
})
}
inner(self, data, 0, cb);
}
pub fn read_async(self: Arc<Self>, out: Vec<u8>, cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static) {
pub fn read_async(
self: Arc<Self>,
out: Vec<u8>,
cb: impl FnOnce(Result<Vec<u8>, i32>) + 'static,
) {
let mut out = Some(out);
(get_async_io_payload(
self.epoll.clone(),
@ -396,7 +429,14 @@ impl TcpStream {
let _out = out.as_mut().unwrap();
let out_cap = _out.capacity();
let ret = unsafe {
_recvfrom(fd, _out.as_mut_ptr(), out_cap, 0, ::std::ptr::null_mut(), ::std::ptr::null_mut())
_recvfrom(
fd,
_out.as_mut_ptr(),
out_cap,
0,
::std::ptr::null_mut(),
::std::ptr::null_mut(),
)
};
if ret >= 0 {
assert!(ret as usize <= out_cap);
@ -411,7 +451,7 @@ impl TcpStream {
move |x| {
drop(self);
cb(x);
}
},
))();
}
}

View File

@ -91,8 +91,12 @@ pub trait RunnableModule: Send + Sync {
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> !;
fn get_code(&self) -> Option<&[u8]> { None }
fn get_offsets(&self) -> Option<Vec<usize>> { None }
fn get_code(&self) -> Option<&[u8]> {
None
}
fn get_offsets(&self) -> Option<Vec<usize>> {
None
}
}
pub trait CacheGen: Send + Sync {

View File

@ -57,7 +57,9 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
/// Adds an import function.
fn feed_import_function(&mut self) -> Result<(), E>;
fn feed_compiler_config(&mut self, _config: &CompilerConfig) -> Result<(), E> { Ok(()) }
fn feed_compiler_config(&mut self, _config: &CompilerConfig) -> Result<(), E> {
Ok(())
}
unsafe fn from_cache(cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
}

View File

@ -5,15 +5,15 @@ use crate::{
export::{Context, Export, ExportIter, FuncPointer},
global::Global,
import::{ImportObject, LikeNamespace},
loader::Loader,
memory::Memory,
module::{ExportIndex, Module, ModuleInfo, ModuleInner},
sig_registry::SigRegistry,
structures::TypedIndex,
table::Table,
typed_func::{Func, Wasm, WasmTrapInfo, WasmTypeList},
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Type, Value},
vm,
loader::Loader,
structures::TypedIndex,
};
use smallvec::{smallvec, SmallVec};
use std::{mem, ptr::NonNull, sync::Arc};
@ -130,7 +130,9 @@ impl Instance {
}
pub fn load<T: Loader>(&self, loader: T) -> ::std::result::Result<T::Instance, T::Error> {
loader.load(&*self.module.runnable_module, &self.module.info, unsafe { &*self.inner.vmctx })
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...

View File

@ -21,6 +21,7 @@ pub mod export;
pub mod global;
pub mod import;
pub mod instance;
pub mod loader;
pub mod memory;
pub mod module;
pub mod parse;
@ -34,7 +35,6 @@ pub mod units;
pub mod vm;
#[doc(hidden)]
pub mod vmcalls;
pub mod loader;
use self::error::CompileResult;
#[doc(inline)]

View File

@ -1,24 +1,21 @@
use crate::{backend::RunnableModule, module::ModuleInfo, types::Value, vm::Ctx};
#[cfg(unix)]
use libc::{mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE};
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use crate::{
backend::RunnableModule,
vm::Ctx,
module::ModuleInfo,
types::Value,
};
#[cfg(unix)]
use libc::{
mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ,
PROT_WRITE,
};
pub trait Loader {
type Instance: Instance;
type Error: Debug;
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &Ctx) -> Result<Self::Instance, Self::Error>;
fn load(
&self,
rm: &dyn RunnableModule,
module: &ModuleInfo,
ctx: &Ctx,
) -> Result<Self::Instance, Self::Error>;
}
pub trait Instance {
@ -39,7 +36,12 @@ impl Loader for LocalLoader {
type Instance = LocalInstance;
type Error = String;
fn load(&self, rm: &dyn RunnableModule, _module: &ModuleInfo, _ctx: &Ctx) -> Result<Self::Instance, Self::Error> {
fn load(
&self,
rm: &dyn RunnableModule,
_module: &ModuleInfo,
_ctx: &Ctx,
) -> Result<Self::Instance, Self::Error> {
let code = rm.get_code().unwrap();
let mut code_mem = CodeMemory::new(code.len());
code_mem[..code.len()].copy_from_slice(code);
@ -67,11 +69,29 @@ impl Instance for LocalInstance {
match args.len() {
0 => (transmute::<_, extern "C" fn() -> u64>(addr))(),
1 => (transmute::<_, extern "C" fn(u64) -> u64>(addr))(args[0].to_u64()),
2 => (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))(args[0].to_u64(), args[1].to_u64()),
3 => (transmute::<_, extern "C" fn(u64, u64, u64) -> u64>(addr))(args[0].to_u64(), args[1].to_u64(), args[2].to_u64()),
4 => (transmute::<_, extern "C" fn(u64, u64, u64, u64) -> u64>(addr))(args[0].to_u64(), args[1].to_u64(), args[2].to_u64(), args[3].to_u64()),
5 => (transmute::<_, extern "C" fn(u64, u64, u64, u64, u64) -> u64>(addr))(args[0].to_u64(), args[1].to_u64(), args[2].to_u64(), args[3].to_u64(), args[4].to_u64()),
_ => return Err("too many arguments".into())
2 => (transmute::<_, extern "C" fn(u64, u64) -> u64>(addr))(
args[0].to_u64(),
args[1].to_u64(),
),
3 => (transmute::<_, extern "C" fn(u64, u64, u64) -> u64>(addr))(
args[0].to_u64(),
args[1].to_u64(),
args[2].to_u64(),
),
4 => (transmute::<_, extern "C" fn(u64, u64, u64, u64) -> u64>(addr))(
args[0].to_u64(),
args[1].to_u64(),
args[2].to_u64(),
args[3].to_u64(),
),
5 => (transmute::<_, extern "C" fn(u64, u64, u64, u64, u64) -> u64>(addr))(
args[0].to_u64(),
args[1].to_u64(),
args[2].to_u64(),
args[3].to_u64(),
args[4].to_u64(),
),
_ => return Err("too many arguments".into()),
}
})
}
@ -129,23 +149,21 @@ impl CodeMemory {
#[cfg(unix)]
impl Drop for CodeMemory {
fn drop(&mut self) {
unsafe { munmap(self.ptr as _, self.size); }
unsafe {
munmap(self.ptr as _, self.size);
}
}
}
impl Deref for CodeMemory {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
::std::slice::from_raw_parts(self.ptr, self.size)
}
unsafe { ::std::slice::from_raw_parts(self.ptr, self.size) }
}
}
impl DerefMut for CodeMemory {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
::std::slice::from_raw_parts_mut(self.ptr, self.size)
}
unsafe { ::std::slice::from_raw_parts_mut(self.ptr, self.size) }
}
}

View File

@ -300,9 +300,7 @@ impl Ctx {
/// Returns the number of dynamic sigindices.
pub fn dynamic_sigindice_count(&self) -> usize {
unsafe {
(*self.local_backing).dynamic_sigindices.len()
}
unsafe { (*self.local_backing).dynamic_sigindices.len() }
}
}

View File

@ -10,7 +10,9 @@ use smallvec::SmallVec;
use std::ptr::NonNull;
use std::{any::Any, collections::HashMap, sync::Arc};
use wasmer_runtime_core::{
backend::{sys::Memory, Backend, CacheGen, Token, RunnableModule, CompilerConfig, MemoryBoundCheckMode},
backend::{
sys::Memory, Backend, CacheGen, CompilerConfig, MemoryBoundCheckMode, RunnableModule, Token,
},
cache::{Artifact, Error as CacheError},
codegen::*,
memory::MemoryType,
@ -318,8 +320,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
}
fn next_function(&mut self) -> Result<&mut X64FunctionCode, CodegenError> {
let (mut assembler, mut function_labels, breakpoints) =
match self.functions.last_mut() {
let (mut assembler, mut function_labels, breakpoints) = match self.functions.last_mut() {
Some(x) => (
x.assembler.take().unwrap(),
x.function_labels.take().unwrap(),
@ -365,12 +366,12 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
Ok(self.functions.last_mut().unwrap())
}
fn finalize(mut self, _: &ModuleInfo) -> Result<(X64ExecutionContext, Box<dyn CacheGen>), CodegenError> {
fn finalize(
mut self,
_: &ModuleInfo,
) -> Result<(X64ExecutionContext, Box<dyn CacheGen>), CodegenError> {
let (assembler, breakpoints) = match self.functions.last_mut() {
Some(x) => (
x.assembler.take().unwrap(),
x.breakpoints.take().unwrap(),
),
Some(x) => (x.assembler.take().unwrap(), x.breakpoints.take().unwrap()),
None => {
return Err(CodegenError {
message: "no function",
@ -1429,7 +1430,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
GPR::RDI, // first parameter is vmctx
vm::Ctx::offset_stack_lower_bound() as i32,
),
Location::GPR(GPR::RSP)
Location::GPR(GPR::RSP),
);
a.emit_conditional_trap(Condition::Below);
}
@ -3329,13 +3330,16 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
let memory_index = MemoryIndex::new(reserved as usize);
a.emit_mov(
Size::S64,
Location::Memory(Machine::get_vmctx_reg(), vm::Ctx::offset_intrinsics() as i32),
Location::GPR(GPR::RAX)
Location::Memory(
Machine::get_vmctx_reg(),
vm::Ctx::offset_intrinsics() as i32,
),
Location::GPR(GPR::RAX),
);
a.emit_mov(
Size::S64,
Location::Memory(GPR::RAX, vm::Intrinsics::offset_memory_size() as i32),
Location::GPR(GPR::RAX)
Location::GPR(GPR::RAX),
);
Self::emit_call_sysv(
a,
@ -3359,13 +3363,16 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
a.emit_mov(
Size::S64,
Location::Memory(Machine::get_vmctx_reg(), vm::Ctx::offset_intrinsics() as i32),
Location::GPR(GPR::RAX)
Location::Memory(
Machine::get_vmctx_reg(),
vm::Ctx::offset_intrinsics() as i32,
),
Location::GPR(GPR::RAX),
);
a.emit_mov(
Size::S64,
Location::Memory(GPR::RAX, vm::Intrinsics::offset_memory_grow() as i32),
Location::GPR(GPR::RAX)
Location::GPR(GPR::RAX),
);
Self::emit_call_sysv(
@ -4091,10 +4098,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
);
a.emit_jmp(Condition::AboveEqual, default_br);
a.emit_lea_label(
table_label,
Location::GPR(GPR::RCX),
);
a.emit_lea_label(table_label, Location::GPR(GPR::RCX));
a.emit_mov(Size::S32, cond, Location::GPR(GPR::RDX));
a.emit_imul_imm32_gpr64(5, GPR::RDX);
a.emit_add(Size::S64, Location::GPR(GPR::RCX), Location::GPR(GPR::RDX));

View File

@ -1,21 +1,19 @@
extern crate structopt;
extern crate byteorder;
extern crate structopt;
use std::thread;
use structopt::StructOpt;
use wasmer::*;
use wasmer_runtime::{
Value,
};
use wasmer_runtime::Value;
use wasmer_runtime_core::{
self,
backend::{CompilerConfig, MemoryBoundCheckMode},
loader::{Instance as LoadedInstance},
loader::Instance as LoadedInstance,
};
use wasmer_singlepass_backend::SinglePassCompiler;
use std::os::unix::net::{UnixStream, UnixListener};
use std::io::prelude::*;
use std::os::unix::net::{UnixListener, UnixStream};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@ -54,7 +52,8 @@ fn handle_client(mut stream: UnixStream) {
enforce_stack_check: true,
},
&SinglePassCompiler::new(),
).unwrap();
)
.unwrap();
let mut import_object = wasmer_runtime_core::import::ImportObject::new();
import_object.allow_missing_functions = true; // Import initialization might be left to the loader.
@ -90,13 +89,13 @@ fn handle_client(mut stream: UnixStream) {
Ok(x) => {
stream.write_u32::<LittleEndian>(1).unwrap();
stream.write_u64::<LittleEndian>(x).unwrap();
},
}
Err(e) => {
println!("Execution error: {:?}", e);
stream.write_u32::<LittleEndian>(0).unwrap();
},
}
},
}
}
CMD_READ_MEMORY => {
let offset = stream.read_u32::<LittleEndian>().unwrap();
let len = stream.read_u32::<LittleEndian>().unwrap();
@ -106,7 +105,7 @@ fn handle_client(mut stream: UnixStream) {
}
let buf = ins.read_memory(offset, len).unwrap();
stream.write_all(&buf).unwrap();
},
}
CMD_WRITE_MEMORY => {
let offset = stream.read_u32::<LittleEndian>().unwrap();
let len = stream.read_u32::<LittleEndian>().unwrap();
@ -118,7 +117,7 @@ fn handle_client(mut stream: UnixStream) {
unsafe { buf.set_len(len as usize) };
stream.read_exact(&mut buf).unwrap();
ins.write_memory(offset, len, &buf).unwrap();
},
}
_ => {
println!("Unknown command");
return;
@ -137,7 +136,7 @@ fn run_listen(opts: Listen) {
match ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
handle_client(stream);
})) {
Ok(()) => {},
Ok(()) => {}
Err(_) => {}
}
});

View File

@ -315,7 +315,8 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
enforce_stack_check: true,
},
&*compiler,
).map_err(|e| format!("Can't compile module: {:?}", e))?
)
.map_err(|e| format!("Can't compile module: {:?}", e))?
} else if disable_cache {
webassembly::compile_with_config_with(
&wasm_binary[..],
@ -324,7 +325,8 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
..Default::default()
},
&*compiler,
).map_err(|e| format!("Can't compile module: {:?}", e))?
)
.map_err(|e| format!("Can't compile module: {:?}", e))?
} else {
// If we have cache enabled
@ -388,7 +390,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
LoaderName::Kernel => Box::new(instance.load(::kwasm_loader::KernelLoader).unwrap()),
};
println!("{:?}", ins.call(index, &args));
return Ok(())
return Ok(());
}
// TODO: refactor this