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

Fix nullability for string constants and let namespace be chosen #29

Merged
merged 4 commits into from
Jun 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions proposals/js-string-builtins/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,41 @@ The simplest way is to have a module import each string as an immutable global.

This proposal adds an extension to the JS-API compile routine to support optimized 'imported string constants' to address this use-case.

The `WebAssemblyCompileOptions` dictionary is extended with a `boolean importedStringConstants` flag. When this is set, the module may define imports of the form `(import "'" "%stringConstant%"" (global externref))`, and the JS-API will use the provided `%stringConstant%` import field name to be the value of the global. This allows for any UTF-8 string to be imported with minimal overhead.
The `WebAssemblyCompileOptions` dictionary is extended with a `USVString? importedStringConstants` flag.

The string namespace is chosen to be the single quote ASCII character `'`. We may revise this to be a longer name before this proposal is finalized.
```
partial dictionary WebAssemblyCompileOptions {
USVString? importedStringConstants;
}
```

When this is set to a non-null value, the module may import globals of the form `(import "%importedStringConstants%" "%stringConstant%"" (global ...))`, and the JS-API will use the provided `%stringConstant%` import field name to be the value of the global. This allows for any UTF-8 string to be imported with minimal overhead.

### Example

```wasm
(module
(global (import "strings" "my string constant") (ref extern))
(export "constant" (global 0))
)
```

```js
let instance = WebAssembly.instantiate(bytes, {importedStringConstants: "strings"});

// The global is automatically populated with the string constant
assertEq(instance.exports.constant.value, "my string constant");
```

### Details

When `importedStringConstants` is non-null, the specified string becomes the `imported string namespace`.

During the ['compile a module'](https://webassembly.github.io/spec/js-api/index.html#compile-a-webassembly-module) step of the JS-API, the imports of the module are examined to see which refer to the imported string namespace. If an import refers to the imported string namespace, then the import type is [matched](https://webassembly.github.io/spec/core/valid/types.html#globals) against an extern type of `(global (ref extern))`. If an import fails to match, then 'compile a module' fails. The resulting module is associated with the imported string namespace for use during instantiation.

During the ['read the imports'](https://webassembly.github.io/spec/js-api/index.html#read-the-imports) step of the JS-API, if the module has an imported string namespace, then every import that refers to this namespace has a global created to hold the string constant specified in the import field. This global is added to the imports object. If all imports in a module are from the imported string namespace, no import object needs to be provided.

All imports that reference this namespace must be globals of type immutable externref. If they are not, an eager compile error is emitted.
When the imports object is used during ['instantiate a module'](https://webassembly.github.io/spec/js-api/index.html#instantiate-the-core-of-a-webassembly-module), these implicitly created globals should never cause a link error due to the eager matching done in 'compile a module'.

## JS String Builtin API

Expand Down