-
Notifications
You must be signed in to change notification settings - Fork 792
[Strings] Make string a subtype of ext, not any #7373
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
Conversation
src/wasm/wasm-type.cpp
Outdated
// Bottom types already handled (including string as the switch value, | ||
// which implies the other value is bottom, which again would have been | ||
// handled). |
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.
I don't understand the addition to this comment. string
isn't a bottom type, so why is it included in the bottom types already having been handled?
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.
Lines 399-400 swap to get the lower type as a
. If a
is string, then b
is higher than a
, which means (since string is the last of the non-bottom types in the list) that b
is a bottom type. But we already handled bottom types before on 392-396.
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.
Right, but I don't get that from reading the comment. Is there something special about string here that doesn't also apply to other types?
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.
Just that strings are at the end (right before all the bottom types). I can add that to the comment.
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.
Comment improved.
@@ -949,8 +956,9 @@ std::optional<HeapType> HeapType::getSuperType() const { | |||
case none: | |||
case exn: | |||
case noexn: | |||
case string: |
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.
Yikes! This doesn't look like it was correct before, since it should have returned any
. Do you know how this wasn't caught by tests?
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.
The test was just wrong, but it agreed with the code 😄
See line 1683 in the gtest modified in this PR.
(any.convert_extern | ||
(extern.convert_any | ||
(string.const "string") |
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.
It might still be useful to test any.convert_extern
of a string.
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.
I don't follow - convert it from what to what?
In the new model a string is an externref like a JS object is an externref: it doesn't have a wasm representation under any
.
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.
any.convert_extern
and extern.convert_any
are infallible; all any
and extern
values, including strings, can be converted to the other representation.
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.
But what is the "other representation" of string? I.e. what are you saying that any.convert_extern
of a string should return - what actual 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.
It's an anyref. There's no more specific type and trying to cast it to anything else will fail.
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.
Sure, I guess we can leave it for later. I need to update the interpretation of casts to handle exact types at some point anyway.
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.
The fuzzer hits this, so we do need to resolve the matter in this PR somehow. I'm not sure it is easy to work around it in the fuzzer.
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.
We already support Literal
s with type externref that can be unwrapped to access the underlying any
value. This is the same thing in reverse.
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.
Do/should exact casts to externref work on such values?
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, but if they do for now, it might be ok since there are no real engines to compare such executions to.
(ref.null noextern) ;; The change from stringref to externref does not | ||
;; cause problems here, nothing needs to change. |
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.
Does this unlock any potential code simplifications in StringLowering.cpp?
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.
I wondered this too, but the answer is actually no. While we are doing something much simpler, logically - swapping a type for a supertype, rather than an entirely unrelated type - the actual mechanical change is identical. We just swap all appearances of type X for Y, and don't need to handle any subtyping.
We can no longer fuzz strings in v8, as we represent them in a nonstandard way, so I disabled that. |
I added a readme mention with references to the relevant proposals in the last commit. |
@tlively I am going to fix this fuzztest error: https://github.com/WebAssembly/binaryen/actions/runs/13933139917/job/38994921125?pr=7373 but only because luckily it seems obvious what the issue is. In general, how are people intended to debug errors like that? |
|
The fact that this shows up in CI at all is a nice property of FuzzTest over our other fuzzer patterns. (Although of course we could run the other fuzzers for limited time on CI as well.) |
Thanks, now I see it... it was separated from the error itself, for some reason:
|
I added commits for fuzztest, and the last commit adds hacks to allow converting string to anyref and back. |
Fuzzer looks happy now. |
StringLowering converts strings to externs, which makes sense as we lower
stringrefs to imported JS strings. For the reverse transform it is convenient
to just have strings be subtypes of ext, see #7370 - that makes it simple to
switch stringref to externref and vice versa.