Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Problematic sentinel value with table.grow #40

Closed

Description

@rossberg

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:

  1. Leave as is. Pro: symmetry with memory.grow; cons: quite a wart and sets a bad precedent.

  2. 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

  3. Use zero as a sentinel value. Pro: less arbitrary, in practice you never want to grow by 0; cons: still a bit hacky.

  4. 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.

  5. 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

  6. Use multiple results, success status + old size. Pro: serves all purposes; cons: more complex, creates dependency on multi-value proposal

  7. 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.

Activity

  1. AndrewScheidecker commented on Apr 23, 2019

    @AndrewScheidecker
    Contributor

    Regarding option 6: instead of adding a dependency on the multi-value proposal, this proposal could just clone the part of the multi-value proposal that generalizes instructions to yield more than one value; that's a simple and non-controversial part of that proposal, and all that's necessary for table.grow to yield 2 results in this proposal.

  2. lars-t-hansen commented on Apr 23, 2019

    @lars-t-hansen
    Contributor

    So... we have a MaxTableLength of 1e7. I thought this limit was generally agreed upon since WebAssembly/spec#873. Doesn't that prevent this from being an issue?

  3. rossberg commented on Apr 23, 2019

    @rossberg
    MemberAuthor

    @lars-t-hansen, that's a web-specific limit, not one inherent to Wasm per se.

  4. lars-t-hansen commented on Apr 23, 2019

    @lars-t-hansen
    Contributor

    OK, fair point about the web embedding.

    The size of a table is limited to what table.size can return, ie, 2^32-1. The only time table.grow can be called on a table and return 2^32-1 and that can be not-an-error is when the table size is already 2^32-1 and the delta is zero.

    My preference here would actually be to choose (1) because it fits the current design, and then, once we have multi-value and/or exceptions and/or shared tables, revisit both memory.grow and table.grow to see if there are more principled solutions.

    In a similar but not quite analogous situation, we chose to trap (WebAssembly/threads#72). We could do that here too.

  5. binji commented on Apr 23, 2019

    @binji
    Member

    I prefer (1) or (6) (w/ @AndrewScheidecker's modification). Mostly because I prefer the symmetry w/ memory.grow and want to avoid raciness.

  6. titzer commented on Apr 29, 2019

    @titzer
  7. rossberg commented on May 2, 2019

    @rossberg
    MemberAuthor

    @titzer, I'm not sure I understand your comment re option (6). It does not change the definition of what is a "successful" grow nor whether Wasm code can observe that result, so any such weirdness is no different than with the other options.

  8. self-assigned this
    on May 8, 2019
  9. rossberg commented on Jan 16, 2020

    @rossberg
    MemberAuthor

    The majority voice seems to be to leave the wart alone, so I'm closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions