From 1cf95dc94a791059a552653c20475f4195110e9f Mon Sep 17 00:00:00 2001 From: Veykril Date: Sun, 26 Jan 2020 22:44:59 +0100 Subject: [PATCH] Enable no_std --- Cargo.toml | 6 +++++- src/error.rs | 15 ++++++++------- src/function.rs | 16 ++++++--------- src/lib.rs | 12 ++++++++++++ src/module.rs | 46 +++++++++++++++++++++++++------------------- src/runtime.rs | 14 +++++++------- wasm3-sys/Cargo.toml | 3 +++ wasm3-sys/build.rs | 2 ++ wasm3-sys/src/lib.rs | 1 + 9 files changed, 70 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 46aa164..c12f9fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,11 @@ license = "MIT" [features] wasi = ["ffi/wasi"] -default = ["wasi"] +std = [] +default = ["wasi", "std"] + +[dependencies] +libc = "^0.2" [dependencies.ffi] path = "wasm3-sys" diff --git a/src/error.rs b/src/error.rs index b0d4457..b8ec60e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,9 @@ -use std::error; -use std::fmt; +use core::fmt; +use core::str; -pub type Result = std::result::Result; +use crate::bytes_till_null; + +pub type Result = core::result::Result; #[derive(Clone, Debug, PartialEq, Eq)] pub enum Error { @@ -16,15 +18,14 @@ impl Error { if ptr.is_null() { Ok(()) } else { - Err(Error::Wasm3( - std::ffi::CStr::from_ptr(ptr).to_str().unwrap(), - )) + Err(Error::Wasm3(str::from_utf8_unchecked(bytes_till_null(ptr)))) } } } } -impl error::Error for Error {} +#[cfg(feature = "std")] +impl std::error::Error for Error {} impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/src/function.rs b/src/function.rs index a9a4fae..7a841e5 100644 --- a/src/function.rs +++ b/src/function.rs @@ -1,5 +1,7 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; +use core::str; +use crate::bytes_till_null; use crate::error::{Error, Result}; use crate::runtime::Runtime; use crate::{WasmArgs, WasmType}; @@ -51,17 +53,11 @@ where } pub fn import_module_name(&self) -> &str { - unsafe { - std::str::from_utf8_unchecked( - std::ffi::CStr::from_ptr((*self.raw).import.moduleUtf8).to_bytes(), - ) - } + unsafe { str::from_utf8_unchecked(bytes_till_null((*self.raw).import.moduleUtf8)) } } pub fn name(&self) -> &str { - unsafe { - std::str::from_utf8_unchecked(std::ffi::CStr::from_ptr((*self.raw).name).to_bytes()) - } + unsafe { str::from_utf8_unchecked(bytes_till_null((*self.raw).name)) } } fn call_impl(&self, args: ARGS) -> Result { @@ -73,7 +69,7 @@ where stack.as_mut_ptr(), self.rt.mallocated(), 666, - std::f64::NAN, + core::f64::NAN, ) }; match self.rt.rt_error() { diff --git a/src/lib.rs b/src/lib.rs index 6a9b9de..446c595 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![warn(clippy::all)] pub mod environment; pub mod error; @@ -16,3 +17,14 @@ pub fn print_m3_info() { pub fn print_profiler_info() { unsafe { ffi::m3_PrintProfilerInfo() }; } + +pub(crate) unsafe fn bytes_till_null<'a>(ptr: *const libc::c_char) -> &'a [u8] { + let start = ptr.cast::(); + let mut ptr = start; + let mut len = 0; + while *ptr != 0 { + ptr = ptr.add(1); + len += 1; + } + core::slice::from_raw_parts(start, len - 1) +} diff --git a/src/module.rs b/src/module.rs index 73b3d7a..fba4285 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1,7 +1,6 @@ -use std::cmp::Ordering; -use std::ffi::CStr; -use std::marker::PhantomData; -use std::ptr; +use core::marker::PhantomData; +use core::ptr; +use core::slice; use crate::environment::Environment; use crate::error::{Error, Result}; @@ -85,10 +84,7 @@ impl<'env, 'rt> Module<'env, 'rt> { (*m3_func).compiled = ffi::GetPagePC(page); (*m3_func).module = self.raw; ffi::EmitWord_impl(page, ffi::op_CallRawFunction as _); - ffi::EmitWord_impl( - page, - func.map(|f| f as _).unwrap_or_else(std::ptr::null_mut), - ); + ffi::EmitWord_impl(page, func.map(|f| f as _).unwrap_or_else(ptr::null_mut)); ffi::ReleaseCodePage(self.rt.as_ptr(), page); } @@ -100,10 +96,10 @@ impl<'env, 'rt> Module<'env, 'rt> { function_name: &str, ) -> Result { if let Some(func) = unsafe { - std::slice::from_raw_parts_mut((*self.raw).functions, (*self.raw).numFunctions as usize) + slice::from_raw_parts_mut((*self.raw).functions, (*self.raw).numFunctions as usize) .iter_mut() - .filter(|func| eq_cstr_str(CStr::from_ptr(func.import.moduleUtf8), module_name)) - .find(|func| eq_cstr_str(CStr::from_ptr(func.import.fieldUtf8), function_name)) + .filter(|func| eq_cstr_str(func.import.moduleUtf8, module_name)) + .find(|func| eq_cstr_str(func.import.fieldUtf8, function_name)) } { Ok(func) } else { @@ -121,16 +117,16 @@ impl<'env, 'rt> Module<'env, 'rt> { { if let Some(func) = unsafe { let functions_ptr = (*self.raw).functions; - std::slice::from_raw_parts_mut( + slice::from_raw_parts_mut( if functions_ptr.is_null() { - std::ptr::NonNull::dangling().as_ptr() + ptr::NonNull::dangling().as_ptr() } else { functions_ptr }, (*self.raw).numFunctions as usize, ) .iter_mut() - .find(|func| eq_cstr_str(CStr::from_ptr(func.name), function_name)) + .find(|func| eq_cstr_str(func.name, function_name)) } { Function::from_raw(self.rt, func).and_then(Function::compile) } else { @@ -148,12 +144,22 @@ impl<'env, 'rt> Module<'env, 'rt> { } } -fn cmp_cstr_str(cstr: &CStr, str: &str) -> Ordering { - cstr.to_bytes().iter().cmp(str.as_bytes()) -} - -fn eq_cstr_str(cstr: &CStr, str: &str) -> bool { - cmp_cstr_str(cstr, str) == Ordering::Equal +fn eq_cstr_str(cstr: *const libc::c_char, str: &str) -> bool { + if cstr.is_null() { + return str.is_empty(); + } + let mut bytes = str.as_bytes().iter(); + let mut cstr = cstr.cast::(); + loop { + match (bytes.next(), unsafe { *cstr }) { + (None, 0) => break true, + (Some(_), 0) => break false, + (Some(&byte), cbyte) if cbyte == byte => unsafe { + cstr = cstr.add(1); + }, + _ => break false, + } + } } #[test] diff --git a/src/runtime.rs b/src/runtime.rs index f87642f..b5df8ad 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -1,6 +1,6 @@ -use std::mem; -use std::ptr; -use std::slice; +use core::mem; +use core::ptr; +use core::slice; use crate::environment::Environment; use crate::error::{Error, Result}; @@ -31,7 +31,7 @@ impl<'env> Runtime<'env> { pub fn load_module<'rt>( &'rt self, module: ParsedModule<'env>, - ) -> std::result::Result, (ParsedModule<'env>, Error)> { + ) -> core::result::Result, (ParsedModule<'env>, Error)> { if let Err(err) = unsafe { Error::from_ffi_res(ffi::m3_LoadModule(self.raw, module.as_ptr())) } { @@ -83,7 +83,7 @@ impl<'env> Runtime<'env> { let ptr = ffi::m3_GetMemory(self.raw, &mut size, 0); slice::from_raw_parts( if size == 0 { - std::ptr::NonNull::dangling().as_ptr() + ptr::NonNull::dangling().as_ptr() } else { ptr }, @@ -95,7 +95,7 @@ impl<'env> Runtime<'env> { /// This function is unsafe because it allows aliasing to happen. /// The underlying memory may change if a runtimes exposed function is called. pub unsafe fn stack(&self) -> &[u64] { - std::slice::from_raw_parts( + slice::from_raw_parts( (*self.raw).stack as ffi::m3stack_t, (*self.raw).numStackSlots as usize, ) @@ -106,7 +106,7 @@ impl<'env> Runtime<'env> { /// The underlying memory may change if a runtimes exposed function is called. #[allow(clippy::mut_from_ref)] pub unsafe fn stack_mut(&self) -> &mut [u64] { - std::slice::from_raw_parts_mut( + slice::from_raw_parts_mut( (*self.raw).stack as ffi::m3stack_t, (*self.raw).numStackSlots as usize, ) diff --git a/wasm3-sys/Cargo.toml b/wasm3-sys/Cargo.toml index 9ffc424..0d976aa 100644 --- a/wasm3-sys/Cargo.toml +++ b/wasm3-sys/Cargo.toml @@ -9,6 +9,9 @@ links = "wasm3" [features] wasi = [] +[dependencies] +libc = "^0.2" + [build-dependencies] bindgen = "0.52" cc = "1" \ No newline at end of file diff --git a/wasm3-sys/build.rs b/wasm3-sys/build.rs index 6730065..ebb4cb1 100644 --- a/wasm3-sys/build.rs +++ b/wasm3-sys/build.rs @@ -8,6 +8,8 @@ fn gen_bindings() -> io::Result<()> { let whitelist_regex = "((?:I|c_)?[Mm]3.*)|.*Page.*|Module_.*|EmitWord_impl|op_CallRawFunction|Compile_Function"; let bindgen = bindgen::builder() + .use_core() + .ctypes_prefix("libc") .layout_tests(false) .generate_comments(false) .default_enum_style(bindgen::EnumVariation::ModuleConsts) diff --git a/wasm3-sys/src/lib.rs b/wasm3-sys/src/lib.rs index a38a13a..0af9da1 100644 --- a/wasm3-sys/src/lib.rs +++ b/wasm3-sys/src/lib.rs @@ -1,3 +1,4 @@ +#![no_std] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)]