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

[Wasm] Add option to use js-string-builtins for using JS string to implement string #4994

Open
tanishiking opened this issue Jun 3, 2024 · 0 comments
Assignees
Labels
enhancement Feature request (that does not concern language semantics, see "language") wasm Applies to the WebAssembly backend only

Comments

@tanishiking
Copy link
Contributor

tanishiking commented Jun 3, 2024

In future (at least after seeing how it goes after the origin trial on Chrome), it might be a good idea to introduce an option like useExperimentalJSStringBuiltins, and if this option is turned ON, generate a WebAssembly module that implements JavaScript string operations using the js-string-builtins proposals.

What is the js-string-builtins proposal

The js-string-builtin proposal aims to improve the efficiency of string operations by allowing us to directly use a subset of the JS String API through built-in WebAssembly functions. These builtin functions can be efficiently called from within WebAssembly modules without the need for JS glue code, the implementations are provided by the Wasm runtime. (This import mechanism is said to be more efficient than regular imports)

We can use these builtin functions by giving a WebAssemblyCompileOptions like this:

WebAssembly.compile(bytes, { builtins: ['js-string'] });

The builtin functions include (from|into)CharCodeArray to convert i16array <=> externref (js string), cast, test, and so on

(This proposal also provides a way to encode/decode UTF-8 strings through wasm:text-encoder and wasm:text-decoder)

Why

For example, instead of converting individual character codes using String.fromCharCode and concatenating them in genCreateStringFromData

/** `createStringFromData: (ref array u16) -> (ref any)` (representing a `string`). */
private def genCreateStringFromData()(implicit ctx: WasmContext): Unit = {
val dataType = RefType(genTypeID.i16Array)
val fb = newFunctionBuilder(genFunctionID.createStringFromData)
val dataParam = fb.addParam("data", dataType)
fb.setResultType(RefType.any)
val lenLocal = fb.addLocal("len", Int32)
val iLocal = fb.addLocal("i", Int32)
val resultLocal = fb.addLocal("result", RefType.any)
// len := data.length
fb = LocalGet(dataParam)
fb = ArrayLen
fb = LocalSet(lenLocal)
// i := 0
fb = I32Const(0)
fb = LocalSet(iLocal)
// result := ""
fb = GlobalGet(genGlobalID.emptyString)
fb = LocalSet(resultLocal)
fb.loop() { labelLoop =>
// if i == len
fb = LocalGet(iLocal)
fb = LocalGet(lenLocal)
fb = I32Eq
fb.ifThen() {
// then return result
fb = LocalGet(resultLocal)
fb = Return
}
// result := concat(result, charToString(data(i)))
fb = LocalGet(resultLocal)
fb = LocalGet(dataParam)
fb = LocalGet(iLocal)
fb = ArrayGetU(genTypeID.i16Array)
fb = Call(genFunctionID.charToString)
fb = Call(genFunctionID.stringConcat)
fb = LocalSet(resultLocal)
// i := i - 1
fb = LocalGet(iLocal)
fb = I32Const(1)
fb = I32Add
fb = LocalSet(iLocal)
// loop back to the beginning
fb = Br(labelLoop)
} // end loop $loop
fb = Unreachable
fb.buildAndAddToModule()
}

the "wasm:js-string" "fromCharCodeArray" builtin function can be used to convert an i16array directly to a JavaScript string more efficiently.

/// Convert the specified range of a mutable i16 array into a String,
/// treating each i16 as an unsigned 16-bit char code.
///
/// The range is given by [start, end). This function traps if the range is
/// outside the bounds of the array.
///
/// NOTE: This function only takes a mutable i16 array defined in its own
/// recursion group.
///
/// If this is an issue for toolchains, we can look into how to relax the
/// function type while still maintaining good performance.
func fromCharCodeArray(
  array: (ref null (array (mut i16))),
  start: i32,
  end: i32
) -> (ref extern)

https://github.com/WebAssembly/js-string-builtins/blob/main/proposals/js-string-builtins/Overview.md#wasmjs-string-fromcharcodearray

Also, the builtin functions should be called more efficiently than imported functions, and we can expect some more efficient string operations.

When to work on it

Not now, we should see how it goes after the Origin trial

@sjrd sjrd added enhancement Feature request (that does not concern language semantics, see "language") wasm Applies to the WebAssembly backend only labels Jun 8, 2024
@sjrd sjrd self-assigned this Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature request (that does not concern language semantics, see "language") wasm Applies to the WebAssembly backend only
Projects
None yet
Development

No branches or pull requests

2 participants