Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EH] Add validation for new instructions #6185

Merged
merged 4 commits into from
Dec 20, 2023

Conversation

aheejin
Copy link
Member

@aheejin aheejin commented Dec 19, 2023

This adds validation for the new EH instructions (try_table and throw_ref):
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md

This also adds a spec test for checking invalid modules. We cannot check the executions yet because we don't have the interpreter implementation. The new test file also contains tests for the existing throw, because this is meant to replace the old spec test someday.

This adds validation for the new EH instructions (`try_table` and
`throw_ref`):
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md

This also adds a spec test for checking invalid modules. We cannot check
the executions yet because we don't have the interpreter implementation.
The new test file also contains tests for the existing `throw`, because
this is meant to replace the old spec test someday.
src/wasm/wasm-validator.cpp Outdated Show resolved Hide resolved
src/wasm/wasm-validator.cpp Outdated Show resolved Hide resolved
Comment on lines +2453 to +2454
if (curr->type != Type::unreachable) {
shouldBeSubType(curr->body->type,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be combined with the else case into a single shouldBeSubType, since the only subtype of Type::unreachable is Type::unreachable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 2499 to 2501
if (shouldBeTrue(sentType.size() == 1, curr, "")) {
shouldBeEqual(sentType,
Type(Type::none),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is happening here? sentType cannot both have size 1 and be equal to Type::none, since Type::none has size 0.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in case the sent type is none, the sentTypes will look like {Type(Type::none)}, which is of size 1, no?

To make it contain the sent types that can be used directly at branch-utils.h, in case there is no sent values, we add a single Type::none:

curr->sentTypes.push_back(sentType.empty() ? Type::none : Type(sentType));

Usage in branch-utils.h
} else if (auto* tt = expr->dynCast<TryTable>()) {
for (Index i = 0; i < tt->catchTags.size(); i++) {
auto dest = tt->catchDests[i];
if (dest == name) {
func(name, tt->sentTypes[i]);
}
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make it {} and branch-utils.h's operateOnScopeNameUsesAndSentTypes to return Type::none in case there is an empty type, but that adds one more if and operateOnScopeNameUsesAndSentTypes runs more times than the routine popuating sentTypes when reading a binary.

Copy link
Member Author

@aheejin aheejin Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, nevermind all above. I didn't know (Type::none).size() returns 0. Will fix.

shouldBeEqual(
tagType[j], sentType[j], curr, "invalid catch sent type information");
}
if (curr->catchRefs[i]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to check that the sizes match when this is false as well. Alternatively, when there is no extra exnref, you can just check tagType == sentType.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was actually incorrect because even if there is no values to send, sentType will contain Type::none, which is size 1... And this wasn't crashing because I was doing the early exit (https://github.com/WebAssembly/binaryen/pull/6185/files#diff-2149be365b66a82038f1d3fa8f9fb1b4dcd40ab535c986f4bf0a4c37e669a1ceR2481-R2483). Will fix that and check both cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind the comment. Didn't know (Type::none).size() returns 0...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up rewriting much of the loop, but I think I an now checking both cases. PTAL

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, LGTM!

Name tagName = curr->catchTags[i];
if (!tagName) { // catch_all or catch_all_ref
tagTypeSize = 0;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think this extra newline looks a little odd.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed it

@aheejin aheejin merged commit 11e3af0 into WebAssembly:main Dec 20, 2023
14 checks passed
@aheejin aheejin deleted the new_eh_validation branch December 20, 2023 18:48
radekdoulik pushed a commit to dotnet/binaryen that referenced this pull request Jul 12, 2024
This adds validation for the new EH instructions (`try_table` and
`throw_ref`):
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md

This also adds a spec test for checking invalid modules. We cannot check
the executions yet because we don't have the interpreter implementation.
The new test file also contains tests for the existing `throw`, because
this is meant to replace the old spec test someday.
@gkdn gkdn mentioned this pull request Aug 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants