Zero-glue platform classes: pattern doc, parity pins, accessor-safe A2 probe - #117
Merged
Conversation
…2 probe The #686-inspired pattern — satisfy a WIT resource import by passing a native platform class directly — already works here for method-shaped interfaces; claim it and pin its limits (deltic#115 tracks the upstream draft): - contracts/embedder-api.md: non-normative "binding platform classes directly" subsection under Resources — the pattern, the executable reference, and the three limits with their one-line bridges (getter- backed properties trap per-call; platform null is not WIT none, the conversion TypeError names the import; platform exceptions are unbranded and trap even from result-typed imports, only ComponentException crosses as err). - runtime/tests/embedder/platform_class_test.ts + platform-class.wat: characterization pins against native URLSearchParams/TextDecoder with no wrapper — happy path (ctor args, kebab->camel toString, string/ bool/list<u8>/record conversions, BufferSource compatibility), each limit's exact failure class + wording, and the wrapper recipe turning a native throw into a WIT err. Fixture note: wasmparser requires records referenced by imported functions to be NAMED type exports of the importing instance (all_valtypes_named_in_func). - runtime/src/embedder/instantiate.ts: the A2 wrap-time suspending probe now reads only DATA properties (descriptor walk, dataMember) — the old raw prototype read invoked platform getters with this = prototype, so binding URLSearchParams exploded at INSTANTIATION with Deno's brand-check TypeError, even for guests that never touch the getter- backed member. Accessor-backed members are now a per-call concern with the documented named Trap; an A2 mark cannot ride an accessor (doc'd).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Track 3 from the #686 evaluation (watchlist: #115): claim the draft web embedding's best ergonomic idea — satisfying a WIT resource import by passing a native platform class directly — which deltic's existing semantics already support for method-shaped interfaces, and pin its limits as executable characterization.
Doc (contracts/embedder-api.md, non-normative subsection under Resources): the pattern, the executable reference, and the three limits each with a one-line
extends Nativebridge:null≠ WITnone→ conversion-layer TypeError naming the import (not a trap, nevernone);throw new ComponentException(payload)crosses aserr.Test (runtime/tests/embedder/platform_class_test.ts + platform-class.wat): native
URLSearchParams/TextDecoderbound with zero glue — happy path proves ctor args, kebab→camel (to-string→toString), string/bool/list<u8>/record conversions and BufferSource compatibility; then each limit's exact failure class and pinned wording; then the wrapper recipe (subclass try/catch →ComponentException) flipping the same native failure into the guest'serrcase. Wat-authoring note: wasmparser'sall_valtypes_named_in_funcrequires records referenced by imported functions to be named type exports of the importing instance.Runtime fix (instantiate.ts): the A2 wrap-time suspending probe now walks descriptors and reads only data properties. The previous raw
prototype[member]read invoked platform getters withthis = prototype, so bindingURLSearchParamsfailed at instantiation with Deno's brand-check TypeError — even for guests that never call the getter-backed member. Now accessor-backed members are a per-call concern with the documented named Trap, and an A2 suspending mark cannot ride an accessor (documented).Characterization delta worth a look: a malformed host return value (limit 2) surfaces as a per-call TypeError without poisoning the instance, while an unbranded host throw traps and poisons. Defensible asymmetry, but if we ever want conversion failures to trap like host throws, that's a contract question — flagging, not changing.
Gates: full
just gatesgreen (runtime 489/0 incl. the 5 new pins, conformance 1254/0, seeds, sm/node/bun shells, chromium+firefox, websocket-conformance 55/0, smoke legs).