From 5d19813e63ab892c70a135575f724283540830eb Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 8 Oct 2020 17:14:45 +0200 Subject: [PATCH 1/4] fix(c-api) `wasm_limits_t` contains `Pages`, not `Bytes`. When building a `wasm_memorytype_t` with `wasm_memorytype_new`, we pass a `wasm_limits_t`, where `min` and `max` represent `Pages`. This semantics is set by `wasm_memorytype_new` itself where `min` and `max` from `wasm_limits_t` are used to compute `Pages`, which are then passed to `MemoryType`. Then, in `wasm_memorytype_limits`, we expect to get the same `wasm_limits_t` given to `wasm_memorytype_new`. But it's not! The same `MemoryType` is read, good. The `minimum` and `maximum` fields are `Pages`, good. Then, we compute the `min` and `max` values for the resulting `wasm_limits_t`, which receive `Page.bytes().0`, not good! We don't want the number of bytes, but the number of pages. This patch fixes that. --- lib/c-api/src/wasm_c_api/types/memory.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/types/memory.rs b/lib/c-api/src/wasm_c_api/types/memory.rs index 077eb772b02..ed772c0bc9f 100644 --- a/lib/c-api/src/wasm_c_api/types/memory.rs +++ b/lib/c-api/src/wasm_c_api/types/memory.rs @@ -39,6 +39,7 @@ pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box *const wasm_limits_t { let md = mt.as_memorytype(); + Box::into_raw(Box::new(wasm_limits_t { - min: md.minimum.bytes().0 as _, - max: md.maximum.map(|max| max.bytes().0 as _).unwrap_or(0), + min: md.minimum.0 as _, + max: md.maximum.map(|max| max.0 as _).unwrap_or(0), })) } From f6595cdd33ca866998822a0846dcbecc571bc5e5 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 8 Oct 2020 17:23:59 +0200 Subject: [PATCH 2/4] fix(c-api) Fix the sentinel value returned by `wasm_memorytype_limits`. --- lib/c-api/src/wasm_c_api/types/memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/types/memory.rs b/lib/c-api/src/wasm_c_api/types/memory.rs index ed772c0bc9f..a9e46e8411a 100644 --- a/lib/c-api/src/wasm_c_api/types/memory.rs +++ b/lib/c-api/src/wasm_c_api/types/memory.rs @@ -58,6 +58,6 @@ pub unsafe extern "C" fn wasm_memorytype_limits(mt: &wasm_memorytype_t) -> *cons Box::into_raw(Box::new(wasm_limits_t { min: md.minimum.0 as _, - max: md.maximum.map(|max| max.0 as _).unwrap_or(0), + max: md.maximum.map(|max| max.0 as _).unwrap_or(u32::max_value()), })) } From 80459f3ae05b7c66776400fd4facd968f1556355 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 8 Oct 2020 17:24:12 +0200 Subject: [PATCH 3/4] feat(c-api) Replace the max limit sentinel value by a constant. In the `wasm.h` header file, it is defined by `wasm_limits_max_default`. --- lib/c-api/src/wasm_c_api/types/memory.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/types/memory.rs b/lib/c-api/src/wasm_c_api/types/memory.rs index a9e46e8411a..9edd5bf37e5 100644 --- a/lib/c-api/src/wasm_c_api/types/memory.rs +++ b/lib/c-api/src/wasm_c_api/types/memory.rs @@ -30,11 +30,13 @@ pub struct wasm_limits_t { pub(crate) max: u32, } +const LIMITS_MAX_SENTINEL: u32 = u32::max_value(); + #[no_mangle] pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box { let min_pages = Pages(limits.min as _); // u32::max_value() is a sentinel value for no max specified - let max_pages = if limits.max == u32::max_value() { + let max_pages = if limits.max == LIMITS_MAX_SENTINEL { None } else { Some(Pages(limits.max as _)) @@ -58,6 +60,9 @@ pub unsafe extern "C" fn wasm_memorytype_limits(mt: &wasm_memorytype_t) -> *cons Box::into_raw(Box::new(wasm_limits_t { min: md.minimum.0 as _, - max: md.maximum.map(|max| max.0 as _).unwrap_or(u32::max_value()), + max: md + .maximum + .map(|max| max.0 as _) + .unwrap_or(LIMITS_MAX_SENTINEL), })) } From 3e77b8f2f5c295a72fcd74fa559a3736e355fec5 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 8 Oct 2020 17:27:45 +0200 Subject: [PATCH 4/4] doc(changelog) Add #1690. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b0573bd984..bd944d264b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## **[Unreleased]** +- [#1690](https://github.com/wasmerio/wasmer/pull/1690) Fix `wasm_memorytype_limits` where `min` and `max` represents pages, not bytes. Additionally, fixes the max limit sentinel value. - [#1635](https://github.com/wasmerio/wasmer/pull/1635) Implement `wat2wasm` in the Wasm C API. - [#1636](https://github.com/wasmerio/wasmer/pull/1636) Implement `wasm_module_validate` in the Wasm C API. - [#1671](https://github.com/wasmerio/wasmer/pull/1671) Fix probestack firing inappropriately, and sometimes over/under allocating stack.