WebAssembly/js-string-builtins

Add method to test if an external reference is a string

Jamesernator opened this issue · 4 comments

So the current proposal types all strings as externref, given that all the builtin methods trap if they don't receive strings, and that JS may well call webassembly methods with a non-string reference, it would be helpful to be able to determine that an externref is in fact a string before passing it to the other methods.

I would propose the simple addition:

// WebAssembly.String.isString
func isString(ref: externref) -> i32 {
    return typeof ref === "string" ? 1 : 0;
}

Alternatively it might be worth actually typing string that way even calls into WASM from JS would ensure that references are in fact strings.

Once we have type imports and an importable string type, Wasm will presumably be able to use a built-in cast mechanism similar to ref.test from the GC proposal to check whether an arbitrary externref is an imported string, so in that future this method will be unnecessary. If there is a pressing need for this functionality before we get type imports, it may still be worth it to add this method, though.

@tlively Is it expected that we can ref.test $t where $t is an imported type? I'm not sure how we could implement that, because the kind of test we'd do for checking if a reference is a JS string (or other host type imports) would be different from if a reference is some GC struct.

This is all TBD once we have a design for type imports, of course, but I am imagining that WebAssembly.String would be a subtype of extern, so the type import would look something like (type $string (import "string") (sub extern)), then ref.test (ref $string) would have type [externref] -> [i32]. This seems like a natural extension of how ref.test currently works, where you can have ref.test nullexternref with type [externref] -> [i32]. The only complication is that perhaps we would require RTTs to get involved.

It's ok that the type check is operationally different from a type check in the any hierarchy since you will know at compile time that $string will be in the extern hierarchy rather than the any hierarchy.

This was added in #8. See here.