Skip to content

馃獧 Value text encoding ambiguities / quirks聽#718

Closed

Description

@lann

In looking at WAVE mapping to value defs (ref #639 (comment)) I found some quirks in the val rules:

  • char
    • Allows unescaped single quote (value char '''), which is unambiguous in context but seems awkward to parse and confusing to read (especially if you're used to Python!).
    • Rejects unescaped double-quote ('"'), which is slightly annoying to me, personally. 馃檪
  • floats
    • f32 is encoded as core:f64 which leaves rounding and overflow ambiguous, e.g. core:f64 accepts 1e99 which will overflow an f32.
    • f64canon rejects nan:0x but not -nan
  • Handles in variants:
    • Currently this would seem to be valid: (value (option (future)) none), which is at least surprising if not actually wrong.
  • Ints:
    • Depending on how I squint it looks like (value u64 -1) might be valid via core:i64 (wrapping to u64::MAX).

Separately: the bottom of the value definitions section describes value imports/exports but the import/export defs are missing matching rules. Nope, I was looking in the wrong place.

Activity

  1. changed the title [-]Value 馃獧 text encoding ambiguities / quirks[/-] [+]馃獧 Value text encoding ambiguities / quirks[/+] on Sep 9, 2026
  2. lukewagner commented on Sep 9, 2026

    @lukewagner
    Member

    Great points!

    • char: given that we're type-directed (towards char-vs-string), I suppose the fix is to switch '<core:stringchar>' to "<core:stringchar>" (which makes sense; core:stringchar is meant to be used inside double-quotes in core wasm)
    • floats: I suppose the fix is to add an f32canon and indicate that only fXXcanon matches fXX, and also rule out -nan
    • handles in variants: I suppose the fix is to stipulate the valtype of a value may not contain handle or async types, before even considering whether the val matches the type.
    • Ints: I think this comes down to what we mean by the current hand-wavy sentence "The validation rules for value require the val to match the valtype". Since we have explicitly-signed u64/s64 types at the component-level (unlike i64 which is sign-agnostic), I suppose this justifies a break from core wasm (which allows (i64.const -1)) and so we should reject any integer outside of the natural range of {s,u}{8,16,32,64} that would otherwise require wrapping.
    • For import/export, unless I'm missing something, because value is in componentsort, it goes included in externidx; it's also explicitly in externtype, so I think it shows up as needed in import/export, but let me know if I'm missing something.

    Happy if anyone wants to write these (or better) fixes in a PR; otherwise I can in a bit.

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

Metadata

Metadata

Assignees

No one assigned

    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