Skip to content

[spec] Fix the default alignment of memarg in the text format - #2314

Merged
rossberg merged 1 commit into
WebAssembly:mainfrom
sanguineman:fix/text-default-align
Nov 2, 2026
Merged

rossberg merged 1 commit into
WebAssembly:mainfrom
sanguineman:fix/text-default-align

Conversation

@sanguineman

@sanguineman sanguineman commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The text format section on memory instructions says the alignment defaults to the natural alignment, but the grammar right below it does not:

스크린샷 2026-10-31 오후 9 56 04

(§6.5.6 of the Release 3.0 PDF, 2026-10-28)

align_N (Talign_ in 6.3-text.instructions.spectec L184-L186) receives the access size N in bytes and should return the alignment exponent that memarg stores. The explicit case converts the byte value m to the exponent n, but the default case returns the byte value N unchanged. For example, i32.load uses Tmemarg_(4) (L192), so i32.load without align= gets ALIGN 4 instead of ALIGN 2.

Memarg_ok requires 2^n <= N/8 with N in bits, i.e. 2^n must not exceed the access size in bytes. With the default, n is the byte size itself, and 2^n <= n never holds. So every load and store that omits align= is invalid under this grammar, for example:

(module (memory 1)
  (func (drop (i32.load (i32.const 0)))))

The reference interpreter follows the prose: it uses the natural alignment as an exponent (lexer.mll L249-L256, e.g. opt a 2 for i32.load).

In Wasm 2.0, align_N returned the byte value and memarg_N converted it with a = 2^n (wg-2.0 text/instructions.rst L288-L295), so ε ⇒ N was correct there. The SpecTec version moved the conversion into Talign_, and #2107 fixed its explicit case to return n, but the default case was left as N.

Fix

Convert the default in the same way as the explicit case:

 grammar Talign_(N) : u32 =
   | "align=" m:Tu64 => n  -- if $(m = 2^n)
-  | eps => N
+  | eps => n  -- if $(N = 2^n)

The rendered grammar becomes ε ⇒ n if N = 2^n, matching the line above it.

This PR changes 6.3-text.instructions.spectec in wasm-3.0 and wasm-latest and updates the spectec/test-*/TEST.md outputs. No test is added, since the reference interpreter's parser already uses the natural alignment.

@sanguineman sanguineman changed the title fix(spec): convert the default text-format alignment to an exponent [spec] Fix the default alignment of memarg in the text format Oct 31, 2026

@rossberg rossberg 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.

Thanks! Can you also backport this to the 1.0 and 2.0 specs?

@sanguineman

Copy link
Copy Markdown
Contributor Author

Thanks!
I looked into this, but I don't think there is anything to backport.
The 1.0 and 2.0 SpecTec specs (specification/wasm-1.0, specification/wasm-2.0) don't define the text format; it only exists in SpecTec from 3.0 on.
And the hand-written 1.0 and 2.0 documents are correct: there, align_N returns the byte value and memarg_N converts it with a = 2^n, so the default ε ⇒ N gives the right exponent (wg-1.0 L185-L192, wg-2.0 L288-L295).
Am I missing something?

@rossberg rossberg 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.

Ah, sorry, indeed we haven't recreated the text format for 1.0 and 2.0 in SpecTec yet.

@rossberg
rossberg merged commit 0148af7 into WebAssembly:main Nov 2, 2026
12 checks passed
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.

2 participants