-
Notifications
You must be signed in to change notification settings - Fork 831
Provide Module& parameter to operateOnScopeNameUsesAndSentTypes #6096
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The root of this sequence of changes appears to be adding
Module& wasmhere. That leads to needing the module in the newBranchTypeSeekerwhich leads toBlock::finalizeneeding it, which leads to lots of changes.However, I do not actually see
Module& wasmused here inoperateOnScopeNameUsesAndSentTypes, so I don't yet understand the motivation. Reading the code in #6083 I don't seewasmused there. I do see some discussion in https://github.com/WebAssembly/binaryen/pull/6083/files#r1382658351 but I can't understand it 😄 Probably because it speaks about wasm proposals I am not familiar with.What I am trying to understand is: what would the code look like, that uses
Module& wasmhere?I ask because this PR looks like a very large refactoring of the sort we've tried to avoid in general. For example,
RefFunccould in theory read the type of the function from the Module, but we purposefully do not do that inReFinalize::visitRefFunc, and instead rely on it being set initially in a correct manner, and then we just preserve it there (and anyone that changes a Function's type is responsible for updatingRefFuncs). In that case it avoids parallelism risks of modifying one function's type while modifying the contents of another, for example - in general, we try to avoid reading global state like this for Expressions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The core problem is that the new
resumeinstruction from typed continuations and the newtry_tableinstruction from the redesigned EH proposal act as a branches where the sent types depends on tag types. We currently depend on being able to determine the sent type of branches just by inspecting the branchingExpression, but the new dependencies on tag types means that determining the types of branches requires being able to look up the tags on the module as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's right.
Sorry, I realize that this PR and the linked one do a bad job at showing what the
Module&is actually needed for.From a high-level perspective, the typed continuations proposal allows writing something like this:
This means that if you
suspendto the tag$mytagwhile running the continuation$mycont, then execution continues after $myblock. The type of the data that is provided to$myblockdepends on the types of the tag used and the type of the continuation (the latter is$cthere).Something very similar will happen for the new EH proposal, where exception handlers are just ordinary blocks, and
throwjumps to them, with additional data.Practically speaking, for
operateOnScopeNameUsesAndSentTypesthis means that we need to do something like this:I agree that this is a rather large refactoring. Id be happy to hear if there are ways of decreasing its footprint somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation!
Can we simply duplicate the type into the resume? This is what we do in practice for e.g. RefFunc today: the type of each RefFunc mirrors the module's information about the function's signature. Likewise a Call mirrors the returns of the signature, etc. While in general such duplication is not great, it allows us to avoid reading global state constantly.
If that can't work, maybe elaborate on what
iis in that example, and whattype send to label is calculatedmeans in practice? (if those things are referring to some kind of "dynamic" read from the module, then simple mirroring of a single value might not work, but I hope that's not the case here...) For the new EH proposal, at least, I think this should work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both of the new instructions take a vector of (tag, label) pairs, so they're similar to
br_tableexcept that they can potentially send different types to each of the labels. If we want to store the sent types directly in the newExpressions, they would have to beArenaVector<Type>rather than just a single type.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is nothing prohibiting this from a technical perspective. Note that in general, each
resumeinstruction has a list of(tag $sometag $someblock)clauses, where my example above only used one. This means that we would have to duplicate theSignatures of all of the tags into theResumeobject.I just used the
ito reflect that theResumenode actually contains a list of tags and a list of blocks, together representing a(tag $sometag $someblock)entry. I was trying to hand-wave this away, becauseoperateOnScopeNameUsesAndSentTypesneeds some unrelated adapation to avoid a quadratic blowup because of this, but that is independent from the need to have access to theModule.But coming back to your actual question: The information we need from the
Moduleis entirely static. We just need access to the param and results types that were given when defining the tags in the tags section of the module.More concretely, the types of the values that flow into a handler block (such as
$myblockin my example above) are then a) the param types of the tag used, followed by b) a continuation type. The latter continuation type is determined entirely by the result types of the tag and the type of theresumed continuation (which can be read off from the instruction itself).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, in my previous comment I mentioned storing the signtatures of each of the tag in the
Resumenode for each(tag ...)clause, but we may equally store the sent types directly. Note that these are often tuples, because the types sent to the handler are the param types of the corresponding tag, followed by a continuation type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks, that it's a list of types is the tricky part then.
An
ArenaVector<Type>seems like a reasonable way to proceed here, since I don't think we will have very many such nodes and not very long lists in them? For EH at least for C++ I believe the list will always be of length 1 (the single standard C++ exception tag with a pointer in it).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, the size of the
ArenaVector<Type>itself will be equal to the number of(tag ...)clauses of theresumeinstruction. EachTypewill then be a tuple type with n_i + 1 elements, where n_i is the number of parameters of the tag used by the i-th clause.I think it's difficult to give a meaningful estimate of how many
(tag ...)clauses aresumeinstruction will usually have, and how manyparamsthe involved tags will have. But I would be surprised to see larger numbers of each.Going back to your original concerns about this refactoring, I don't quite understand what you meant by the following:
Were you concerned that we are relying on some kind of global mutable state here? Luckily, this is not the case. Or was your concern more generally about the fact that in, say,
Block::finalize(Module& wasm)we would be relying on information that is maintained outside of the block in question? That is definitely true.During the refactoring, it seemed like the
Modulewas usually in reach and just needed to be passed on to additional places (which arguably then sums up to: quite a lot of additional places).I don't mind discarding this PR and adding the
ArenaVectorto theResumenodes in #6083 if that is your preferred option.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I wasn't clear about the parallelism. Yes, in this case it is safe. I was trying to give an example of why we avoid reading global state in general, one reason for which is that in some situations it is unsafe.
I do prefer to add an ArenaVector. It's less of a change, and it is more consistent with our existing coding style, I think. If we see it adds significant overhead in practice we can always optimize it later.