Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 86e996d

Browse files
Merge branch 'next' into feat/simd
2 parents b643e90 + 1252a89 commit 86e996d

File tree

11 files changed

+145
-90
lines changed

11 files changed

+145
-90
lines changed

Cargo.lock

Lines changed: 65 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414

1515
- **Tiny**: TinyWasm is designed to be as small as possible without significantly compromising performance or functionality (< 4000 LLOC).
1616
- **Portable**: TinyWasm runs on any platform that Rust can target, including `no_std`, with minimal external dependencies.
17-
- **Safe**: No unsafe code is used in the runtime (`rkyv`, which uses unsafe code, can be used for serialization but is optional).
17+
- **Safe**: No unsafe code is used in the runtime
1818

19-
## Status
19+
## Current Status
2020

21-
TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite](https://github.com/WebAssembly/testsuite) and is able to run most WebAssembly programs. Additionally, the current 2.0 Draft is mostly supported, with the exception of Fixed-Width SIMD and Memory64/Multiple Memories. See the [Supported Proposals](#supported-proposals) section for more information.
21+
TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite](https://github.com/WebAssembly/testsuite) and is able to run most WebAssembly programs. Additionally, the current 2.0 WebAssembly is mostly supported, with the exception of the SIMD and Memory64 proposals. See the [Supported Proposals](#supported-proposals) section for more information.
22+
23+
## Safety
24+
25+
Safety wise, TinyWasm doesn't use any unsafe code and is designed to be completly memory-safe. Untrusted WebAssembly code should not be able to crash the runtime or access memory outside of its sandbox, however currently there is no protection against infinite loops or excessive memory usage. Unvalidated Wasm and untrusted, precompilled twasm bytecode is safe to run too but can crash the runtime.
2226

2327
## Supported Proposals
2428

@@ -38,7 +42,7 @@ TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite](
3842
| [**Multiple Memories**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 |
3943
| [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | `next` |
4044
| [**Tail Call**](https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md) | 🟢 | `next` |
41-
| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🚧 | N/A |
45+
| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🟢 | `next` |
4246
| [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🚧 | N/A |
4347

4448
## Usage

crates/tinywasm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false
2020
libm={version="0.2", default-features=false}
2121

2222
[dev-dependencies]
23-
wasm-testsuite={version="0.4.5"}
23+
wasm-testsuite={version="0.5.0"}
2424
indexmap="2.7"
2525
wast={workspace=true}
2626
wat={workspace=true}

crates/tinywasm/src/interpreter/executor.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -709,16 +709,31 @@ impl<'store, 'stack> Executor<'store, 'stack> {
709709

710710
fn exec_memory_size(&mut self, addr: u32) {
711711
let mem = self.store.get_mem(self.module.resolve_mem_addr(addr));
712-
self.stack.values.push::<i32>(mem.page_count as i32);
712+
713+
match mem.is_64bit() {
714+
true => self.stack.values.push::<i64>(mem.page_count as i64),
715+
false => self.stack.values.push::<i32>(mem.page_count as i32),
716+
}
713717
}
714718
fn exec_memory_grow(&mut self, addr: u32) {
715719
let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(addr));
716-
let prev_size = mem.page_count as i32;
717-
let pages_delta = self.stack.values.pop::<i32>();
718-
self.stack.values.push::<i32>(match mem.grow(pages_delta) {
719-
Some(_) => prev_size,
720-
None => -1,
721-
});
720+
let prev_size = mem.page_count;
721+
722+
let pages_delta = match mem.is_64bit() {
723+
true => self.stack.values.pop::<i64>(),
724+
false => self.stack.values.pop::<i32>() as i64,
725+
};
726+
727+
match (
728+
mem.is_64bit(),
729+
match mem.grow(pages_delta) {
730+
Some(_) => prev_size as i64,
731+
None => -1_i64,
732+
},
733+
) {
734+
(true, size) => self.stack.values.push::<i64>(size),
735+
(false, size) => self.stack.values.push::<i32>(size as i32),
736+
};
722737
}
723738

724739
fn exec_memory_copy(&mut self, from: u32, to: u32) -> Result<()> {
@@ -796,14 +811,13 @@ impl<'store, 'stack> Executor<'store, 'stack> {
796811
dst as usize,
797812
src as usize,
798813
size as usize,
799-
)?;
814+
)
800815
} else {
801816
// copy between two memories
802817
let (table_from, table_to) =
803818
self.store.get_tables_mut(self.module.resolve_table_addr(from), self.module.resolve_table_addr(to))?;
804-
table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?)?;
819+
table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?)
805820
}
806-
Ok(())
807821
}
808822

809823
fn exec_mem_load_lane<
@@ -854,11 +868,16 @@ impl<'store, 'stack> Executor<'store, 'stack> {
854868
cast: fn(LOAD) -> TARGET,
855869
) -> ControlFlow<Option<Error>> {
856870
let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr));
857-
let val = self.stack.values.pop::<i32>() as u64;
858-
let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else {
871+
872+
let addr = match mem.is_64bit() {
873+
true => self.stack.values.pop::<i64>() as u64,
874+
false => self.stack.values.pop::<i32>() as u32 as u64,
875+
};
876+
877+
let Some(Ok(addr)) = offset.checked_add(addr).map(TryInto::try_into) else {
859878
cold();
860879
return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds {
861-
offset: val as usize,
880+
offset: addr as usize,
862881
len: LOAD_SIZE,
863882
max: 0,
864883
})));
@@ -876,10 +895,16 @@ impl<'store, 'stack> Executor<'store, 'stack> {
876895
let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr));
877896
let val = self.stack.values.pop::<T>();
878897
let val = (cast(val)).to_mem_bytes();
879-
let addr = self.stack.values.pop::<i32>() as u64;
898+
899+
let addr = match mem.is_64bit() {
900+
true => self.stack.values.pop::<i64>() as u64,
901+
false => self.stack.values.pop::<i32>() as u32 as u64,
902+
};
903+
880904
if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) {
881905
return ControlFlow::Break(Some(e));
882906
}
907+
883908
ControlFlow::Continue(())
884909
}
885910

@@ -939,7 +964,7 @@ impl<'store, 'stack> Executor<'store, 'stack> {
939964
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
940965
};
941966

942-
table.init(dst, &items[offset as usize..(offset + size) as usize])
967+
table.init(dst as i64, &items[offset as usize..(offset + size) as usize])
943968
}
944969
fn exec_table_grow(&mut self, table_index: u32) -> Result<()> {
945970
let table = self.store.get_table_mut(self.module.resolve_table_addr(table_index));

crates/tinywasm/src/reference.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl MemoryRefMut<'_> {
5454
}
5555

5656
/// Grow the memory by the given number of pages
57-
pub fn grow(&mut self, delta_pages: i32) -> Option<i32> {
57+
pub fn grow(&mut self, delta_pages: i64) -> Option<i64> {
5858
self.0.grow(delta_pages)
5959
}
6060

0 commit comments

Comments
 (0)