@@ -56,12 +56,18 @@ data WasmPrimitive
5656-- Example: List elem =
5757-- WHT_Rec (WHT_Struct [("head", WVT_Ref elem), ("tail", WVT_RefNull (WHT_Var 0))])
5858-- which is the WasmGC type μX. (struct (field (ref elem)) (field (ref null X)))
59+ --
60+ -- WHT_Any is the WasmGC top reference type (`any` in the spec). All struct,
61+ -- array, and i31 references are subtypes of `any`. It is used as the payload
62+ -- type in `resultLayout` (a `Result T E` stores its payload as `(ref any)` and
63+ -- casts to the concrete T or E at the use site).
5964data WasmHeapType
6065 = WHT_Array WasmValType -- (array <valtype>)
6166 | WHT_Struct (List (String , WasmValType )) -- (struct (field ...))
6267 | WHT_Func (List WasmValType ) (List WasmValType ) -- (func (param ...) (result ...))
6368 | WHT_Var Nat -- bound type variable (de Bruijn index)
6469 | WHT_Rec WasmHeapType -- μ-binder: (rec <heaptype>)
70+ | WHT_Any -- top reference type: (any)
6571
6672-- | A WasmGC value type — either a primitive or a typed reference.
6773data WasmValType
@@ -92,9 +98,10 @@ optionLayout t = WVT_RefNull t
9298||| Field 1: payload as (ref any) — cast to concrete T or E at use site.
9399resultLayout : WasmValType
94100resultLayout =
95- WVT_Ref (WHT_Struct [(" tag" , WVT_Prim WasmI32 ), (" payload" , WVT_Ref (WHT_Struct []))])
96- -- Note: placeholder payload uses an empty struct; a `WasmExtern` constructor
97- -- will replace it when WasmGC's `any`/`extern` reference types are modelled.
101+ WVT_Ref (WHT_Struct [(" tag" , WVT_Prim WasmI32 ), (" payload" , WVT_Ref WHT_Any )])
102+ -- Payload is (ref any): the concrete T or E is recovered by a checked downcast
103+ -- at the use site. WHT_Any is the WasmGC top reference type — all structs and
104+ -- arrays are subtypes, so this is the canonical encoding for a sum-type payload.
98105
99106-- ─────────────────────────────────────────────────────────────────────────────
100107-- DecEq instances
@@ -198,6 +205,18 @@ mutual
198205 decEq (WHT_Array _ ) (WHT_Rec _ ) = No (\ case Refl impossible)
199206 decEq (WHT_Struct _ ) (WHT_Rec _ ) = No (\ case Refl impossible)
200207 decEq (WHT_Func _ _ ) (WHT_Rec _ ) = No (\ case Refl impossible)
208+ -- WHT_Any — nullary constructor; equal only to itself
209+ decEq WHT_Any WHT_Any = Yes Refl
210+ decEq WHT_Any (WHT_Array _ ) = No (\ case Refl impossible)
211+ decEq WHT_Any (WHT_Struct _ ) = No (\ case Refl impossible)
212+ decEq WHT_Any (WHT_Func _ _ ) = No (\ case Refl impossible)
213+ decEq WHT_Any (WHT_Var _ ) = No (\ case Refl impossible)
214+ decEq WHT_Any (WHT_Rec _ ) = No (\ case Refl impossible)
215+ decEq (WHT_Array _ ) WHT_Any = No (\ case Refl impossible)
216+ decEq (WHT_Struct _ ) WHT_Any = No (\ case Refl impossible)
217+ decEq (WHT_Func _ _ ) WHT_Any = No (\ case Refl impossible)
218+ decEq (WHT_Var _ ) WHT_Any = No (\ case Refl impossible)
219+ decEq (WHT_Rec _ ) WHT_Any = No (\ case Refl impossible)
201220
202221 DecEq WasmValType where
203222 decEq (WVT_Prim p1) (WVT_Prim p2) with (decEq p1 p2)
@@ -289,3 +308,21 @@ varInjective _ _ Refl = Refl
289308||| WHT_Rec is injective: equal bodies give equal recursive types.
290309recInjective : (h1 h2 : WasmHeapType) -> WHT_Rec h1 = WHT_Rec h2 -> h1 = h2
291310recInjective _ _ Refl = Refl
311+
312+ ||| WHT_Any is not an array, struct, func, var, or recursive type.
313+ ||| Prevents any code from treating the top type as a concrete layout.
314+ anyNotArray : (v : WasmValType) -> WHT_Any = WHT_Array v -> Void
315+ anyNotArray _ Refl impossible
316+ anyNotStruct : (fs : List (String, WasmValType)) -> WHT_Any = WHT_Struct fs -> Void
317+ anyNotStruct _ Refl impossible
318+ anyNotFunc : (ps rs : List WasmValType) -> WHT_Any = WHT_Func ps rs -> Void
319+ anyNotFunc _ _ Refl impossible
320+ anyNotVar : (n : Nat ) -> WHT_Any = WHT_Var n -> Void
321+ anyNotVar _ Refl impossible
322+ anyNotRec : (h : WasmHeapType) -> WHT_Any = WHT_Rec h -> Void
323+ anyNotRec _ Refl impossible
324+
325+ ||| `resultLayout` payload uses (ref any): correct WasmGC encoding.
326+ resultPayloadIsAny
327+ : resultLayout = WVT_Ref (WHT_Struct [(" tag" , WVT_Prim WasmI32 ), (" payload" , WVT_Ref WHT_Any )])
328+ resultPayloadIsAny = Refl
0 commit comments