Skip to content

Handle flow via imports and exports in Unsubtyping#8439

Open
tlively wants to merge 1 commit intomainfrom
unsubtyping-import-export-jsinterop
Open

Handle flow via imports and exports in Unsubtyping#8439
tlively wants to merge 1 commit intomainfrom
unsubtyping-import-export-jsinterop

Conversation

@tlively
Copy link
Member

@tlively tlively commented Mar 10, 2026

We previously upated Unsubtyping so that any subtype of the result of a
JS-called function would keep its descriptor if that descriptor could
configure a JS prototype. But configured prototypes can also become
visible indirectly because they flow out of the module via imported or
exported functions, globals, or tables. Handle these cases of values
flowing in from or out to JS.

We previously upated Unsubtyping so that any subtype of the result of a
JS-called function would keep its descriptor if that descriptor could
configure a JS prototype. But configured prototypes can also become
visible indirectly because they flow out of the module via imported or
exported functions, globals, or tables. Handle these cases of values
flowing in from or out to JS.
@tlively tlively requested a review from kripken March 10, 2026 05:10
(func $test (export "test") (param (ref $super)) (result anyref)
(local $sub (ref null $sub))
;; $super flowing in from JS means it is cast from any. Since $sub flows out
;; via any, it could be flowing back in and must remain a subtype of $super.
Copy link
Member

Choose a reason for hiding this comment

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

Must we assume any export is called by JS? Can we consider exports not marked with js.called to be called from wasm?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I think that would be nice eventually. Right now we do treat every export as being called from JS by virtue of the --fuzz-exec interpreter pretending to be JS.

)

;; $super flows out via the exported global and also flows back in because the
;; global is immutable.
Copy link
Member

Choose a reason for hiding this comment

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

This sounds wrong? Should immutable be mutable? But the global is immutable...

Copy link
Member Author

@tlively tlively Mar 10, 2026

Choose a reason for hiding this comment

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

Oh yes, copy-paste error. Disregard copies of this below as well. I will fix them.

Copy link
Member

Choose a reason for hiding this comment

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

Sg. Then I am not sure what this module is testing, though - that we export an immutable super (which has subtypes) does not constrain us..?

Copy link
Member Author

Choose a reason for hiding this comment

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

The key result for this one is that $sub-in is optimized to no longer be a subtype of $super. That's only possible because $super does not flow in from JS.

Copy link
Member

Choose a reason for hiding this comment

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

Got it, thanks. So the comment on this test could say this?

  ;; Exported immutable global flows out, but not in. As a result, sub-in can be unsubtyped.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, exactly.

;; CHECK-NEXT: )
(func $test-in (result anyref)
(local $sub-in (ref null $sub-in))
;; This requires that $sub-in is a subtype of $any. If $super flows in from
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
;; This requires that $sub-in is a subtype of $any. If $super flows in from
;; This requires that $sub-in is a subtype of any. If $super flows in from

)

;; $super flows out via the exported global and also flows back in because the
;; global is immutable.
Copy link
Member

Choose a reason for hiding this comment

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

Got it, thanks. So the comment on this test could say this?

  ;; Exported immutable global flows out, but not in. As a result, sub-in can be unsubtyped.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

lgtm aside from comment improvements

(func $test-out (result (ref null $super))
(local $sub-out (ref null $sub-out))
;; This requires that $sub-out is a subtype of $super. If $super flows out
;; to JS, $sub-out will have to keep its descriptor.
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 not to repeat these comments in each testcase. Or to specialize them for each, alternatively.

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.

2 participants