Skip to content

Restore the extern heap type - #4898

Merged
tlively merged 8 commits into
mainfrom
heaptype-extern
Aug 18, 2022
Merged

Restore the extern heap type#4898
tlively merged 8 commits into
mainfrom
heaptype-extern

Conversation

@tlively

@tlively tlively commented Aug 11, 2022

Copy link
Copy Markdown
Member

The GC proposal has split any and extern back into two separate types, so
reintroduce HeapType::ext to represent extern. Before it was originally
removed in #4633, externref was a subtype of anyref, but now it is not. Now that
we have separate heaptype type hierarchies, make HeapType::getLeastUpperBound
fallible as well.

@tlively
tlively requested a review from kripken August 11, 2022 01:38
@tlively

tlively commented Aug 11, 2022

Copy link
Copy Markdown
Member Author

Current dependencies on/for this PR:

This comment was auto-generated by Graphite.

@tlively
tlively requested a review from aheejin August 11, 2022 01:39

@kripken kripken left a comment

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.

Why are the tests changed here?

Comment thread src/ir/possible-constant.h Outdated
auto lub = HeapType::getLeastUpperBound(type, otherType);
if (lub != type) {
value = Literal::makeNull(lub);
assert(lub && "TODO: Handle case without LUB");

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.

I think we should handle this in this PR, or else we'll get fuzzer failures. To handle it, if there is no LUB let's turn the result into Many().

@tlively tlively Aug 11, 2022

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.

Shouldn't we turn it into a None, since the types are incompatible? Although once we implement bottom types, we'll be able to make it a Literal of that bottom type instead.

Edit: I guess the conservative thing to do here is use Many for now and Literal in the future.

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.

None means "no contents". Many means "many things are possible here", which can include many incompatible things.

otherType.getHeapType());
value = Literal::makeNull(lub);
assert(lub && "TODO: handle case where there is no LUB");
value = Literal::makeNull(*lub);

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.

Same as above, this can make a Many().

@tlively

tlively commented Aug 11, 2022

Copy link
Copy Markdown
Member Author

The tests changed because their input used "externref" or "(ref extern)", which previously was an alias for "anyref" and "(ref any)" but now is not.

@kripken

kripken commented Aug 11, 2022

Copy link
Copy Markdown
Member

I see about the tests, thanks.

@kripken kripken left a comment

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.

lgtm if this passes fuzzing.

@aheejin aheejin left a comment

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.

Some places this didn't just add externref but replaced anyref with it. We don't need anyref in those places anymore?

Comment thread src/binaryen-c.cpp
case HeapType::eq:
assert(x.isNull() && "unexpected non-null reference type literal");
break;
case HeapType::any:

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.

Why is any's behavior here different from that of ext? Is any not nullable?

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.

We only support the standardized reference types extern and func in this API and all the GC types are meant to hit that WASM_UNREACHABLE. Previously HeapType::any represented the standardized extern, but now it only represents the sepate any GC type.

Comment thread src/passes/InstrumentLocals.cpp Outdated
Name get_v128("get_v128");
Name get_funcref("get_funcref");
Name get_anyref("get_anyref");
Name get_extref("get_extref");

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.

We don't abbreviate externref to extref in other places, so how about just get_externref/set_externref here as well?

@tlively

tlively commented Aug 12, 2022

Copy link
Copy Markdown
Member Author

Note to self: I should also update the changelog.

@tlively

tlively commented Aug 12, 2022

Copy link
Copy Markdown
Member Author

Some places this didn't just add externref but replaced anyref with it. We don't need anyref in those places anymore?

Right, these were places that were logically using externref all along, but because we had externref == anyref, they had to use anyref in the code.

The GC proposal has split `any` and `extern` back into two separate types, so
reintroduce `HeapType::ext` to represent `extern`. Before it was originally
removed in #4633, externref was a subtype of anyref, but now it is not. Now that
we have separate heaptype type hierarchies, make `HeapType::getLeastUpperBound`
fallible as well.
@tlively

tlively commented Aug 18, 2022

Copy link
Copy Markdown
Member Author

Fuzzer looks good when I hack it to use v8-10.5.117, which still has func <: any. The next PR will make it work with up-to-date v8.

@tlively
tlively merged commit 2d86d1f into main Aug 18, 2022
@tlively
tlively deleted the heaptype-extern branch August 18, 2022 05:51
@kripken

kripken commented Aug 18, 2022

Copy link
Copy Markdown
Member

./scripts/fuzz_opt.py 5710490634504070365 fails on main now, which I am guessing is related to this as the error is:

binaryen/src/tools/fuzzing/fuzzing.cpp:1972: wasm::Expression* wasm::TranslateToFuzzReader::makeConstBasicRef(wasm::Type): Assertion `type.isNullable() && "Cannot handle non-nullable externref"' failed.

@kripken

kripken commented Aug 18, 2022

Copy link
Copy Markdown
Member

Bisected to confirm, the breakage indeed starts here.

This type of error seems to happen every 1,000 or so fuzzer iterations now, but sometimes it's 100 or 10,000, so this type of rare issue is easy to miss...

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