Skip to content

Fix handling of waitqueue in ctor-eval - #9172

Open
stevenfontanella wants to merge 2 commits into
mainfrom
fuzz-fix
Open

stevenfontanella wants to merge 2 commits into
mainfrom
fuzz-fix

Conversation

@stevenfontanella

@stevenfontanella stevenfontanella commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Resolves a crash on makeConstantExpression during ctor-eval when e.g. a waitqueue local is used. See the relevant code path in ctor-eval, which now changes since isData() is true for waitqueues.

Passes ~12 hours of monitor_fuzz.py -j 64, then hit a fuzz bug that reproduces from main.

Part of #8315.

@stevenfontanella
stevenfontanella force-pushed the fuzz-fix branch 2 times, most recently from c384a95 to 7ab93bf Compare September 30, 2026 23:06
@stevenfontanella
stevenfontanella changed the base branch from atomicwait to main September 30, 2026 23:09
@stevenfontanella
stevenfontanella force-pushed the fuzz-fix branch 2 times, most recently from 97dcca4 to f3388dc Compare September 30, 2026 23:29
@stevenfontanella stevenfontanella changed the title Gemini fix Fix handling of waitqueue in ctor-eval Sep 30, 2026
@stevenfontanella
stevenfontanella force-pushed the fuzz-fix branch 2 times, most recently from 5409639 to 6b0ff7a Compare October 1, 2026 15:03
@stevenfontanella
stevenfontanella changed the base branch from main to gc October 1, 2026 15:07
@stevenfontanella
stevenfontanella added this pull request to stack #9178 October 1, 2026 15:16
@stevenfontanella
stevenfontanella marked this pull request as ready for review October 1, 2026 15:16
@stevenfontanella
stevenfontanella requested a review from a team as a code owner October 1, 2026 15:16
@stevenfontanella
stevenfontanella requested review from tlively and removed request for a team October 1, 2026 15:16
stevenfontanella added a commit that referenced this pull request Oct 1, 2026
Waitqueue instructions only make sense when GC is enabled. e.g.
`struct.wait` takes a struct reference which requires GC anyway, and
waitqueues live on the GC heap. This is also needed for #9172 to pass
[this
check](https://github.com/WebAssembly/binaryen/blob/4d8ac549e2ab9b283246ea95e79ebe139ca579ac/src/tools/wasm-ctor-eval.cpp#L598-L599).

Part of #8315.
Base automatically changed from gc to main October 1, 2026 18:32
Comment thread src/wasm-type.h
Comment on lines +1197 to +1198
return isMaybeShared(string) || isMaybeShared(waitqueue) ||
kind == HeapTypeKind::Struct || kind == HeapTypeKind::Array;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This change is surprising to me, since waitqueues don't seem like transparent holders of other data the way structs and arrays are. And it seems like this change is the cause of several of the other changes. What's the motivation here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I mentioned this in the PR description, the idea is that isData is now true which hits a different code path in ctor-eval: link.

Alternatively we could just add an extra check for waitqueue here in addition to isData, but my thinking is that waitqueues really are GC data, and other passes that look at isData are more likely to want to treat them that way (which this case is evidence of).

From a quick look, it looks like this is the only pass that's affected in terms of real logic at the moment:
https://github.com/search?q=repo%3AWebAssembly%2Fbinaryen+%2F%5CbisData%28%29%5Cb%2F&type=code

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That code path is using !value.isData() || value.isString() to mean "requires special global-creating logic." I think it would make more sense to update that code path to explicitly include waitqueues than it would to include waitqueues in isData.

FWIW, isData is essentially a historical accident. At one point during the development of the GC proposal, there was a data type that was a supertype of structs and arrays. The type was removed, but we kept isData() because it was shorter than writing isStruct() || isArray() everywhere. It's possible that it globally make the codebase clearer if we removed it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

My thinking is that waitqueue is 'similar' to struct and array that way; they are all stateful GC objects. Sounds good though, I don't have a strong opinion. waitqueue is definitely different in some ways.

FWIW it looks like we still use gcData as the identity of the global that we synthesize link. This looks like a problem with the current PR because we always use nullptr so there's no identity here link. Let me take a look and fix it.

This branch has not been deployed

No deployments
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