mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-08 16:52:13 +00:00
Merge branch 'master' into fix-runtime-c-api-error-length
This commit is contained in:
commit
b050144898
@ -7,6 +7,7 @@ Blocks of changes will separated by version increments.
|
|||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
- [#432](https://github.com/wasmerio/wasmer/pull/432) Fix returned value of `wasmer_last_error_message` in the runtime C API
|
- [#432](https://github.com/wasmerio/wasmer/pull/432) Fix returned value of `wasmer_last_error_message` in the runtime C API
|
||||||
|
- [#429](https://github.com/wasmerio/wasmer/pull/429) Get wasi::path_filestat_get working for some programs; misc. minor WASI FS improvements
|
||||||
- [#413](https://github.com/wasmerio/wasmer/pull/413) Update LLVM backend to use new parser codegen traits
|
- [#413](https://github.com/wasmerio/wasmer/pull/413) Update LLVM backend to use new parser codegen traits
|
||||||
|
|
||||||
## 0.4.1 - 2018-05-06
|
## 0.4.1 - 2018-05-06
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
mod func_env;
|
mod func_env;
|
||||||
mod libcalls;
|
mod libcalls;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate wasmer_runtime_core;
|
extern crate wasmer_runtime_core;
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::varargs::VarArgs;
|
use crate::varargs::VarArgs;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use libc::size_t;
|
||||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||||
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
||||||
use libc::{
|
use libc::{
|
||||||
@ -53,7 +55,6 @@ use libc::{
|
|||||||
sendto,
|
sendto,
|
||||||
setpgid,
|
setpgid,
|
||||||
setsockopt,
|
setsockopt,
|
||||||
size_t,
|
|
||||||
sockaddr,
|
sockaddr,
|
||||||
socket,
|
socket,
|
||||||
socklen_t,
|
socklen_t,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
#![cfg_attr(nightly, feature(unwind_attributes))]
|
#![cfg_attr(nightly, feature(unwind_attributes))]
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
|
@ -34,7 +34,7 @@ pub unsafe fn visit_fde(addr: *mut u8, size: usize, visitor: extern "C" fn(*mut
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
pub unsafe fn visit_fde(addr: *mut u8, size: usize, visitor: extern "C" fn(*mut u8)) {
|
pub unsafe fn visit_fde(addr: *mut u8, _size: usize, visitor: extern "C" fn(*mut u8)) {
|
||||||
visitor(addr);
|
visitor(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ impl FunctionMiddleware for CallTrace {
|
|||||||
fn feed_event<'a, 'b: 'a>(
|
fn feed_event<'a, 'b: 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: Event<'a, 'b>,
|
op: Event<'a, 'b>,
|
||||||
module_info: &ModuleInfo,
|
_module_info: &ModuleInfo,
|
||||||
sink: &mut EventSink<'a, 'b>,
|
sink: &mut EventSink<'a, 'b>,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
match op {
|
match op {
|
||||||
|
@ -1 +1,3 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
pub mod call_trace;
|
pub mod call_trace;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
extern crate wasmer_runtime;
|
extern crate wasmer_runtime;
|
||||||
extern crate wasmer_runtime_core;
|
extern crate wasmer_runtime_core;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::RunnableModule,
|
backend::RunnableModule,
|
||||||
backend::{sys::Memory, Backend, CacheGen, Compiler, CompilerConfig, Token},
|
backend::{Backend, CacheGen, Compiler, CompilerConfig, Token},
|
||||||
cache::{Artifact, Error as CacheError},
|
cache::{Artifact, Error as CacheError},
|
||||||
error::{CompileError, CompileResult},
|
error::{CompileError, CompileResult},
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::{ModuleInfo, ModuleInner},
|
||||||
@ -35,7 +35,6 @@ impl fmt::Debug for InternalEvent {
|
|||||||
InternalEvent::Breakpoint(_) => write!(f, "Breakpoint"),
|
InternalEvent::Breakpoint(_) => write!(f, "Breakpoint"),
|
||||||
InternalEvent::SetInternal(_) => write!(f, "SetInternal"),
|
InternalEvent::SetInternal(_) => write!(f, "SetInternal"),
|
||||||
InternalEvent::GetInternal(_) => write!(f, "GetInternal"),
|
InternalEvent::GetInternal(_) => write!(f, "GetInternal"),
|
||||||
_ => panic!("unknown event"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
#![cfg_attr(nightly, feature(unwind_attributes))]
|
#![cfg_attr(nightly, feature(unwind_attributes))]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -247,7 +247,7 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
|
|||||||
type CStruct = S1<A>;
|
type CStruct = S1<A>;
|
||||||
type RetArray = [u64; 1];
|
type RetArray = [u64; 1];
|
||||||
fn from_ret_array(array: Self::RetArray) -> Self {
|
fn from_ret_array(array: Self::RetArray) -> Self {
|
||||||
(WasmExternType::from_native(NativeWasmType::from_bits(
|
(WasmExternType::from_native(NativeWasmType::from_binary(
|
||||||
array[0],
|
array[0],
|
||||||
)),)
|
)),)
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
|
|||||||
ctx: *mut Ctx,
|
ctx: *mut Ctx,
|
||||||
) -> Result<Rets, RuntimeError> {
|
) -> Result<Rets, RuntimeError> {
|
||||||
let (a,) = self;
|
let (a,) = self;
|
||||||
let args = [a.to_native().to_bits()];
|
let args = [a.to_native().to_binary()];
|
||||||
let mut rets = Rets::empty_ret_array();
|
let mut rets = Rets::empty_ret_array();
|
||||||
let mut trap = WasmTrapInfo::Unknown;
|
let mut trap = WasmTrapInfo::Unknown;
|
||||||
let mut user_error = None;
|
let mut user_error = None;
|
||||||
@ -322,7 +322,7 @@ macro_rules! impl_traits {
|
|||||||
fn from_ret_array(array: Self::RetArray) -> Self {
|
fn from_ret_array(array: Self::RetArray) -> Self {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let [ $( $x ),* ] = array;
|
let [ $( $x ),* ] = array;
|
||||||
( $( WasmExternType::from_native(NativeWasmType::from_bits($x)) ),* )
|
( $( WasmExternType::from_native(NativeWasmType::from_binary($x)) ),* )
|
||||||
}
|
}
|
||||||
fn empty_ret_array() -> Self::RetArray {
|
fn empty_ret_array() -> Self::RetArray {
|
||||||
[0; count_idents!( $( $x ),* )]
|
[0; count_idents!( $( $x ),* )]
|
||||||
@ -344,7 +344,7 @@ macro_rules! impl_traits {
|
|||||||
unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, RuntimeError> {
|
unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, RuntimeError> {
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
let ( $( $x ),* ) = self;
|
let ( $( $x ),* ) = self;
|
||||||
let args = [ $( $x.to_native().to_bits() ),* ];
|
let args = [ $( $x.to_native().to_binary()),* ];
|
||||||
let mut rets = Rets::empty_ret_array();
|
let mut rets = Rets::empty_ret_array();
|
||||||
let mut trap = WasmTrapInfo::Unknown;
|
let mut trap = WasmTrapInfo::Unknown;
|
||||||
let mut user_error = None;
|
let mut user_error = None;
|
||||||
|
@ -76,44 +76,44 @@ where
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
const TYPE: Type;
|
const TYPE: Type;
|
||||||
fn from_bits(bits: u64) -> Self;
|
fn from_binary(bits: u64) -> Self;
|
||||||
fn to_bits(self) -> u64;
|
fn to_binary(self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl NativeWasmType for i32 {
|
unsafe impl NativeWasmType for i32 {
|
||||||
const TYPE: Type = Type::I32;
|
const TYPE: Type = Type::I32;
|
||||||
fn from_bits(bits: u64) -> Self {
|
fn from_binary(bits: u64) -> Self {
|
||||||
bits as _
|
bits as _
|
||||||
}
|
}
|
||||||
fn to_bits(self) -> u64 {
|
fn to_binary(self) -> u64 {
|
||||||
self as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl NativeWasmType for i64 {
|
unsafe impl NativeWasmType for i64 {
|
||||||
const TYPE: Type = Type::I64;
|
const TYPE: Type = Type::I64;
|
||||||
fn from_bits(bits: u64) -> Self {
|
fn from_binary(bits: u64) -> Self {
|
||||||
bits as _
|
bits as _
|
||||||
}
|
}
|
||||||
fn to_bits(self) -> u64 {
|
fn to_binary(self) -> u64 {
|
||||||
self as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl NativeWasmType for f32 {
|
unsafe impl NativeWasmType for f32 {
|
||||||
const TYPE: Type = Type::F32;
|
const TYPE: Type = Type::F32;
|
||||||
fn from_bits(bits: u64) -> Self {
|
fn from_binary(bits: u64) -> Self {
|
||||||
bits as _
|
f32::from_bits(bits as u32)
|
||||||
}
|
}
|
||||||
fn to_bits(self) -> u64 {
|
fn to_binary(self) -> u64 {
|
||||||
self as _
|
self.to_bits() as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl NativeWasmType for f64 {
|
unsafe impl NativeWasmType for f64 {
|
||||||
const TYPE: Type = Type::F64;
|
const TYPE: Type = Type::F64;
|
||||||
fn from_bits(bits: u64) -> Self {
|
fn from_binary(bits: u64) -> Self {
|
||||||
bits as _
|
f64::from_bits(bits)
|
||||||
}
|
}
|
||||||
fn to_bits(self) -> u64 {
|
fn to_binary(self) -> u64 {
|
||||||
self as _
|
self.to_bits()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,3 +516,58 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::types::NativeWasmType;
|
||||||
|
use crate::types::WasmExternType;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_native_types_round_trip() {
|
||||||
|
assert_eq!(
|
||||||
|
42i32,
|
||||||
|
i32::from_native(i32::from_binary((42i32).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
-42i32,
|
||||||
|
i32::from_native(i32::from_binary((-42i32).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
use std::i64;
|
||||||
|
let xi64 = i64::MAX;
|
||||||
|
assert_eq!(
|
||||||
|
xi64,
|
||||||
|
i64::from_native(i64::from_binary((xi64).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
let yi64 = i64::MIN;
|
||||||
|
assert_eq!(
|
||||||
|
yi64,
|
||||||
|
i64::from_native(i64::from_binary((yi64).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
16.5f32,
|
||||||
|
f32::from_native(f32::from_binary((16.5f32).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
-16.5f32,
|
||||||
|
f32::from_native(f32::from_binary((-16.5f32).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
use std::f64;
|
||||||
|
let xf64: f64 = f64::MAX;
|
||||||
|
assert_eq!(
|
||||||
|
xf64,
|
||||||
|
f64::from_native(f64::from_binary((xf64).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
|
||||||
|
let yf64: f64 = f64::MIN;
|
||||||
|
assert_eq!(
|
||||||
|
yf64,
|
||||||
|
f64::from_native(f64::from_binary((yf64).to_native().to_binary()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
//! Wasmer-runtime is a library that makes embedding WebAssembly
|
//! Wasmer-runtime is a library that makes embedding WebAssembly
|
||||||
//! in your application easy, efficient, and safe.
|
//! in your application easy, efficient, and safe.
|
||||||
//!
|
//!
|
||||||
|
@ -212,10 +212,10 @@ impl RunnableModule for X64ExecutionContext {
|
|||||||
user_error: *mut Option<Box<dyn Any>>,
|
user_error: *mut Option<Box<dyn Any>>,
|
||||||
num_params_plus_one: Option<NonNull<c_void>>,
|
num_params_plus_one: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let rm: &Box<dyn RunnableModule> = &unsafe { &*(*ctx).module }.runnable_module;
|
let rm: &Box<dyn RunnableModule> = &(&*(*ctx).module).runnable_module;
|
||||||
let execution_context = unsafe {
|
let execution_context =
|
||||||
::std::mem::transmute_copy::<&dyn RunnableModule, &X64ExecutionContext>(&&**rm)
|
::std::mem::transmute_copy::<&dyn RunnableModule, &X64ExecutionContext>(&&**rm);
|
||||||
};
|
|
||||||
let args = ::std::slice::from_raw_parts(
|
let args = ::std::slice::from_raw_parts(
|
||||||
args,
|
args,
|
||||||
num_params_plus_one.unwrap().as_ptr() as usize - 1,
|
num_params_plus_one.unwrap().as_ptr() as usize - 1,
|
||||||
@ -478,7 +478,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn from_cache(artifact: Artifact, _: Token) -> Result<ModuleInner, CacheError> {
|
unsafe fn from_cache(_artifact: Artifact, _: Token) -> Result<ModuleInner, CacheError> {
|
||||||
Err(CacheError::Unknown(
|
Err(CacheError::Unknown(
|
||||||
"the singlepass compiler API doesn't support caching yet".to_string(),
|
"the singlepass compiler API doesn't support caching yet".to_string(),
|
||||||
))
|
))
|
||||||
@ -1409,7 +1409,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_body(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
fn begin_body(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||||
let a = self.assembler.as_mut().unwrap();
|
let a = self.assembler.as_mut().unwrap();
|
||||||
a.emit_push(Size::S64, Location::GPR(GPR::RBP));
|
a.emit_push(Size::S64, Location::GPR(GPR::RBP));
|
||||||
a.emit_mov(Size::S64, Location::GPR(GPR::RSP), Location::GPR(GPR::RBP));
|
a.emit_mov(Size::S64, Location::GPR(GPR::RSP), Location::GPR(GPR::RBP));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
#![feature(proc_macro_hygiene)]
|
#![feature(proc_macro_hygiene)]
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ pub fn fd_allocate(
|
|||||||
len: __wasi_filesize_t,
|
len: __wasi_filesize_t,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::fd_allocate");
|
debug!("wasi::fd_allocate");
|
||||||
unimplemented!()
|
unimplemented!("wasi::fd_allocate")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `fd_close()`
|
/// ### `fd_close()`
|
||||||
@ -434,7 +434,7 @@ pub fn fd_filestat_set_size(
|
|||||||
st_size: __wasi_filesize_t,
|
st_size: __wasi_filesize_t,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::fd_filestat_set_size");
|
debug!("wasi::fd_filestat_set_size");
|
||||||
unimplemented!()
|
unimplemented!("wasi::fd_filestat_set_size")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `fd_filestat_set_times()`
|
/// ### `fd_filestat_set_times()`
|
||||||
@ -474,14 +474,14 @@ pub fn fd_filestat_set_times(
|
|||||||
inode.stat.st_atim = st_atim;
|
inode.stat.st_atim = st_atim;
|
||||||
} else if fst_flags & __WASI_FILESTAT_SET_ATIM_NOW != 0 {
|
} else if fst_flags & __WASI_FILESTAT_SET_ATIM_NOW != 0 {
|
||||||
// set to current real time
|
// set to current real time
|
||||||
unimplemented!();
|
unimplemented!("Set filestat time to the current real time");
|
||||||
}
|
}
|
||||||
|
|
||||||
if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 {
|
if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 {
|
||||||
inode.stat.st_mtim = st_mtim;
|
inode.stat.st_mtim = st_mtim;
|
||||||
} else if fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 {
|
} else if fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 {
|
||||||
// set to current real time
|
// set to current real time
|
||||||
unimplemented!();
|
unimplemented!("Set filestat time to the current real time");
|
||||||
}
|
}
|
||||||
|
|
||||||
__WASI_ESUCCESS
|
__WASI_ESUCCESS
|
||||||
@ -501,7 +501,7 @@ pub fn fd_pread(
|
|||||||
let iov_cells = wasi_try!(iovs.deref(memory, 0, iovs_len));
|
let iov_cells = wasi_try!(iovs.deref(memory, 0, iovs_len));
|
||||||
let nread_cell = wasi_try!(nread.deref(memory));
|
let nread_cell = wasi_try!(nread.deref(memory));
|
||||||
|
|
||||||
unimplemented!();
|
unimplemented!("wasi::fd_pread");
|
||||||
|
|
||||||
__WASI_ESUCCESS
|
__WASI_ESUCCESS
|
||||||
}
|
}
|
||||||
@ -637,7 +637,7 @@ pub fn fd_pwrite(
|
|||||||
// TODO: verify
|
// TODO: verify
|
||||||
return __WASI_EISDIR;
|
return __WASI_EISDIR;
|
||||||
}
|
}
|
||||||
Kind::Symlink { .. } => unimplemented!(),
|
Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_pwrite"),
|
||||||
Kind::Buffer { buffer } => wasi_try!(write_bytes(
|
Kind::Buffer { buffer } => wasi_try!(write_bytes(
|
||||||
&mut buffer[(offset as usize)..],
|
&mut buffer[(offset as usize)..],
|
||||||
memory,
|
memory,
|
||||||
@ -725,7 +725,7 @@ pub fn fd_read(
|
|||||||
// TODO: verify
|
// TODO: verify
|
||||||
return __WASI_EISDIR;
|
return __WASI_EISDIR;
|
||||||
}
|
}
|
||||||
Kind::Symlink { .. } => unimplemented!(),
|
Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_read"),
|
||||||
Kind::Buffer { buffer } => {
|
Kind::Buffer { buffer } => {
|
||||||
wasi_try!(read_bytes(&buffer[offset..], memory, iovs_arr_cell))
|
wasi_try!(read_bytes(&buffer[offset..], memory, iovs_arr_cell))
|
||||||
}
|
}
|
||||||
@ -771,7 +771,7 @@ pub fn fd_readdir(
|
|||||||
if let (Ok(buf_arr_cell), Ok(bufused_cell)) =
|
if let (Ok(buf_arr_cell), Ok(bufused_cell)) =
|
||||||
(buf.deref(memory, 0, buf_len), bufused.deref(memory))
|
(buf.deref(memory, 0, buf_len), bufused.deref(memory))
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!("wasi::fd_readdir")
|
||||||
} else {
|
} else {
|
||||||
__WASI_EFAULT
|
__WASI_EFAULT
|
||||||
}
|
}
|
||||||
@ -833,7 +833,7 @@ pub fn fd_seek(
|
|||||||
// TODO: handle case if fd is a dir?
|
// TODO: handle case if fd is a dir?
|
||||||
match whence {
|
match whence {
|
||||||
__WASI_WHENCE_CUR => fd_entry.offset = (fd_entry.offset as i64 + offset) as u64,
|
__WASI_WHENCE_CUR => fd_entry.offset = (fd_entry.offset as i64 + offset) as u64,
|
||||||
__WASI_WHENCE_END => unimplemented!(),
|
__WASI_WHENCE_END => unimplemented!("__WASI__WHENCE_END in wasi::fd_seek"),
|
||||||
__WASI_WHENCE_SET => fd_entry.offset = offset as u64,
|
__WASI_WHENCE_SET => fd_entry.offset = offset as u64,
|
||||||
_ => return __WASI_EINVAL,
|
_ => return __WASI_EINVAL,
|
||||||
}
|
}
|
||||||
@ -855,7 +855,7 @@ pub fn fd_seek(
|
|||||||
pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
|
pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
|
||||||
debug!("wasi::fd_sync");
|
debug!("wasi::fd_sync");
|
||||||
// TODO: check __WASI_RIGHT_FD_SYNC
|
// TODO: check __WASI_RIGHT_FD_SYNC
|
||||||
unimplemented!()
|
unimplemented!("wasi::fd_sync")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `fd_tell()`
|
/// ### `fd_tell()`
|
||||||
@ -950,7 +950,7 @@ pub fn fd_write(
|
|||||||
// TODO: verify
|
// TODO: verify
|
||||||
return __WASI_EISDIR;
|
return __WASI_EISDIR;
|
||||||
}
|
}
|
||||||
Kind::Symlink { .. } => unimplemented!(),
|
Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_write"),
|
||||||
Kind::Buffer { buffer } => {
|
Kind::Buffer { buffer } => {
|
||||||
wasi_try!(write_bytes(&mut buffer[offset..], memory, iovs_arr_cell))
|
wasi_try!(write_bytes(&mut buffer[offset..], memory, iovs_arr_cell))
|
||||||
}
|
}
|
||||||
@ -987,8 +987,62 @@ pub fn path_create_directory(
|
|||||||
path_len: u32,
|
path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_create_directory");
|
debug!("wasi::path_create_directory");
|
||||||
// check __WASI_RIGHT_PATH_CREATE_DIRECTORY
|
let memory = ctx.memory(0);
|
||||||
unimplemented!()
|
let state = get_wasi_state(ctx);
|
||||||
|
|
||||||
|
let working_dir = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF));
|
||||||
|
if !has_rights(working_dir.rights, __WASI_RIGHT_PATH_CREATE_DIRECTORY) {
|
||||||
|
return __WASI_EACCES;
|
||||||
|
}
|
||||||
|
let path_cells = wasi_try!(path.deref(memory, 0, path_len));
|
||||||
|
let path_string =
|
||||||
|
wasi_try!(
|
||||||
|
std::str::from_utf8(unsafe { &*(path_cells as *const [_] as *const [u8]) })
|
||||||
|
.map_err(|_| __WASI_EINVAL)
|
||||||
|
);
|
||||||
|
debug!("=> path: {}", &path_string);
|
||||||
|
|
||||||
|
let path = std::path::PathBuf::from(path_string);
|
||||||
|
let path_vec = wasi_try!(path
|
||||||
|
.components()
|
||||||
|
.map(|comp| {
|
||||||
|
comp.as_os_str()
|
||||||
|
.to_str()
|
||||||
|
.map(|inner_str| inner_str.to_string())
|
||||||
|
.ok_or(__WASI_EINVAL)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<String>, __wasi_errno_t>>());
|
||||||
|
if path_vec.is_empty() {
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
path_vec.len() == 1,
|
||||||
|
"path_create_directory for paths greater than depth 1 has not been implemented because our WASI FS abstractions are a work in progress. We apologize for the inconvenience"
|
||||||
|
);
|
||||||
|
debug!("Path vec: {:#?}", path_vec);
|
||||||
|
|
||||||
|
wasi_try!(std::fs::create_dir(&path).map_err(|_| __WASI_EIO));
|
||||||
|
|
||||||
|
let kind = Kind::Dir {
|
||||||
|
//parent: Some(working_dir.inode),
|
||||||
|
path: path.clone(),
|
||||||
|
entries: Default::default(),
|
||||||
|
};
|
||||||
|
let new_inode = state.fs.inodes.insert(InodeVal {
|
||||||
|
stat: __wasi_filestat_t::default(),
|
||||||
|
is_preopened: false,
|
||||||
|
name: path_vec[0].clone(),
|
||||||
|
kind,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Kind::Dir { entries, .. } = &mut state.fs.inodes[working_dir.inode].kind {
|
||||||
|
entries.insert(path_vec[0].clone(), new_inode);
|
||||||
|
} else {
|
||||||
|
return __WASI_ENOTDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
__WASI_ESUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `path_filestat_get()`
|
/// ### `path_filestat_get()`
|
||||||
@ -1023,32 +1077,71 @@ pub fn path_filestat_get(
|
|||||||
return __WASI_EACCES;
|
return __WASI_EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path_vec = wasi_try!(::std::str::from_utf8(unsafe {
|
let path_string = wasi_try!(::std::str::from_utf8(unsafe {
|
||||||
&*(wasi_try!(path.deref(memory, 0, path_len)) as *const [_] as *const [u8])
|
&*(wasi_try!(path.deref(memory, 0, path_len)) as *const [_] as *const [u8])
|
||||||
})
|
})
|
||||||
.map_err(|_| __WASI_EINVAL))
|
.map_err(|_| __WASI_EINVAL));
|
||||||
.split('/')
|
debug!("=> path: {}", &path_string);
|
||||||
.map(|str| str.to_string())
|
let path = std::path::PathBuf::from(path_string);
|
||||||
|
let path_vec = path
|
||||||
|
.components()
|
||||||
|
.map(|comp| comp.as_os_str().to_string_lossy().to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
let buf_cell = wasi_try!(buf.deref(memory));
|
let buf_cell = wasi_try!(buf.deref(memory));
|
||||||
|
|
||||||
|
if path_vec.is_empty() {
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
let mut cumulative_path = std::path::PathBuf::new();
|
||||||
|
|
||||||
|
debug!("=> Path vec: {:?}:", &path_vec);
|
||||||
// find the inode by traversing the path
|
// find the inode by traversing the path
|
||||||
let mut inode = root_dir.inode;
|
let mut inode = root_dir.inode;
|
||||||
'outer: for segment in path_vec {
|
'outer: for segment in &path_vec[..(path_vec.len() - 1)] {
|
||||||
// loop to traverse symlinks
|
// loop to traverse symlinks
|
||||||
// TODO: proper cycle detection
|
// TODO: proper cycle detection
|
||||||
let mut sym_count = 0;
|
let mut sym_count = 0;
|
||||||
loop {
|
loop {
|
||||||
match &state.fs.inodes[inode].kind {
|
match &state.fs.inodes[inode].kind {
|
||||||
Kind::Dir { entries, .. } => {
|
Kind::Dir { entries, .. } => {
|
||||||
if let Some(entry) = entries.get(&segment) {
|
cumulative_path.push(&segment);
|
||||||
|
if let Some(entry) = entries.get(segment) {
|
||||||
|
debug!("Entry {:?} found", &segment);
|
||||||
inode = entry.clone();
|
inode = entry.clone();
|
||||||
continue 'outer;
|
|
||||||
} else {
|
} else {
|
||||||
return __WASI_ENOENT;
|
// lazily load
|
||||||
|
debug!("Lazily loading entry {:?}", &segment);
|
||||||
|
let path_metadata =
|
||||||
|
wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_ENOENT));
|
||||||
|
if !path_metadata.is_dir() {
|
||||||
|
// TODO: should this just return invalid arg?
|
||||||
|
return __WASI_ENOTDIR;
|
||||||
}
|
}
|
||||||
|
let kind = Kind::Dir {
|
||||||
|
path: std::path::PathBuf::from(&segment),
|
||||||
|
entries: Default::default(),
|
||||||
|
};
|
||||||
|
let inode_val = InodeVal::from_file_metadata(
|
||||||
|
&path_metadata,
|
||||||
|
segment.clone(),
|
||||||
|
false,
|
||||||
|
kind,
|
||||||
|
);
|
||||||
|
let new_inode = state.fs.inodes.insert(inode_val);
|
||||||
|
let inode_idx = state.fs.inode_counter.get();
|
||||||
|
state.fs.inode_counter.replace(inode_idx + 1);
|
||||||
|
if let Kind::Dir { entries, .. } = &mut state.fs.inodes[inode].kind {
|
||||||
|
// check that we're not displacing any entries
|
||||||
|
assert!(entries.insert(segment.clone(), new_inode).is_none());
|
||||||
|
state.fs.inodes[new_inode].stat.st_ino = state.fs.inode_counter.get();
|
||||||
|
inode = new_inode;
|
||||||
|
}
|
||||||
|
debug!("Directory {:#?} lazily loaded", &cumulative_path);
|
||||||
|
}
|
||||||
|
continue 'outer;
|
||||||
}
|
}
|
||||||
Kind::Symlink { forwarded } => {
|
Kind::Symlink { forwarded } => {
|
||||||
|
// TODO: updated cumulative path
|
||||||
sym_count += 1;
|
sym_count += 1;
|
||||||
inode = forwarded.clone();
|
inode = forwarded.clone();
|
||||||
if sym_count > MAX_SYMLINKS {
|
if sym_count > MAX_SYMLINKS {
|
||||||
@ -1062,7 +1155,62 @@ pub fn path_filestat_get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let stat = state.fs.inodes[inode].stat;
|
let final_inode = match &state.fs.inodes[inode].kind {
|
||||||
|
Kind::Dir { path, entries, .. } => {
|
||||||
|
// TODO: fail earlier if size 0
|
||||||
|
let last_segment = path_vec.last().unwrap();
|
||||||
|
cumulative_path.push(last_segment);
|
||||||
|
|
||||||
|
if entries.contains_key(last_segment) {
|
||||||
|
entries[last_segment]
|
||||||
|
} else {
|
||||||
|
// lazily load it if we can
|
||||||
|
if !cumulative_path.exists() {
|
||||||
|
return __WASI_ENOENT;
|
||||||
|
}
|
||||||
|
let final_path_metadata =
|
||||||
|
wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_EIO));
|
||||||
|
let new_inode = if final_path_metadata.is_dir() {
|
||||||
|
debug!("Opening host directory {:#?}", &cumulative_path);
|
||||||
|
state.fs.inodes.insert(InodeVal {
|
||||||
|
stat: __wasi_filestat_t::default(),
|
||||||
|
is_preopened: false, // is this correct?
|
||||||
|
name: last_segment.clone(),
|
||||||
|
kind: Kind::Dir {
|
||||||
|
path: std::path::PathBuf::from(&last_segment),
|
||||||
|
entries: Default::default(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
debug!("Opening host file {:#?}", &cumulative_path);
|
||||||
|
let real_open_file = wasi_try!(std::fs::OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.open(&cumulative_path)
|
||||||
|
.map_err(|_| __WASI_ENOENT));
|
||||||
|
|
||||||
|
state.fs.inodes.insert(InodeVal {
|
||||||
|
stat: __wasi_filestat_t::default(),
|
||||||
|
is_preopened: false, // is this correct?
|
||||||
|
name: last_segment.clone(),
|
||||||
|
kind: Kind::File {
|
||||||
|
handle: WasiFile::HostFile(real_open_file),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
// reborrow to insert entry
|
||||||
|
if let Kind::Dir { entries, .. } = &mut state.fs.inodes[inode].kind {
|
||||||
|
entries.insert(last_segment.clone(), new_inode);
|
||||||
|
}
|
||||||
|
new_inode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return __WASI_ENOTDIR;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let stat = state.fs.inodes[final_inode].stat;
|
||||||
|
|
||||||
buf_cell.set(stat);
|
buf_cell.set(stat);
|
||||||
|
|
||||||
@ -1097,7 +1245,7 @@ pub fn path_filestat_set_times(
|
|||||||
fst_flags: __wasi_fstflags_t,
|
fst_flags: __wasi_fstflags_t,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_filestat_set_times");
|
debug!("wasi::path_filestat_set_times");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_filestat_set_times")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `path_link()`
|
/// ### `path_link()`
|
||||||
@ -1128,7 +1276,7 @@ pub fn path_link(
|
|||||||
new_path_len: u32,
|
new_path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_link");
|
debug!("wasi::path_link");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_link")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `path_open()`
|
/// ### `path_open()`
|
||||||
@ -1221,6 +1369,7 @@ pub fn path_open(
|
|||||||
match &state.fs.inodes[cur_dir_inode].kind {
|
match &state.fs.inodes[cur_dir_inode].kind {
|
||||||
Kind::Dir { entries, .. } => {
|
Kind::Dir { entries, .. } => {
|
||||||
if let Some(child) = entries.get(path_segment) {
|
if let Some(child) = entries.get(path_segment) {
|
||||||
|
cumulative_path.push(path_segment);
|
||||||
let inode_val = *child;
|
let inode_val = *child;
|
||||||
cur_dir_inode = inode_val;
|
cur_dir_inode = inode_val;
|
||||||
} else {
|
} else {
|
||||||
@ -1376,7 +1525,7 @@ pub fn path_readlink(
|
|||||||
bufused: WasmPtr<u32>,
|
bufused: WasmPtr<u32>,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_readlink");
|
debug!("wasi::path_readlink");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_readlink")
|
||||||
}
|
}
|
||||||
pub fn path_remove_directory(
|
pub fn path_remove_directory(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1385,7 +1534,7 @@ pub fn path_remove_directory(
|
|||||||
path_len: u32,
|
path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_remove_directory");
|
debug!("wasi::path_remove_directory");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_remove_directory")
|
||||||
}
|
}
|
||||||
pub fn path_rename(
|
pub fn path_rename(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1397,7 +1546,7 @@ pub fn path_rename(
|
|||||||
new_path_len: u32,
|
new_path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_rename");
|
debug!("wasi::path_rename");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_rename")
|
||||||
}
|
}
|
||||||
pub fn path_symlink(
|
pub fn path_symlink(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1408,7 +1557,7 @@ pub fn path_symlink(
|
|||||||
new_path_len: u32,
|
new_path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_symlink");
|
debug!("wasi::path_symlink");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_symlink")
|
||||||
}
|
}
|
||||||
pub fn path_unlink_file(
|
pub fn path_unlink_file(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1417,7 +1566,7 @@ pub fn path_unlink_file(
|
|||||||
path_len: u32,
|
path_len: u32,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::path_unlink_file");
|
debug!("wasi::path_unlink_file");
|
||||||
unimplemented!()
|
unimplemented!("wasi::path_unlink_file")
|
||||||
}
|
}
|
||||||
pub fn poll_oneoff(
|
pub fn poll_oneoff(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1427,7 +1576,7 @@ pub fn poll_oneoff(
|
|||||||
nevents: WasmPtr<u32>,
|
nevents: WasmPtr<u32>,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::poll_oneoff");
|
debug!("wasi::poll_oneoff");
|
||||||
unimplemented!()
|
unimplemented!("wasi::poll_oneoff")
|
||||||
}
|
}
|
||||||
pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result<Infallible, ExitCode> {
|
pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result<Infallible, ExitCode> {
|
||||||
debug!("wasi::proc_exit, {}", code);
|
debug!("wasi::proc_exit, {}", code);
|
||||||
@ -1435,7 +1584,7 @@ pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result<Infallible, E
|
|||||||
}
|
}
|
||||||
pub fn proc_raise(ctx: &mut Ctx, sig: __wasi_signal_t) -> __wasi_errno_t {
|
pub fn proc_raise(ctx: &mut Ctx, sig: __wasi_signal_t) -> __wasi_errno_t {
|
||||||
debug!("wasi::proc_raise");
|
debug!("wasi::proc_raise");
|
||||||
unimplemented!()
|
unimplemented!("wasi::proc_raise")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### `random_get()`
|
/// ### `random_get()`
|
||||||
@ -1478,7 +1627,7 @@ pub fn sock_recv(
|
|||||||
ro_flags: WasmPtr<__wasi_roflags_t>,
|
ro_flags: WasmPtr<__wasi_roflags_t>,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::sock_recv");
|
debug!("wasi::sock_recv");
|
||||||
unimplemented!()
|
unimplemented!("wasi::sock_recv")
|
||||||
}
|
}
|
||||||
pub fn sock_send(
|
pub fn sock_send(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
@ -1489,9 +1638,9 @@ pub fn sock_send(
|
|||||||
so_datalen: WasmPtr<u32>,
|
so_datalen: WasmPtr<u32>,
|
||||||
) -> __wasi_errno_t {
|
) -> __wasi_errno_t {
|
||||||
debug!("wasi::sock_send");
|
debug!("wasi::sock_send");
|
||||||
unimplemented!()
|
unimplemented!("wasi::sock_send")
|
||||||
}
|
}
|
||||||
pub fn sock_shutdown(ctx: &mut Ctx, sock: __wasi_fd_t, how: __wasi_sdflags_t) -> __wasi_errno_t {
|
pub fn sock_shutdown(ctx: &mut Ctx, sock: __wasi_fd_t, how: __wasi_sdflags_t) -> __wasi_errno_t {
|
||||||
debug!("wasi::sock_shutdown");
|
debug!("wasi::sock_shutdown");
|
||||||
unimplemented!()
|
unimplemented!("wasi::sock_shutdown")
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::ffi::c_void;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer_runtime_core::vm::{Ctx, Func};
|
use wasmer_runtime_core::vm::{Ctx, Func};
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod exception_handling;
|
mod exception_handling;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate wasmer_runtime_core;
|
extern crate wasmer_runtime_core;
|
||||||
// extern crate wasmer_emscripten;
|
// extern crate wasmer_emscripten;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user