Skip to content

Commit

Permalink
Merge pull request #755 from wasmx/export-grown-memory
Browse files Browse the repository at this point in the history
Enforce updated lower limit of exported memory after grow
  • Loading branch information
gumb0 authored May 20, 2022
2 parents a1dd22d + ed9f106 commit 7b700be
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
9 changes: 6 additions & 3 deletions lib/fizzy/instantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ void match_imported_memories(const std::vector<Memory>& 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"};
}
}

Expand Down Expand Up @@ -558,7 +558,10 @@ std::optional<ExternalMemory> 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<uint32_t>(instance.memory->size() / PageSize), instance.memory_limits.max};
return ExternalMemory{instance.memory.get(), limits};
}

} // namespace fizzy
74 changes: 74 additions & 0 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,3 +810,77 @@ 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);
}

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}));
}
10 changes: 5 additions & 5 deletions test/unittests/instantiate_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7b700be

Please sign in to comment.