Add Component Model composite ValType wrappers: list / record / tuple / enum / flags#283
Open
glassmonkey wants to merge 6 commits into
Open
Add Component Model composite ValType wrappers: list / record / tuple / enum / flags#283glassmonkey wants to merge 6 commits into
glassmonkey wants to merge 6 commits into
Conversation
…m/flags Continues the type-hierarchy work from bytecodealliance#282 by exposing payload accessors for the product/enum composite kinds: list, record, tuple, enum, flags. Each ships as a Go wrapper type with the C API's count/nth-style accessors (plus list/record's element/field types via independent ComponentValType clones, matching ComponentItem.TypeAlias()): - ComponentListType (Element) - ComponentRecordType (FieldCount / FieldNth) - ComponentTupleType (TypesCount / TypesNth) - ComponentEnumType (NamesCount / NamesNth) - ComponentFlagsType (NamesCount / NamesNth) ComponentValType gains a downcast method per kind (List, Record, Tuple, Enum, Flags) returning nil for any other kind. The corresponding five ComponentValTypeKind* constants -- commented out in bytecodealliance#282 -- are now uncommented. Out of scope for this slice (per the roadmap split): variant / option / result (sum types, deferred to share a focused PR with their value marshaling), resource own/borrow, future/stream/error-context/map, and value-side marshaling for the kinds added here. Verified: go build ./..., go test ./..., go test -tags debug ./..., go vet ./..., gofmt -l . -- all clean. 14 new test functions.
Aligns the Tuple/Enum/Flags accessors with the singular noun + Count/Nth
pattern already established by ComponentType.{Import,Export}{Count,Nth}
and the record-side FieldCount/FieldNth added in this slice:
- ComponentTupleType: TypesCount/TypesNth -> TypeCount/TypeNth
- ComponentEnumType: NamesCount/NamesNth -> CaseCount/CaseNth
- ComponentFlagsType: NamesCount/NamesNth -> FlagCount/FlagNth
CaseNth/FlagNth also pick the WIT-domain term (enum "cases", flags
"flags") over the C API's generic "_names_nth", matching how FieldNth
uses the WIT term "field".
Two adjustments to align with the test names established in component_type_feat_component_model_test.go: 1. Fix stale method names left from the previous rename commit (TupleType.TypesNth -> TypeNth, EnumType.NamesNth -> CaseNth, FlagsType.NamesNth -> FlagNth): - TupleTypesNthOutOfRange -> TupleTypeNthOutOfRange - EnumNamesNthOutOfRange -> EnumCaseNthOutOfRange - FlagsNamesNthOutOfRange -> FlagsFlagNthOutOfRange 2. Switch the wrong-kind tests from "<Method>OnNon<X>ReturnsNil" to "<Method>ReturnsNilForNon<X>Kind", matching the only existing precedent (TestComponentItemTypeAliasReturnsNilForNonTypeKind): - ListOnNonListReturnsNil -> ListReturnsNilForNonListKind - RecordOnNonRecordReturnsNil -> RecordReturnsNilForNonRecordKind - TupleOnNonTupleReturnsNil -> TupleReturnsNilForNonTupleKind - EnumOnNonEnumReturnsNil -> EnumReturnsNilForNonEnumKind - FlagsOnNonFlagsReturnsNil -> FlagsReturnsNilForNonFlagsKind
Pre-existing wasmtime-go test files (e.g. functype_test.go, importtype_test.go, valtype_test.go) follow a "one test per type, multiple inline assertions" pattern. The previous V1 layout (14 tests split by kind x variation axis with OutOfRange / ReturnsNilForNon<X>Kind suffixes) was modeled on the recently-merged bytecodealliance#282 component tests, which have diverged from that pre-existing canonical style. Collapse to 5 tests, one per composite kind. Each test covers happy path + index-out-of-range (where applicable) + wrong-kind-returns-nil inline. Net: 224 -> 65 lines.
- ComponentValTypeKind doc: drop the slice-scope narrative; the kind set is already self-documenting from the constants below. - Commented-out-kinds note: collapse to one line; the rationale lives in the PR description, not in the source. - Downcast lifecycle note: move the "independently-owned wrapper" remark from ComponentValType.List's per-method comment up to the type-level doc, since it applies to every downcast (List/Record/Tuple/Enum/Flags). - Tests: replace the five copy-pasted "X() returns nil on a non-X kind" blocks with a single TestComponentValTypeDowncastNilForOtherKinds that probes all five downcasts against a u32 type alias.
b580910 to
12cd8cd
Compare
…time-go style
externtype.go already exposes the same pattern (ExternType.FuncType /
GlobalType / TableType / MemoryType: return the underlying type for the
matching kind, nil otherwise) but uses different conventions than the
ones this slice originally adopted:
- Doc wording: existing methods say "returns the underlying X ... if
it's a Y type. Otherwise returns nil." -- not "downcast method".
- Test shape: TestFuncType asserts NotNil for the matching accessor
and Nil for every other accessor inline, not via a separate
cross-kind test function.
Adjust this slice to match:
- Drop the "downcast" framing from the ComponentValType type comment
and from each composite accessor's doc; switch to the
"returns the underlying X if this is a Y type. Otherwise returns
nil." form, in one line.
- Compress the ComponentValType type comment from 6 lines to 4.
- Move the "other-kind accessors return nil" assertions from a
dedicated TestComponentValTypeDowncastNilForOtherKinds into each
of the five per-kind tests inline, mirroring TestFuncType. The
dedicated test is removed.
alexcrichton
approved these changes
May 23, 2026
| var nameLen C.size_t | ||
| var out C.wasmtime_component_valtype_t | ||
| found := C.wasmtime_component_record_type_field_nth(rt.ptr(), C.size_t(i), &nameP, &nameLen, &out) | ||
| runtime.KeepAlive(rt) |
Member
There was a problem hiding this comment.
This'll want to be below the C.GoStringN call below because the rt value owns the returned string and needs to stay alive
| var nameP *C.char | ||
| var nameLen C.size_t | ||
| found := C.wasmtime_component_enum_type_names_nth(et.ptr(), C.size_t(i), &nameP, &nameLen) | ||
| runtime.KeepAlive(et) |
Member
There was a problem hiding this comment.
Similar to above, this needs to be below the GoStringN call
| var nameP *C.char | ||
| var nameLen C.size_t | ||
| found := C.wasmtime_component_flags_type_names_nth(ft.ptr(), C.size_t(i), &nameP, &nameLen) | ||
| runtime.KeepAlive(ft) |
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.
Continues the type-hierarchy work from #282 by exposing payload accessors for the product/enum composite kinds (list, record, tuple, enum, flags). Follow-up to #282 (merged). Tracks #280.
Summary
Each composite kind ships as a Go wrapper type with count/nth-style accessors mirroring the underlying C API:
ComponentListType(Element)ComponentRecordType(FieldCount/FieldNth)ComponentTupleType(TypeCount/TypeNth)ComponentEnumType(CaseCount/CaseNth)ComponentFlagsType(FlagCount/FlagNth)For enum/flags, the C API's generic
names_count/names_nthare renamed to the WIT-domain terms (case,flag); record/tuple already use WIT terms (field/type).ComponentValTypegains a downcast method per kind (List,Record,Tuple,Enum,Flags) returningnilfor any other kind. The corresponding fiveComponentValTypeKind*constants — commented out in #282 — are now uncommented. Downcast methods return independently-owned wrappers (the C API exposes*_clonehelpers used internally), so each wrapper has its own lifecycle andClose().Out of scope (next slices)
variant/option/result(sum types) — deferred to share a focused PR with their value marshalingown/borrowresources,future/stream/error-context/mapComponentFuncTypeStyle notes
New tests follow the #282 review feedback (individual test functions over
casesslice, nonewComponenthelper, minimal comments). Existing tests are intentionally not touched.Open question
Tuple's accessor pair is currently
TypeCount/TypeNth(i). Happy to rename toElement(i)/ElementCount(or similar) if you'd prefer wording that disambiguates "the tuple's element types" from "the tuple type itself".Verified
go build ./...cleango test ./...andgo test -tags debug ./...passgo vet ./...cleangofmt -l .clean