Skip to content

runtime: sync() — synchronous view of WIT-sync exports (A25); getter/setter pre-ruling (CM#701) - #256

Merged
lannbot merged 1 commit into
mainfrom
sync-adapter-a25
Aug 30, 2026
Merged

runtime: sync() — synchronous view of WIT-sync exports (A25); getter/setter pre-ruling (CM#701)#256
lannbot merged 1 commit into
mainfrom
sync-adapter-a25

Conversation

@lannbot

@lannbot lannbot commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

What

Amendment A25: sync(), the explicit synchronous view of a WIT-sync export — motivated by host contexts where a Promise is useless no matter how promptly it resolves (deciding preventDefault() before an event handler returns, sort comparators, Proxy traps, JS accessors: even a resolved Promise defers observation by a microtask).

Getters/setters pre-ruling (upstream WebAssembly/component-model#701, 📡-gated, approved): contract section pinning the JS shape — export-side real accessors, sync-required both directions via A25; import-side property get/assign on the A2 receiver — so implementation is mechanical once the toolchain (wit-parser → wasm-tools → wasmtime gate → our pinned bump) catches up. Dependency chain tracked in #254. Until then the runtime refuses unknown bracket forms loudly instead of misbinding them as plain names.

How

  • Kernel: CONSTRUCTOR_SYNC_ENTRY generalized to SYNC_ENTRY on every sync-typed lifted export in jspi mode (plain mode already completes synchronously through driveSyncLift; the Promise was an embedder-layer wrapper). New SyncEntryBusy (non-poisoning, pre-enter) refuses sync entry during a jspi hop window — which also closes the constructor sync entry's latent bypass of the hop-quiescence gate (lift-corruption window).
  • Embedder: sync()/Sync<F> from @polyengine/runtime/embedder (application-tier per A22 — deliberately not protocol vocabulary; brand polyengine.syncCallable/1 in the registry). Views over export functions, resource instances (receiver-bound methods), classes (statics), and exports records (recursive, memoized, lazy async refusal). Failure ladder per A25: result<T,E> throws ComponentException synchronously; parking guests fail loudly (NeedsJspi / SyncEntryBusy / trap).
  • casing: parseLeafName refuses unknown bracket forms per the pre-ruling (found & fixed in passing: [method][get]r.p previously parsed as a method of a resource literally named [get]r).
  • Consumers: kitchen-sink §10 demonstrates the preventDefault pattern against a genuine jspi-mode instantiation; bindgen usage suite pins Sync<F> mappings over generated interfaces/classes (including the named-interface index-signature pitfall, fixed here).

Conventions goldens untouched (sync() is runtime surface, not host-ABI — protocol package deliberately untouched); no breaking labels needed (additive runtime surface).

Gates

Full just gates green (build/test-rust, test-runtime 696/0, protocol, wasi, ct-runner, sockets-node, bundle, publish-check, examples, test-translate, conformance, sched-seeds 1/4242, shells, browsers incl. worker realms, smoke-tls, smoke-c0).

Automerge armed per repo convention.

…ter/setter pre-ruling (CM#701, #254)

Amendment A25 (contracts/embedder-api.md §"Functions and async"): some
host contexts cannot use a Promise however promptly it resolves (an event
handler deciding preventDefault before it returns, a sort comparator, a
JS accessor). sync() — exported from @polyengine/runtime/embedder,
application-tier per A22 — adapts a WIT-sync export to a synchronous
call: brand-dispatched views over export functions, guest-resource
instances/classes, and exports records, riding a plain-entered SYNC_ENTRY
generalized from the constructor-only CONSTRUCTOR_SYNC_ENTRY. Failure
ladder per A25: pre-enter refusals and NeedsJspi stay non-poisoning;
new SyncEntryBusy refuses sync entry during a jspi hop window (also
closing the constructor sync entry's latent bypass of the hop-quiescence
gate); a genuinely-parking guest fails as the trap it is.

Pre-ruling for CM getters/setters (WebAssembly/component-model#701,
tracked in #254): export side will emit real JS accessors, sync-required
both directions via A25; import side dispatches as property get/assign
on the A2 receiver. Until the toolchain catches up, parseLeafName
refuses unknown bracket forms instead of misbinding them as plain names
(also fixes [method][get]r.p parsing as a method of resource '[get]r').
@lannbot
lannbot enabled auto-merge August 30, 2026 23:06
@lannbot
lannbot merged commit 2dac91f into main Aug 30, 2026
3 checks passed
@lannbot
lannbot deleted the sync-adapter-a25 branch August 30, 2026 23:10
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