Closed fitzgen closed 1 month ago
As I pointed out elsewhere, we want to factor "composite" types as something like
shcomptype ::= shared? comptype
comptype ::= func ... | struct ... | array ...
because that's the only factorisation that makes sense semantically and works in rules that need to decompose such types.
In a similar vein, it should be consistent for all "external" types (func, memory, table, global). And that clearly demands that shared
shouldn't go into the middle of some of these.
I'd suggest
functype ::= shared? param* result*
globaltype ::= shared? mut? valtype
memtype ::= shared? idxtype? limits pagetype?
tabletype ::= shared? idxtype? limits reftype
Unfortunately, the threads proposal currently puts it last for memory types — perhaps it's not too late to tweak that in its text format? If not, we could either allow both forms for backwards compatibility, or we consistently put shared
last for all types (which I find less natural).
[Maybe this issue should be migrated to the shared-everything proposal repo, since the question is a bit broader than just shared vs page size.]
The text format generally has the property that parsing the first keyword after an open paren is enough to tell you what it is you're parsing; there's usually no need for further lookahead. Although having shared
at the beginning in the abstract syntax makes sense, putting it at the beginning in the text format means we need to look ahead to the next keyword to see what's being parsed. That's not the end of the world, but it is enough that I prefer the existing text format for shared memories.
[@fitzgen, if you're ok with it, I'd be happy to transfer this to the shared-everything-threads repo]
@tlively, I don't think anything changes in that regard. External types already do not have a specific keyword, e.g. mem and table types both start with just limits currently. For composite types, you still have the keyword in front: assuming the parser follows the same factorisation, it just adds another level of common prefix around them; we already have optional rec
and sub
, and now also add shared
in the same manner.
(Seems fine to transfer this issue, since it is more general than this particular proposal, and will get more eyes in the shared-everything-threads repo. Also I don't have permissions to do that transfer, so someone else would have to.)
@rossberg, I see, so we would have (shared (global ...))
and (shared (table ...))
and (shared (struct ...))
and (shared (array ...))
and (shared (func ...))
?
Presumably we would want to add (shared (memory ...))
as an alternative to the existing shared memory syntax?
Also, something I've been thinking about: inside a global type of a reference, e.g., are we really going to write something like (global (shared mut (ref shared null any)) ...)
? Or would the shared ref-type be (shared ref null any)
== (shared anyref)
?
I've been imagining (shared anyref)
== (shared (ref null any))
.
It would be good to get this figured out and written down in the overview!
Oh wait, I forgot that shared
applies to heap types, not reference types. So it should be (shared anyref)
== (ref null (shared any))
. Sorry about that!
From the shared-everything threads proposal's point of view, I think this is settled now that we've documented that the shared
attribute goes first and the legacy syntax is an abbreviation. I guess the ball is now in the custom page size proposal's court to figure out how they want to fit into that. @fitzgen, should we close this or transfer it back to the custom page size proposal?
If the shared
attribute comes first, before the memory's limits, then I don't think there is anything left to figure out, since the (pagesize ...)
comes after the limits.
Cool, I'll close this as resolved, then.
@conrad-watt brought this question up in today's CG meeting: should the
(pagesize n)
come before or aftershared
?FWIW, my prototype implementation has
shared
come before(pagesize n)
right now. All else being equal, I'd propose we move forward with that.