WebAssembly / stringref

Other
37 stars 2 forks source link

Define JS API #13

Open wingo opened 2 years ago

wingo commented 2 years ago

The MVP should probably define a JS API. AFAIU the work needed is to define a mapping between globals, tables, and function parameters and results of type stringref, stringview_wtf8, stringview_wtf16, and stringview_iter.

Current sloppily specified strawperson:

  1. You cannot convert stringview_wtf8, stringview_wtf16, or stringview_iter values to JS. Attempting to access the value of such an exported global throws. There is no value you can pass to a WebAssembly.Global constructor that would succeed. Same for tables. Calling a function that takes a stringview parameter or returns a stringview result throws before the function is called; like it used to be for i64.
  2. The set of JS representations of stringref values is the set of JS strings, plus JS null.
  3. There is no default value for a stringref. If a stringref argument is not supplied, that's an error.
  4. There are no implicitly/automatically applied conversions: no ToString on numeric values passed as stringref arguments, for example.

Regarding (3), perhaps we should default to null when a JS value isn't given, as ref.null string is the default value on the wasm side, because stringref is nullable. Not sure!

Jamesernator commented 2 years ago

Regarding (3), perhaps we should default to null when a JS value isn't given, as ref.null string is the default value on the wasm side, because stringref is nullable. Not sure!

That makes more sense as other nullable types already work that way.

While typed func references and gc aren't completely fleshed out presumably we'd have a non-nullable variant string with stringref being remapped to stringref = (ref null string) like all the other nullable types in those proposals. Such a type wouldn't have any initial value, similar to other non-nullable types in those proposals.

wingo commented 2 years ago

Another thing to do in the JS API is to define limits (https://webassembly.github.io/spec/js-api/index.html#limits). Strawperson would be a limit of 1000000 (one million) string literals. No limit on string sizes though; the module size limit of 1 GB is sufficient.

jakobkummerow commented 2 years ago

No limit on string sizes though; the module size limit of 1 GB is sufficient.

LGTM, if we agree (and maybe formally point out?) that engines may in practice have smaller limits on individual string sizes; so while they might not statically reject a 1GiB string literal with a CompileError, they'll instead fail to allocate such a string with a RuntimeError. I'm not sure whether that's preferable over a lowest-common-denominator static limit...

(For reference, in V8, we currently even have different limits for 32-bit and 64-bit builds: (1 << 28) - 16 (~268M) or (1 << 29) - 24 (~536M) WTF-16 code units, respectively. I don't think we'll be able to change that any time soon: while we'd love to support bigger strings, that's limited by technical constraints, whereas lower limits would make certain use cases unhappy.)

wingo commented 2 years ago

I think it might make sense to allow statically rejecting strings whose length exceeds implementation limits. Less surprise for the user, and just as cheap, given that you are validating already.