Repository navigation
Conversation
And struct.new_default_desc. Also update the valiation for struct.new and struct.new_default to require empty descriptors. Add an explanation of expansion to desctype to the validation conventions section and teach SpecTec about the new ExpandDesc relation to avoid errors during rendering.
Update the syntax of func externtypes and func types in the typing context to include exactness. This allows specifying exact function imports and properly typing ref.func as exact for exact imports and defined functions and otherwise as inexact.
| def $exactheaptype(exact, typeuse) : heaptype | ||
|
|
||
| def $exactheaptype(EXACT, typeuse) = EXACT typeuse | ||
| def $exactheaptype(INEXACT, typeuse) = typeuse |
There was a problem hiding this comment.
Having the externtype and context store explicitly EXACT or INEXACT exactness instead of just containing an EXACT? is important for ensuring that both cases are handled everywhere. At the same time, it is annoying because heaptype has a different representation of exactness (... | typeuse | EXACT typeuse), so we require this auxiliary conversion function.
Do you have a recommendation for how to simplify this? I'm thinking that maybe we should be using heaptype instead of deftype/typeuse in the externtype and context definitions because heaptype already has exactness information built-in, and we would be able to avoid conversions that way. But then we might need a new form of expansion that can fish the type use out of both exact and inexact heap types instead :/
Previously the definition of `heaptype` was `... | EXACT typeuse | typeuse`, but this made it impossible to treat the exactness as a variable. Refactor the definition to `... | _HT exact? typeuse` instead. This is similar to how nullability is treated in reference types, except that the `_HT` tag will not be displayed in the rendered spec.
…nctype Update the typing context to store heap types for functions.
rossberg
left a comment
There was a problem hiding this comment.
Generalising the syntax of function types to arbitrary heaptypes is a bit nasty. Maybe we need an auxiliary form of type representing qualified type uses like exact? typeuse? Having a name and meta variable for that might also avoid the intrusive appearance of the _HT constructor everywhere, like in the other PR.
|
Oh interesting, I used to have an |
# Conflicts: # specification/wasm-latest/1.2-syntax.types.spectec # specification/wasm-latest/1.3-syntax.instructions.spectec # spectec/src/backend-prose/gen.ml # spectec/test-frontend/TEST.md
…nctype # Conflicts: # document/core/valid/conventions.rst # specification/wasm-latest/1.2-syntax.types.spectec # specification/wasm-latest/2.4-validation.modules.spectec # spectec/test-frontend/TEST.md
|
@rossberg, I updated the approach here to match your suggestion in #102 (review). This is ready for another look. |
| C |- FUNC x : FUNC exact? dt | ||
| -- if C.FUNCS[x] = exact? dt |
There was a problem hiding this comment.
| C |- FUNC x : FUNC exact? dt | |
| -- if C.FUNCS[x] = exact? dt | |
| C |- FUNC x : FUNC edt | |
| -- if C.FUNCS[x] = edt |
| ---- | ||
| -- if C' = {TYPES dt'*, GLOBALS gt_I*, FUNCS dt_I* dt*, REFS x*} | ||
| -- if C' = {TYPES dt'*, GLOBALS gt_I*, FUNCS edt_I* edt*, REFS x*} | ||
| -- if edt* = (EXACT dt)* |
There was a problem hiding this comment.
It would be appropriate if Func_ok itself returned the edt now, since that's what functions are classified with.
(Nice side effect: you can rename dt' to plain dt.)
| MEMS memtype*, | ||
| TABLES tabletype*, | ||
| FUNCS deftype_F*, | ||
| FUNCS edt_F*, |
There was a problem hiding this comment.
For consistency:
| FUNCS edt_F*, | |
| FUNCS exactdeftype*, |
| -- (Externaddr_ok: s |- FUNC funcaddr : FUNC exact? dt_F)* | ||
| -- if edt_F* = (exact? dt_F)* |
There was a problem hiding this comment.
| -- (Externaddr_ok: s |- FUNC funcaddr : FUNC exact? dt_F)* | |
| -- if edt_F* = (exact? dt_F)* | |
| -- (Externaddr_ok: s |- FUNC funcaddr : FUNC exactdeftype)* |
| \CMEMS & \memtype^\ast, \\ | ||
| \CTABLES & \tabletype^\ast, \\ | ||
| \CFUNCS & {\deftype'}^\ast, \\ | ||
| \CFUNCS & (\exact^?~\deftype')^\ast, \\ |
There was a problem hiding this comment.
| \CFUNCS & (\exact^?~\deftype')^\ast, \\ | |
| \CFUNCS & \exactdeftype^\ast, \\ |
| C |- FUNC deftype_1 <: FUNC deftype_2 | ||
| -- Deftype_sub: C |- deftype_1 <: deftype_2 | ||
| C |- FUNC exact_1? deftype_1 <: FUNC exact_2? deftype_2 | ||
| -- Heaptype_sub: C |- (_HT exact_1? deftype_1) <: (_HT exact_2? deftype_2) |
There was a problem hiding this comment.
| -- Heaptype_sub: C |- (_HT exact_1? deftype_1) <: (_HT exact_2? deftype_2) | |
| -- Heaptype_sub: C |- _HT exact_1? deftype_1 <: _HT exact_2? deftype_2 |
| syntax deftype hint(desc "defined type") = | ||
| | _DEF rectype n hint(show %.%) | ||
|
|
||
| syntax exactdeftype hint(desc "function type") hint(show (exact? deftype)) = exact? deftype |
There was a problem hiding this comment.
Hm, this show hint is rather hacky, it won't work correctly if somebody needs to use something like exactdeftype_i anywhere. I see that you avoid that by always expanding it out, but it would probably be cleaner if we introduced exactdeftype properly as a new type form.
| MEMS mt*, | ||
| TABLES tt*, | ||
| FUNCS dt_F*, | ||
| FUNCS edt_F*, |
There was a problem hiding this comment.
| FUNCS edt_F*, | |
| FUNCS edt*, |
| -- (Globaltype_ok: C_0 |- gt : OK)* | ||
| -- (Memtype_ok: C_0 |- mt : OK)* | ||
| -- (Tabletype_ok: C_0 |- tt : OK)* | ||
| -- if edt_F* = (exact? dt_F)* |
There was a problem hiding this comment.
| -- if edt_F* = (exact? dt_F)* | |
| -- if edt* = (exact? dt_F)* |
| -- (Resulttype_ok: C_0 |- t*: OK)* | ||
| -- (Resulttype_ok: C_0 |- t'* : OK)? | ||
| -- (if x < |dt_F*|)* | ||
| -- (if x < |edt_F*|)* |
There was a problem hiding this comment.
| -- (if x < |edt_F*|)* | |
| -- (if x < |edt*|)* |
Update the syntax of func externtypes and func types in the typing context to include exactness. This allows specifying exact function imports and properly typing ref.func as exact for exact imports and defined functions and otherwise as inexact.