Problematic sentinel value with table.grow #40
Description
Surprise, using a sentinel value (-1) for memory.grow
is coming back to bite us. For table.grow
should preferably behave analogously. and the proposal currently says that table.grow
also returns -1 (i.e., 2^32-1) in case of error. However, that does not really make sense, because we allow table sizes to span the entire u32 value range.
I can see these possible options:
-
Leave as is. Pro: symmetry with
memory.grow
; cons: quite a wart and sets a bad precedent. -
Keep -1 but disallow 2^32-1 as a table size. Pro: symmetry with memory.grow; cons: weird discontinuity, arguably backwards as a "fix", technically a breaking change
-
Use zero as a sentinel value. Pro: less arbitrary, in practice you never want to grow by 0; cons: still a bit hacky.
-
Always return previous size. Pro: no sentinel; cons: checking for error (via comparing with
table.size
afterwards) requires more work and is potentially racy in a future with shared tables. -
Return success status instead of previous size. Pro: simple and simplest to use; cons: getting old size would require separate call to
table.size
, which again is potentially racy -
Use multiple results, success status + old size. Pro: serves all purposes; cons: more complex, creates dependency on multi-value proposal
-
Return an i64. Pro: solves problem, but only for the "wasm32" equivalent of tables; cons: does not avoid sentinel, coherence would suggest to make table size an i64 everywhere
@binji, @lukewagner, @lars-t-hansen, @titzer, I am probably leaning towards option 5 (Boolean result), but would like to hear your opinions. Is there a strong use case for getting the old size atomically? In general, I would be inclined to avoid sentinel values.