Skip to content

Conversation

@rossberg
Copy link
Member

@rossberg rossberg commented May 8, 2025

Triggered by WebAssembly/design#1539, this spells out the intended backwards-compatibility constraints we assume of future Wasm versions. I believe this captures what was discussed in that context.

@rossberg rossberg requested a review from tlively May 8, 2025 12:15
.. note::
This allows previously illegal programs to become executable.

It also allows program executions that previously trapped to execute successfully.
Copy link
Contributor

@titzer titzer May 8, 2025

Choose a reason for hiding this comment

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

I'm not sure about this point. Have we utilized this to extend semantics to date?

One reason to avoid that is that trapping is observable in an embedding context, and both Wasm programs and embedded environments can use trapping operations as security checks; i.e. a program won't continue past a divide by zero or and out-of-bounds memory access in an unanticipated state.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think we have used it yet, but I believe we have implicitly assumed that we could on a few occasions. I have recollections of design discussions where trapping was suggested as a conservative design choice for cases we don't know how to deal best with yet, e.g. due to possibly unknown future constraints. The answer of starting out with trapping for such cases implies that the trap could be lifted later.

We should definitely use this option rarely and carefully and only in cases where we previously documented that certain trapping cases might have legal behaviour in the future. But shutting out the possibility entirely would eliminate a valuable tool for incremental feature introduction.

Moreover, the same reasoning would apply to relaxing typing, just that it's affecting assumptions about static rather than dynamic failure.

Copy link
Member

Choose a reason for hiding this comment

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

It seems useful to at least guarantee (if we can make such guarantees) that at least some traps will never be lifted, at the very least for the unreachable instruction.

Would it be feasible to include this sense of "cases where we previously documented that certain trapping cases might have legal behaviour in the future" in the text here, and limit the guarantee to that?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a qualification along these lines.

a prior module may encounter new behaviours,
e.g., new forms of control flow or side effects when calling into a latter module.

In addition, the :ref:`instruction opcode <binary-instr>` :math:`\hex{FF}` is considered reserved for custom use and will never be allocated to represent an instruction or instruction prefix.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we say "future versions of the spec will not allocate 0xFF to a valid opcode"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, reworded.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

This all sounds right to me. Do we define subtyping on module types?

@keithw
Copy link
Member

keithw commented May 8, 2025

In the added text, "All syntactically well-formed and valid modules remain well-formed and valid...", the hyperlink on "well-formed" goes to the binary chapter, but the language could be read as applying to both formats.

If it's intended that the text format will also be backwards-compatible, that would be great, but it would be a change from some post-1.0 cases (I think bulk memory) where compatibility was intentionally broken. Or if the text format isn't part of this, it could say something like "In the binary format, all syntactically well-formed..."?

@tlively
Copy link
Member

tlively commented May 8, 2025

Do you have more details about the backward-incompatible text format change? I don't remember that.

@keithw
Copy link
Member

keithw commented May 8, 2025

Do you have more details about the backward-incompatible text format change? I don't remember that.

Sure, e.g. this was a valid module in Wasm 1.0 and became malformed after bulk-memory:

(memory $x 0)
(data $x (i32.const 0))
(data $x (i32.const 0))

(The bulk-memory proposal reassigned the id on a segment to refer to the segment itself, not the memory or table index, so this became a malformed duplicate use.)

And, admittedly pre-1.0 (but still in a lot of online documentation), this was a valid module as late as 76d26bb but malformed after the renaming in #720 and #926:

(table 0 anyfunc)

@tlively
Copy link
Member

tlively commented May 9, 2025

Thanks, I hadn't known about that bulk memory change. Here's the issue about it, in case anyone wants to see the original discussion: WebAssembly/bulk-memory-operations#122. I hope that if we found a similar issue today, we would spend a little more time thinking about it 😅

I would be happy to document that we will maintain backward compatibility of the text format going forward.

@rossberg
Copy link
Member Author

rossberg commented May 9, 2025

@keithw, I clarified that this applies to both formats, despite us having been a tiny bit more loose with the text format in the past. (Though I would almost tend to define away this one away as an early bug fix. :) )

@tlively, we do not formally define subtyping on module types as such, only on individual external types, from which it can be derived. But this formulation is merely intended to give an intuition. It inevitably is a bit informal, since it is relating different language versions, and the definition of types and subtyping itself can change (and has changed) between versions.

2. All non-:ref:`trapping <trap>` :ref:`executions <exec>` of a valid program retain their behaviour with an equivalent set of possible :ref:`results <syntax-result>` (or a non-empty subset).

.. note::
This allows previously illegal programs to become executable.
Copy link
Member

Choose a reason for hiding this comment

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

What is meant by "illegal" here? Is there a more precise word we can use? "Invalid?"

Copy link
Member Author

@rossberg rossberg May 9, 2025

Choose a reason for hiding this comment

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

Malformed or invalid. I expanded it.

@rossberg rossberg merged commit a7b7ac5 into wasm-3.0 May 20, 2025
10 of 11 checks passed
@rossberg rossberg deleted the compat branch May 20, 2025 00:08
@rossberg
Copy link
Member Author

Merging for now, please open issue in case other concerns should come up.

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.

5 participants