Skip to content

Commit 1cf95dc

Browse files
committed
Enable no_std
1 parent 6188b2a commit 1cf95dc

File tree

9 files changed

+70
-45
lines changed

9 files changed

+70
-45
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ license = "MIT"
77

88
[features]
99
wasi = ["ffi/wasi"]
10-
default = ["wasi"]
10+
std = []
11+
default = ["wasi", "std"]
12+
13+
[dependencies]
14+
libc = "^0.2"
1115

1216
[dependencies.ffi]
1317
path = "wasm3-sys"

src/error.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use std::error;
2-
use std::fmt;
1+
use core::fmt;
2+
use core::str;
33

4-
pub type Result<T> = std::result::Result<T, Error>;
4+
use crate::bytes_till_null;
5+
6+
pub type Result<T> = core::result::Result<T, Error>;
57

68
#[derive(Clone, Debug, PartialEq, Eq)]
79
pub enum Error {
@@ -16,15 +18,14 @@ impl Error {
1618
if ptr.is_null() {
1719
Ok(())
1820
} else {
19-
Err(Error::Wasm3(
20-
std::ffi::CStr::from_ptr(ptr).to_str().unwrap(),
21-
))
21+
Err(Error::Wasm3(str::from_utf8_unchecked(bytes_till_null(ptr))))
2222
}
2323
}
2424
}
2525
}
2626

27-
impl error::Error for Error {}
27+
#[cfg(feature = "std")]
28+
impl std::error::Error for Error {}
2829
impl fmt::Display for Error {
2930
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3031
match self {

src/function.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use std::marker::PhantomData;
1+
use core::marker::PhantomData;
2+
use core::str;
23

4+
use crate::bytes_till_null;
35
use crate::error::{Error, Result};
46
use crate::runtime::Runtime;
57
use crate::{WasmArgs, WasmType};
@@ -51,17 +53,11 @@ where
5153
}
5254

5355
pub fn import_module_name(&self) -> &str {
54-
unsafe {
55-
std::str::from_utf8_unchecked(
56-
std::ffi::CStr::from_ptr((*self.raw).import.moduleUtf8).to_bytes(),
57-
)
58-
}
56+
unsafe { str::from_utf8_unchecked(bytes_till_null((*self.raw).import.moduleUtf8)) }
5957
}
6058

6159
pub fn name(&self) -> &str {
62-
unsafe {
63-
std::str::from_utf8_unchecked(std::ffi::CStr::from_ptr((*self.raw).name).to_bytes())
64-
}
60+
unsafe { str::from_utf8_unchecked(bytes_till_null((*self.raw).name)) }
6561
}
6662

6763
fn call_impl(&self, args: ARGS) -> Result<RET> {
@@ -73,7 +69,7 @@ where
7369
stack.as_mut_ptr(),
7470
self.rt.mallocated(),
7571
666,
76-
std::f64::NAN,
72+
core::f64::NAN,
7773
)
7874
};
7975
match self.rt.rt_error() {

src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![cfg_attr(not(feature = "std"), no_std)]
12
#![warn(clippy::all)]
23
pub mod environment;
34
pub mod error;
@@ -16,3 +17,14 @@ pub fn print_m3_info() {
1617
pub fn print_profiler_info() {
1718
unsafe { ffi::m3_PrintProfilerInfo() };
1819
}
20+
21+
pub(crate) unsafe fn bytes_till_null<'a>(ptr: *const libc::c_char) -> &'a [u8] {
22+
let start = ptr.cast::<u8>();
23+
let mut ptr = start;
24+
let mut len = 0;
25+
while *ptr != 0 {
26+
ptr = ptr.add(1);
27+
len += 1;
28+
}
29+
core::slice::from_raw_parts(start, len - 1)
30+
}

src/module.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use std::cmp::Ordering;
2-
use std::ffi::CStr;
3-
use std::marker::PhantomData;
4-
use std::ptr;
1+
use core::marker::PhantomData;
2+
use core::ptr;
3+
use core::slice;
54

65
use crate::environment::Environment;
76
use crate::error::{Error, Result};
@@ -85,10 +84,7 @@ impl<'env, 'rt> Module<'env, 'rt> {
8584
(*m3_func).compiled = ffi::GetPagePC(page);
8685
(*m3_func).module = self.raw;
8786
ffi::EmitWord_impl(page, ffi::op_CallRawFunction as _);
88-
ffi::EmitWord_impl(
89-
page,
90-
func.map(|f| f as _).unwrap_or_else(std::ptr::null_mut),
91-
);
87+
ffi::EmitWord_impl(page, func.map(|f| f as _).unwrap_or_else(ptr::null_mut));
9288

9389
ffi::ReleaseCodePage(self.rt.as_ptr(), page);
9490
}
@@ -100,10 +96,10 @@ impl<'env, 'rt> Module<'env, 'rt> {
10096
function_name: &str,
10197
) -> Result<ffi::IM3Function> {
10298
if let Some(func) = unsafe {
103-
std::slice::from_raw_parts_mut((*self.raw).functions, (*self.raw).numFunctions as usize)
99+
slice::from_raw_parts_mut((*self.raw).functions, (*self.raw).numFunctions as usize)
104100
.iter_mut()
105-
.filter(|func| eq_cstr_str(CStr::from_ptr(func.import.moduleUtf8), module_name))
106-
.find(|func| eq_cstr_str(CStr::from_ptr(func.import.fieldUtf8), function_name))
101+
.filter(|func| eq_cstr_str(func.import.moduleUtf8, module_name))
102+
.find(|func| eq_cstr_str(func.import.fieldUtf8, function_name))
107103
} {
108104
Ok(func)
109105
} else {
@@ -121,16 +117,16 @@ impl<'env, 'rt> Module<'env, 'rt> {
121117
{
122118
if let Some(func) = unsafe {
123119
let functions_ptr = (*self.raw).functions;
124-
std::slice::from_raw_parts_mut(
120+
slice::from_raw_parts_mut(
125121
if functions_ptr.is_null() {
126-
std::ptr::NonNull::dangling().as_ptr()
122+
ptr::NonNull::dangling().as_ptr()
127123
} else {
128124
functions_ptr
129125
},
130126
(*self.raw).numFunctions as usize,
131127
)
132128
.iter_mut()
133-
.find(|func| eq_cstr_str(CStr::from_ptr(func.name), function_name))
129+
.find(|func| eq_cstr_str(func.name, function_name))
134130
} {
135131
Function::from_raw(self.rt, func).and_then(Function::compile)
136132
} else {
@@ -148,12 +144,22 @@ impl<'env, 'rt> Module<'env, 'rt> {
148144
}
149145
}
150146

151-
fn cmp_cstr_str(cstr: &CStr, str: &str) -> Ordering {
152-
cstr.to_bytes().iter().cmp(str.as_bytes())
153-
}
154-
155-
fn eq_cstr_str(cstr: &CStr, str: &str) -> bool {
156-
cmp_cstr_str(cstr, str) == Ordering::Equal
147+
fn eq_cstr_str(cstr: *const libc::c_char, str: &str) -> bool {
148+
if cstr.is_null() {
149+
return str.is_empty();
150+
}
151+
let mut bytes = str.as_bytes().iter();
152+
let mut cstr = cstr.cast::<u8>();
153+
loop {
154+
match (bytes.next(), unsafe { *cstr }) {
155+
(None, 0) => break true,
156+
(Some(_), 0) => break false,
157+
(Some(&byte), cbyte) if cbyte == byte => unsafe {
158+
cstr = cstr.add(1);
159+
},
160+
_ => break false,
161+
}
162+
}
157163
}
158164

159165
#[test]

src/runtime.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::mem;
2-
use std::ptr;
3-
use std::slice;
1+
use core::mem;
2+
use core::ptr;
3+
use core::slice;
44

55
use crate::environment::Environment;
66
use crate::error::{Error, Result};
@@ -31,7 +31,7 @@ impl<'env> Runtime<'env> {
3131
pub fn load_module<'rt>(
3232
&'rt self,
3333
module: ParsedModule<'env>,
34-
) -> std::result::Result<Module<'env, 'rt>, (ParsedModule<'env>, Error)> {
34+
) -> core::result::Result<Module<'env, 'rt>, (ParsedModule<'env>, Error)> {
3535
if let Err(err) =
3636
unsafe { Error::from_ffi_res(ffi::m3_LoadModule(self.raw, module.as_ptr())) }
3737
{
@@ -83,7 +83,7 @@ impl<'env> Runtime<'env> {
8383
let ptr = ffi::m3_GetMemory(self.raw, &mut size, 0);
8484
slice::from_raw_parts(
8585
if size == 0 {
86-
std::ptr::NonNull::dangling().as_ptr()
86+
ptr::NonNull::dangling().as_ptr()
8787
} else {
8888
ptr
8989
},
@@ -95,7 +95,7 @@ impl<'env> Runtime<'env> {
9595
/// This function is unsafe because it allows aliasing to happen.
9696
/// The underlying memory may change if a runtimes exposed function is called.
9797
pub unsafe fn stack(&self) -> &[u64] {
98-
std::slice::from_raw_parts(
98+
slice::from_raw_parts(
9999
(*self.raw).stack as ffi::m3stack_t,
100100
(*self.raw).numStackSlots as usize,
101101
)
@@ -106,7 +106,7 @@ impl<'env> Runtime<'env> {
106106
/// The underlying memory may change if a runtimes exposed function is called.
107107
#[allow(clippy::mut_from_ref)]
108108
pub unsafe fn stack_mut(&self) -> &mut [u64] {
109-
std::slice::from_raw_parts_mut(
109+
slice::from_raw_parts_mut(
110110
(*self.raw).stack as ffi::m3stack_t,
111111
(*self.raw).numStackSlots as usize,
112112
)

wasm3-sys/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ links = "wasm3"
99
[features]
1010
wasi = []
1111

12+
[dependencies]
13+
libc = "^0.2"
14+
1215
[build-dependencies]
1316
bindgen = "0.52"
1417
cc = "1"

wasm3-sys/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ fn gen_bindings() -> io::Result<()> {
88
let whitelist_regex =
99
"((?:I|c_)?[Mm]3.*)|.*Page.*|Module_.*|EmitWord_impl|op_CallRawFunction|Compile_Function";
1010
let bindgen = bindgen::builder()
11+
.use_core()
12+
.ctypes_prefix("libc")
1113
.layout_tests(false)
1214
.generate_comments(false)
1315
.default_enum_style(bindgen::EnumVariation::ModuleConsts)

wasm3-sys/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![no_std]
12
#![allow(non_upper_case_globals)]
23
#![allow(non_camel_case_types)]
34
#![allow(non_snake_case)]

0 commit comments

Comments
 (0)