Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Future extension: builtin string type import #26

Open
tlively opened this issue Mar 27, 2024 · 2 comments
Open

Future extension: builtin string type import #26

tlively opened this issue Mar 27, 2024 · 2 comments

Comments

@tlively
Copy link
Member

tlively commented Mar 27, 2024

In a future with type imports, we could add a builtin subtype of extern representing JS strings importable as something like (import "wasm:js-string" "string" (type $string (sub extern))). We could then allow the builtin operations to be imported with signatures that accept and return $string references instead of extern references. The benefit of this additional static typing would be that engines would be able to skip the check that the inputs to the builtin operations are actually strings, since the type system would prove that they must be.

Does that seem like a reasonable future direction? Are there any foreseeable problems with it?

@jakobkummerow
Copy link
Contributor

Sure, that'd be nice to have.

It'll be more complicated to implement for engines and tools than a non-imported type in the core Wasm spec, but that's nothing new for this proposal.

A certain wrinkle is the fact that importing functions with more specific signatures is not exactly backwards-compatible (even though in this particular case for most practically-relevant cases it probably will happen to be compatible by sheer luck). So to maintain 100% formal backwards compatibility (which will probably be a requirement), this will effectively double the number of supported imports.

Note that to make the mechanism actually generic/polyfillable (for engines that don't implement built-in strings), a type checking function will have to be imported along with the type, to allow such engines to check that a value passed across the boundary (or an externref value being downcast to $string) does actually have that imported string type. Depending on how exactly that mechanism is spec'ed, it may cause further complexity even for engines that do support built-in strings.

@eqrion
Copy link
Collaborator

eqrion commented Mar 29, 2024

Yes, I think we need to have a plan for type imports (although not completely possible without a full type imports design).

My sketch plan for the type import was:

  1. Define a WebAssembly.StringType as the JS-API representation of the type import
  2. Add a "wasm:js-string" "type" field that can be imported (sub externref)

Then one of three options seems possible for the functions:

  1. Refine the function type's using covariant result subtyping.
  (import "wasm:js-string" "string" (type $string (sub extern)))

  (type $originalCastType
    (sub (func
      (param externref)
      (result (ref extern))))

  (type $refinedCastType (sub $originalCastType
    (func
       (param externref)
       (result (ref $string))))

This would cover all of the builtins that generate strings, but not the consumers, which is unfortunate. The advantage is just that this approach is very simple. I haven't found a way to make this work for params.

  1. Duplicate the set of builtins with a new name that indicates opt-in to using type imports. e.g. "cast" -> "cast-typed". Or "wasm:js-string" -> "wasm:js-string-typed".
  2. Inspect the function imports of a module to determine which set of builtins to provide. e.g. If a module imports the 'string' type, then provide it the stricter typed builtin functions instead of the generic typed versions.

I think (3) is probably the nicest, but is maybe a little odd. (2) would probably be the fallback then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants