-
Notifications
You must be signed in to change notification settings - Fork 746
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
Validate pops while ignoring nameless blocks? #6950
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
;; Test for a nameless block containing a pop, which is allowed. | ||
|
||
;; XXXXXXXXXXXXXXX RUN: not wasm-opt --enable-reference-types %s -o - -S 2>&1 | filecheck %s --check-prefix NO-GC | ||
;; RUN: wasm-opt --enable-reference-types --enable-gc %s -o - -S | filecheck %s --check-prefix GC | ||
|
||
;; NO-GC: all used types should be allowed | ||
|
||
;; GC: (func $foo (type $0) (param $x eqref) | ||
|
||
(module | ||
(tag $tag (param i32)) | ||
|
||
(func $0 | ||
(try | ||
(do | ||
(nop) | ||
) | ||
(catch $tag | ||
(drop | ||
(block (result i32) | ||
(pop i32) | ||
) | ||
) | ||
) | ||
Comment on lines
+18
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This Wasm doesn't really make sense from a typing perspective unless the block takes an i32 parameter, which we don't yet support. I'm not sure we should want to be able to parse something like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, we probably should not be printing text that looks like this. I'm working on using IRBuilder in the binary parser now, after which we will be able to update it to support control flow parameters, so we could fix this example to have proper typing, but even then, IRBuilder will lower the control flow parameters away using locals, so we still wouldn't be able to parse this IR directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I see what you mean. But this is consistent with our other extensions to the text format, e.g., this validates: (module
(func $foo
(local $x (ref func))
(block
(local.set $x
(ref.func $foo)
)
)
(drop
(local.get $x)
)
)
) That isn't valid wat since the block should end the range of the non-nullable local, but we decided to allow it. With that said, I do see that this change would be more intrusive and confusion, potentially. So maybe this PR is a bad idea. But we do have a general problem here, where more passes then we expected need EH fixups. Modifying them all adds clutter and overhead, so I was hoping for a more general solution... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think I understand. Why does this not make sense unless the block takes an i32 input parameter? What does this have to do with an input parameter? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the long run, I hope that the text and binary parsers will be able to lower legacy EH directly to new EH IR, so all the problems with pop validation will become moot. Maybe there are less intrusive changes we can make in the short term? |
||
) | ||
) | ||
) | ||
|
||
;; TODO: test two nested blocks |
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.
This change avoids the error, but it doesn't actually move the pop into the right place. Whenever we try to pop from an empty stack, we should look up the stack through nameless blocks to find pops that we could use.
Weird edge case to test:
pop
through such a block?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.
Why is this a situation of popping from an empty stack? Are
Pop
instructions not added to the stack like anything else? (they have a concrete 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.
No,
pop
s are special. They are automatically pushed onto the stack when the beginning of acatch
is parsed, not when thepop
instruction itself is parsed. That's why the existing code here just does some error checking and doesn't push anything. The reason is that we fully support parsing standard code that does not contain anypop
s, so we can't wait until we see apop
to push it onto the stack. For example, this parses: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.
To avoid the edge case here, we should use a scratch local to pull the value of the pop into the block. That won't help the example I gave below, though, so we still need to relax the validation behavior as well.