-
Notifications
You must be signed in to change notification settings - Fork 1
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
Mixed-shareability semantics of ref.eq #76
Comments
I don't think we want to assume this in general. In particular with our decision that globals of all |
This problem is scoped to @manoskouk or @jakobkummerow, are there any engine implementation issues we should consider here? |
I don't think introducing Having a separate instruction initially is less committal, because if we really decided in the future that engines would never use this flexibility, we could interpret both opcodes as different encodings for the same polymorphic |
That shouldn't be necessary. I think the principal type is expressible just fine with a type variable ranging over 𝑠ℎ𝑎𝑟𝑒 (a.k.a., 𝑠ℎ𝑎𝑟𝑒𝑎𝑏𝑠ℎ𝑒𝑎𝑝𝑡𝑦𝑝𝑒 ::= 𝑠ℎ𝑎𝑟𝑒 𝑎𝑏𝑠ℎ𝑒𝑎𝑝𝑡𝑦𝑝𝑒 Then the principal type of ref.eq is: (ref 𝑛𝑢𝑙𝑙₁ (𝑠ℎ𝑎𝑟𝑒 eq)) (ref 𝑛𝑢𝑙𝑙₂ (𝑠ℎ𝑎𝑟𝑒 eq)) → i32 |
FWIW I'd also be fine with @rossberg's solution, so long as we briefly think about whether this + any other instructions would cause issues when validating dead code (gut feeling - it's ok). |
From an implementation perspective, it's a little early for definitive statements... My gut feeling is that we'd probably prefer to have a single Ultimately, the implementation will be dictated by the needs of the spec. If we need shared-null and non-shared-null to be distinguishable at runtime (for So, if we can disallow shared/non-shared comparisons for now (and maybe forever) and thereby sidestep these pitfalls, that sounds great. |
@rossberg, haven't we been very careful in the past to not allow type variables from one operand constrain type variables from another operand? If the |
#6752)" Allowing Literals with different types to compare equal causes problems for passes that want equality to mean real equality, e.g. because they are using literals as map keys or because they otherwise need to use them interchangeably. At a minimum, we would need to differentiate a `refEq` operation where mixed-shareability i31refs can compare equal from physical equality on Literals, but there is also appetite to disallow mixed-shareability ref.eq at the spec level. See WebAssembly/shared-everything-threads#76.
Update the validator to reject mixed-shareability ref.eq, although this is still under discussion in WebAssembly/shared-everything-threads#76. Fix the implementation of `Literal::operator==` to work properly with shared i31ref.
#6752)" (#6761) Allowing Literals with different types to compare equal causes problems for passes that want equality to mean real equality, e.g. because they are using literals as map keys or because they otherwise need to use them interchangeably. At a minimum, we would need to differentiate a `refEq` operation where mixed-shareability i31refs can compare equal from physical equality on Literals, but there is also appetite to disallow mixed-shareability ref.eq at the spec level. See WebAssembly/shared-everything-threads#76.
Update the validator to reject mixed-shareability ref.eq, although this is still under discussion in WebAssembly/shared-everything-threads#76. Fix the implementation of `Literal::operator==` to work properly with shared i31ref.
Update the validator to reject mixed-shareability ref.eq, although this is still under discussion in WebAssembly/shared-everything-threads#76. Fix the implementation of `Literal::operator==` to work properly with shared i31ref.
@tlively, problematic would be non-trivial constraints between different type variables. Multiple occurrences of the same variable are no problem. There already are cases where that is needed, e.g., with the nullability variable in the principal type of extern.convert_any (though that's occurring in operand and result). |
Thanks, that makes sense. That seems like the best solution by far, then. I'll document in the overview that mixed-sharedness ref.eq is disallowed. |
Fix the ref.eq typing to require that both operands have the same sharedness and list the other instructions that will need to be updated to use an unconstrained sharedness metavariable in their typing rules. Resolves #76.
To preserve our principle types properties, we either have to create a new version of
ref.eq
for use with shared references or we have to let the existingref.eq
validate with any combination of shared and unshared operands. So far we have chosen the latter option.This raises the question of what the semantics of
ref.eq
should be in interesting cases where one argument is shared and the other is unshared. Here is the behavior I assume we want, but it would be good to make sure everyone agrees.This would strongly encourage implementations to have the same representation for
ref.null none
andref.null (shared none)
. It also encourages implementations to have the same representation for shared and unshared i31 values, but I don't think that should be controversial.The text was updated successfully, but these errors were encountered: