Skip to content

Commit 7b700be

Browse files
authored
Merge pull request #755 from wasmx/export-grown-memory
Enforce updated lower limit of exported memory after grow
2 parents a1dd22d + ed9f106 commit 7b700be

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

lib/fizzy/instantiate.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ void match_imported_memories(const std::vector<Memory>& module_imported_memories
121121

122122
const auto min = imported_memories[0].limits.min;
123123
const auto& max = imported_memories[0].limits.max;
124-
if (size < memory_pages_to_bytes(min) ||
124+
if (size != memory_pages_to_bytes(min) ||
125125
(max.has_value() && size > memory_pages_to_bytes(*max)))
126-
throw instantiate_error{"provided imported memory doesn't fit provided limits"};
126+
throw instantiate_error{"provided imported memory size must be equal to its min limit"};
127127
}
128128
}
129129

@@ -558,7 +558,10 @@ std::optional<ExternalMemory> find_exported_memory(
558558
if (!find_export(*instance.module, ExternalKind::Memory, name))
559559
return std::nullopt;
560560

561-
return ExternalMemory{instance.memory.get(), instance.memory_limits};
561+
// Memory lower limit should be updated in case it was grown.
562+
const Limits limits{
563+
static_cast<uint32_t>(instance.memory->size() / PageSize), instance.memory_limits.max};
564+
return ExternalMemory{instance.memory.get(), limits};
562565
}
563566

564567
} // namespace fizzy

test/unittests/api_test.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -810,3 +810,77 @@ TEST(api, find_exported_memory_reimport)
810810
// importing the same table into the module with equal limits, instantiate should succeed
811811
instantiate(parse(wasm_reimported_memory), {}, {}, {*opt_memory});
812812
}
813+
814+
TEST(api, find_exported_memory_after_grow)
815+
{
816+
/* wat2wasm
817+
(module
818+
(memory (export "mem") 1 2)
819+
(func (drop (memory.grow (i32.const 1))))
820+
)
821+
*/
822+
const auto wasm = from_hex(
823+
"0061736d0100000001040160000003020100050401010102070701036d656d02000a09010700410140001a0b");
824+
825+
auto instance = instantiate(parse(wasm));
826+
827+
EXPECT_THAT(execute(*instance, 0, {}), Result());
828+
829+
auto opt_memory = find_exported_memory(*instance, "mem");
830+
ASSERT_TRUE(opt_memory);
831+
EXPECT_EQ(opt_memory->data->size(), 2 * PageSize);
832+
EXPECT_EQ(opt_memory->limits.min, 2);
833+
ASSERT_TRUE(opt_memory->limits.max.has_value());
834+
EXPECT_EQ(opt_memory->limits.max, 2);
835+
}
836+
837+
TEST(api, import_grown_memory)
838+
{
839+
/* wat2wasm
840+
(module
841+
(memory (export "mem") 1)
842+
(func (drop (memory.grow (i32.const 1))))
843+
)
844+
*/
845+
const auto wasm = from_hex(
846+
"0061736d01000000010401600000030201000503010001070701036d656d02000a09010700410140001a0b");
847+
848+
auto instance = instantiate(parse(wasm));
849+
850+
EXPECT_THAT(execute(*instance, 0, {}), Result());
851+
852+
auto memory = find_exported_memory(*instance, "mem");
853+
ASSERT_TRUE(memory);
854+
EXPECT_EQ(memory->data->size(), 2 * PageSize);
855+
EXPECT_EQ(memory->limits.min, 2);
856+
ASSERT_FALSE(memory->limits.max.has_value());
857+
858+
/* wat2wasm
859+
(module
860+
(memory (export "mem2") (import "m" "mem") 2)
861+
(func (drop (memory.grow (i32.const 1))))
862+
)
863+
*/
864+
const auto wasm_reexported_mem = from_hex(
865+
"0061736d01000000010401600000020a01016d036d656d02000203020100070801046d656d3202000a09010700"
866+
"410140001a0b");
867+
868+
auto instance_reexported_mem = instantiate(parse(wasm_reexported_mem), {}, {}, {*memory});
869+
870+
EXPECT_THAT(execute(*instance_reexported_mem, 0, {}), Result());
871+
872+
auto reexported_memory = find_exported_memory(*instance_reexported_mem, "mem2");
873+
ASSERT_TRUE(reexported_memory);
874+
EXPECT_EQ(reexported_memory->data->size(), 3 * PageSize);
875+
EXPECT_EQ(reexported_memory->limits.min, 3);
876+
ASSERT_FALSE(reexported_memory->limits.max.has_value());
877+
878+
/* wat2wasm
879+
(module
880+
(memory (import "m" "mem2") 2)
881+
)
882+
*/
883+
const auto wasm_imported_mem = from_hex("0061736d01000000020b01016d046d656d32020002");
884+
885+
EXPECT_NO_THROW(instantiate(parse(wasm_imported_mem), {}, {}, {*reexported_memory}));
886+
}

test/unittests/instantiate_test.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,12 @@ TEST(instantiate, imported_memory_invalid)
302302

303303
// Allocated less than min
304304
EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_empty, {1, 3}}}), instantiate_error,
305-
"provided imported memory doesn't fit provided limits");
305+
"provided imported memory size must be equal to its min limit");
306306

307-
// Allocated more than max
308-
bytes memory_big(PageSize * 4, 0);
309-
EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_big, {1, 3}}}), instantiate_error,
310-
"provided imported memory doesn't fit provided limits");
307+
// Allocated more than min but less than max
308+
bytes memory_two_pages(PageSize * 2, 0);
309+
EXPECT_THROW_MESSAGE(instantiate(*module, {}, {}, {{&memory_two_pages, {1, 3}}}),
310+
instantiate_error, "provided imported memory size must be equal to its min limit");
311311

312312
// Provided max exceeds the hard limit
313313
/* wat2wasm

0 commit comments

Comments
 (0)