-
Notifications
You must be signed in to change notification settings - Fork 837
Fix Unsubtyping and GTO for configureAll #8267
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
Changes from all commits
224c6c9
5030f71
e559690
7edb43d
9f6eb43
75c41f0
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 |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ | |
| #include "ir/localize.h" | ||
| #include "ir/module-utils.h" | ||
| #include "ir/names.h" | ||
| #include "ir/struct-utils.h" | ||
| #include "ir/subtype-exprs.h" | ||
| #include "ir/type-updating.h" | ||
| #include "ir/utils.h" | ||
|
|
@@ -554,6 +555,7 @@ struct Unsubtyping : Pass, Noter<Unsubtyping> { | |
| // Initialize the subtype relation based on what is immediately required to | ||
| // keep the code and public types valid. | ||
| analyzePublicTypes(*wasm); | ||
| analyzeJSCalledFunctions(*wasm); | ||
| analyzeModule(*wasm); | ||
|
|
||
| // Find further subtypings and iterate to a fixed point. | ||
|
|
@@ -605,6 +607,33 @@ struct Unsubtyping : Pass, Noter<Unsubtyping> { | |
| } | ||
| } | ||
|
|
||
| void analyzeJSCalledFunctions(Module& wasm) { | ||
| if (!wasm.features.hasCustomDescriptors()) { | ||
| return; | ||
| } | ||
| Type anyref(HeapType::any, Nullable); | ||
| for (auto func : Intrinsics(wasm).getConfigureAllFunctions()) { | ||
| // Parameter types flow into Wasm and are implicitly cast from any. | ||
| for (auto type : wasm.getFunction(func)->getParams()) { | ||
| if (Type::isSubType(type, anyref)) { | ||
| noteCast(HeapType::any, type); | ||
| } | ||
| } | ||
| for (auto type : wasm.getFunction(func)->getResults()) { | ||
| // Result types flow into JS and are implicitly converted from any to | ||
| // extern. They may also expose configured prototypes that we must keep. | ||
| if (Type::isSubType(type, anyref)) { | ||
| auto heapType = type.getHeapType(); | ||
| noteSubtype(heapType, HeapType::any); | ||
| if (auto desc = heapType.getDescriptorType(); | ||
| desc && StructUtils::hasPossibleJSPrototypeField(*desc)) { | ||
| noteDescriptor(heapType, *desc); | ||
| } | ||
|
Member
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. Why is the cast symmetric in params and results, but the prototype only appears for the results?
Member
Author
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. The parameters are values flowing from JS to Wasm and the results are values flowing from Wasm to JS. Only JS->Wasm involves an implicit cast, only Wasm->JS involves an implict |
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void analyzeModule(Module& wasm) { | ||
| struct Info { | ||
| // (source, target) pairs for casts. | ||
|
|
@@ -746,6 +775,14 @@ struct Unsubtyping : Pass, Noter<Unsubtyping> { | |
| for (auto& [sub, super] : collectedInfo.subtypings) { | ||
| noteSubtype(sub, super); | ||
| } | ||
| // Combine casts we have already noted into the newly gathered casts. | ||
| for (auto& [src, dsts] : casts) { | ||
| for (auto dst : dsts) { | ||
| collectedInfo.casts.insert({src, dst}); | ||
| } | ||
| dsts.clear(); | ||
| } | ||
|
Member
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. Is this an unrelated fix?
Member
Author
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. No. We now have casts that were noted before the parallel function analysis. This is merging them into the parallel function analysis sets so we don't end up with unnecessary duplicated entries. |
||
| // Record the deduplicated cast info. | ||
| for (auto [src, dst] : collectedInfo.casts) { | ||
| casts[src].push_back(dst); | ||
| } | ||
|
|
||
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.
Perhaps add a comment here as to why only the results matter?