From 65ad316bc2cffef9598356d7db2c6eac673f51fa Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 11 Mar 2021 20:30:14 +0100 Subject: [PATCH 1/3] Export memory with updated lower limit after grow --- lib/fizzy/instantiate.cpp | 5 ++++- test/unittests/api_test.cpp | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/fizzy/instantiate.cpp b/lib/fizzy/instantiate.cpp index b77375403..fa96ba02a 100644 --- a/lib/fizzy/instantiate.cpp +++ b/lib/fizzy/instantiate.cpp @@ -558,7 +558,10 @@ std::optional find_exported_memory( if (!find_export(*instance.module, ExternalKind::Memory, name)) return std::nullopt; - return ExternalMemory{instance.memory.get(), instance.memory_limits}; + // Memory lower limit should be updated in case it was grown. + const Limits limits{ + static_cast(instance.memory->size() / PageSize), instance.memory_limits.max}; + return ExternalMemory{instance.memory.get(), limits}; } } // namespace fizzy diff --git a/test/unittests/api_test.cpp b/test/unittests/api_test.cpp index 217bf7f0b..5d0e8e2cf 100644 --- a/test/unittests/api_test.cpp +++ b/test/unittests/api_test.cpp @@ -810,3 +810,26 @@ TEST(api, find_exported_memory_reimport) // importing the same table into the module with equal limits, instantiate should succeed instantiate(parse(wasm_reimported_memory), {}, {}, {*opt_memory}); } + +TEST(api, find_exported_memory_after_grow) +{ + /* wat2wasm + (module + (memory (export "mem") 1 2) + (func (drop (memory.grow (i32.const 1)))) + ) + */ + const auto wasm = from_hex( + "0061736d0100000001040160000003020100050401010102070701036d656d02000a09010700410140001a0b"); + + auto instance = instantiate(parse(wasm)); + + EXPECT_THAT(execute(*instance, 0, {}), Result()); + + auto opt_memory = find_exported_memory(*instance, "mem"); + ASSERT_TRUE(opt_memory); + EXPECT_EQ(opt_memory->data->size(), 2 * PageSize); + EXPECT_EQ(opt_memory->limits.min, 2); + ASSERT_TRUE(opt_memory->limits.max.has_value()); + EXPECT_EQ(opt_memory->limits.max, 2); +} From 35b5ff517b6c173de5c112fe5012a16aa5ba9d2b Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 11 Mar 2021 20:33:50 +0100 Subject: [PATCH 2/3] test: import memory after it was grown --- test/unittests/api_test.cpp | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/unittests/api_test.cpp b/test/unittests/api_test.cpp index 5d0e8e2cf..de3178c47 100644 --- a/test/unittests/api_test.cpp +++ b/test/unittests/api_test.cpp @@ -833,3 +833,54 @@ TEST(api, find_exported_memory_after_grow) ASSERT_TRUE(opt_memory->limits.max.has_value()); EXPECT_EQ(opt_memory->limits.max, 2); } + +TEST(api, import_grown_memory) +{ + /* wat2wasm + (module + (memory (export "mem") 1) + (func (drop (memory.grow (i32.const 1)))) + ) + */ + const auto wasm = from_hex( + "0061736d01000000010401600000030201000503010001070701036d656d02000a09010700410140001a0b"); + + auto instance = instantiate(parse(wasm)); + + EXPECT_THAT(execute(*instance, 0, {}), Result()); + + auto memory = find_exported_memory(*instance, "mem"); + ASSERT_TRUE(memory); + EXPECT_EQ(memory->data->size(), 2 * PageSize); + EXPECT_EQ(memory->limits.min, 2); + ASSERT_FALSE(memory->limits.max.has_value()); + + /* wat2wasm + (module + (memory (export "mem2") (import "m" "mem") 2) + (func (drop (memory.grow (i32.const 1)))) + ) + */ + const auto wasm_reexported_mem = from_hex( + "0061736d01000000010401600000020a01016d036d656d02000203020100070801046d656d3202000a09010700" + "410140001a0b"); + + auto instance_reexported_mem = instantiate(parse(wasm_reexported_mem), {}, {}, {*memory}); + + EXPECT_THAT(execute(*instance_reexported_mem, 0, {}), Result()); + + auto reexported_memory = find_exported_memory(*instance_reexported_mem, "mem2"); + ASSERT_TRUE(reexported_memory); + EXPECT_EQ(reexported_memory->data->size(), 3 * PageSize); + EXPECT_EQ(reexported_memory->limits.min, 3); + ASSERT_FALSE(reexported_memory->limits.max.has_value()); + + /* wat2wasm + (module + (memory (import "m" "mem2") 2) + ) + */ + const auto wasm_imported_mem = from_hex("0061736d01000000020b01016d046d656d32020002"); + + EXPECT_NO_THROW(instantiate(parse(wasm_imported_mem), {}, {}, {*reexported_memory})); +} From ed9f106dc89d94e7d9cc74f1ffd7d6bcf09e8026 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Tue, 16 Mar 2021 19:36:18 +0100 Subject: [PATCH 3/3] Require in instantiate for imported memory size to be equal min limit --- lib/fizzy/instantiate.cpp | 4 ++-- test/unittests/instantiate_test.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/fizzy/instantiate.cpp b/lib/fizzy/instantiate.cpp index fa96ba02a..c919a1a1c 100644 --- a/lib/fizzy/instantiate.cpp +++ b/lib/fizzy/instantiate.cpp @@ -121,9 +121,9 @@ void match_imported_memories(const std::vector& module_imported_memories const auto min = imported_memories[0].limits.min; const auto& max = imported_memories[0].limits.max; - if (size < memory_pages_to_bytes(min) || + if (size != memory_pages_to_bytes(min) || (max.has_value() && size > memory_pages_to_bytes(*max))) - throw instantiate_error{"provided imported memory doesn't fit provided limits"}; + throw instantiate_error{"provided imported memory size must be equal to its min limit"}; } } diff --git a/test/unittests/instantiate_test.cpp b/test/unittests/instantiate_test.cpp index 7fc0ca23c..f0a926992 100644 --- a/test/unittests/instantiate_test.cpp +++ b/test/unittests/instantiate_test.cpp @@ -302,12 +302,12 @@ TEST(instantiate, imported_memory_invalid) // Allocated less than min EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_empty, {1, 3}}}), instantiate_error, - "provided imported memory doesn't fit provided limits"); + "provided imported memory size must be equal to its min limit"); - // Allocated more than max - bytes memory_big(PageSize * 4, 0); - EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_big, {1, 3}}}), instantiate_error, - "provided imported memory doesn't fit provided limits"); + // Allocated more than min but less than max + bytes memory_two_pages(PageSize * 2, 0); + EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_two_pages, {1, 3}}}), + instantiate_error, "provided imported memory size must be equal to its min limit"); // Provided max exceeds the hard limit /* wat2wasm