Skip to content

Merge upstream - #113

Merged
tlively merged 241 commits into
mainfrom
merge-upstream-2026-10-02
Oct 2, 2026
Merged

tlively merged 241 commits into
mainfrom
merge-upstream-2026-10-02

Conversation

@tlively

@tlively tlively commented Oct 2, 2026

Copy link
Copy Markdown
Member

No description provided.

KKiiim and others added 24 commits September 1, 2026 12:59
* Stop suppressing custom test failures

`exit 1` was never running because `cat` and `rm` were succeeding. Oops!

* Catch Custom.Invalid in validate_with_custom

validate_with_custom ran the handlers' check functions for each custom
section, but didn't actually catch the Custom.Invalid exception that
this could throw, resulting in a spurious "failed" result.

* Catch Custom.Code in assert_malformed_custom

assert_malformed catches errors in both binary decoding and text
parsing, but assert_malformed_custom was only catching errors in text
parsing.
…#2229)

Proposal repos are plain forks of `WebAssembly/spec`, so their published
webassembly.github.io/<proposal>/ site has no rendered copy of the
unmodified spec to compare against. The proposals often also lag behind
the upstream spec so a direct comparison between the rendered specs is
full of false differences. A reviewer who wants to see what a proposal
actually does to the spec text has to build upstream themselves, or read
source diffs, which is particularly awkward for parts of the spec which
are generated in the output. e.g. typeset rules, tables, appendices, etc.

With this change a fork also renders every document at the commit where
it diverged from its parent repo, and publishes the result under
webassembly.github.io/<proposal>/upstream with the same layout as the
main site. This will allow us to link to W3C's spec diff service and
view a formatted and searchable comparison with a single URL. e.g.

https://services.w3.org/htmldiff?doc1=https://webassembly.github.io/<proposal>/upstream/core/bikeshed/&doc2=https://webassembly.github.io/<proposal>/core/bikeshed/

The baseline is chosen by a new resolve-baseline job, which asks the `gh`
API for the repository's parent, fetches the parent's main, and takes
`git merge-base`. For most proposals which sync by merging upstream,
this resolves to the most recent sync point. When running on
`WebAssembly/spec`, a fork with no changes of its own, or when the
parent cannot be determined / fetched, the job short-circuits and no
upstream copy is generated.

Each build job stages its render at the final path it occupies on the
site. This lets the publish job merge every artifact into one tree
instead of mapping each one to a destination. Adding a document no
longer requires touching the publish job. It feels like this should be
the Makefile's job but I'll leave that to another PR.

The commit upstream was rendered from is recorded at
/upstream/baseline-sha and compared on the next run. When the shas match,
the upstream variant is dropped from the build matrix and the published
copy is carried over instead of being rendered again. This saves a
decent amount of CI time for most (non-downstreaming) commits.
Two directions of the same underlying mistake - misreading what the
?/! shorthand actually requires:

- [=!=] applied to ToJSValue (7 sites), OrdinaryObjectCreate (3
  sites), CreateBuiltinFunction (1 site), and IsStrictlyEqual (2
  sites): none of these ever return a Completion Record, so there is
  nothing for ! to unwrap. ToJSValue's own body is bare Let/Return
  statements with no Throw/NormalCompletion/ThrowCompletion anywhere;
  OrdinaryObjectCreate and CreateBuiltinFunction are declared with
  non-completion return types in ECMA-262; IsStrictlyEqual is
  declared ': a Boolean'. Every other call site of these same
  operations elsewhere in this corpus (~40 occurrences of
  CreateBuiltinFunction alone, in webidl/index.bs) correctly omits
  the shorthand - these are the sole exceptions.
- read the imports is missing [=?=] before [$HasProperty$]: unlike
  every other [$HasProperty$]/[$Get$] call in this exact algorithm,
  which are all correctly marked [=?=], this one omission means the
  fallback branch it's meant to guard (falling back to reading from
  the plain importObject when a builtin-provided export doesn't have
  the requested property) can never fire, since the raw Completion
  Record it produces is compared against the literal false value as
  a Record, never true.
…ion changes

Five spots where this document still matches an older shape of the
Wasm Core Spec's runtime representation, or otherwise needs the Core
Spec's own declared types to see the bug at all:

- |module|.[=imports=] treats a decoded module as a record with a
  field to project - it's an opaque value now, not a record. Route
  through module_imports(|module|) instead, matching every other
  read of the same data in this file.
- 'is of the form [=external-type/tag=] |attribute| ...' destructures
  an attribute-kind field tagtype no longer carries ('exception' is
  still the only attribute this proposal defines) - drop the binding
  and the now-vacuous assert that followed it (two call sites).
- |moduleinst|.funcaddrs names a field the actual runtime moduleinst
  record doesn't have; it's called .funcs.
- [=ref.null=] |heaptype| / [=ref.null=] <var ignore>t</var>: the
  current runtime ref value grammar's null case is a bare nullary
  constructor, no heap-type argument. Dropping it in
  ToWebAssemblyValue's construction leaves the destructured
  |heaptype| a couple of lines up unused, so that binding is dropped
  too (same shape of leftover as the tag fix above).
- instantiate the core of a WebAssembly module checks |result| for
  [=error=] before destructuring it into (|store|, |instance|) - but
  module_instantiate's own declared return type (embedding.rst) is
  always a (store, moduleinst | error) pair, so |result| (the whole
  tuple) can never literally equal the bare error value; only its
  second component can, making the LinkError branch dead code and a
  genuine link failure silently return the error sentinel as if it
  were a real instance. Fixed by destructuring the call's result
  directly, the way the sibling algorithm call an Exported Function
  already does for func_invoke, and reusing |result| for the second
  component - the check below (already written 'If |result| is
  [=error=]') becomes correct as-is with no rename of its own.
@tlively
tlively force-pushed the merge-upstream-2026-10-02 branch from 344371d to 8efe94e Compare October 2, 2026 23:14
@tlively
tlively merged commit 8efe94e into main Oct 2, 2026
11 of 12 checks passed
@tlively
tlively deleted the merge-upstream-2026-10-02 branch October 2, 2026 23:52
@tlively

tlively commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

@kmiller68, it looks like the resolve-baseline action failed with "Could not determine the parent repo, not rendering an upstream copy." https://github.com/WebAssembly/custom-descriptors/actions/runs/37076658421/job/111067979800

If you can figure out what's going wrong there, I'd be happy to do another merge to pull in a fix.

@tlively

tlively commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Ah, it's because most proposal repos are not actually forks of the spec repo as far as GitHub is concerned. Fix at WebAssembly/spec#2262.

@kmiller68

Copy link
Copy Markdown
Contributor

Cool, thanks for merging! The diffs will definitely help with implementation in JSC.

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.