Improving the passStringToWasm function

This commit is contained in:
Pauan 2019-08-23 01:06:21 +02:00
parent e39e8501db
commit 5581cdf656

View File

@ -805,6 +805,30 @@ impl<'a> Context<'a> {
self.global("let WASM_VECTOR_LEN = 0;"); self.global("let WASM_VECTOR_LEN = 0;");
} }
fn expose_encode_as_ascii(&mut self) {
if !self.should_write_global("encode_as_ascii") {
return;
}
self.expose_uint8_memory();
self.global("
function encodeAsAscii(arg, ptr, len) {
let offset = 0;
const mem = getUint8Memory();
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
return offset;
}
");
}
fn expose_pass_string_to_wasm(&mut self) -> Result<(), Error> { fn expose_pass_string_to_wasm(&mut self) -> Result<(), Error> {
if !self.should_write_global("pass_string_to_wasm") { if !self.should_write_global("pass_string_to_wasm") {
return Ok(()); return Ok(());
@ -846,6 +870,8 @@ impl<'a> Context<'a> {
self.expose_text_encoder()?; self.expose_text_encoder()?;
self.expose_uint8_memory(); self.expose_uint8_memory();
self.expose_encode_as_ascii();
// A fast path that directly writes char codes into WASM memory as long // A fast path that directly writes char codes into WASM memory as long
// as it finds only ASCII characters. // as it finds only ASCII characters.
// //
@ -856,19 +882,11 @@ impl<'a> Context<'a> {
// expensive in mainstream engines than staying in the JS, and // expensive in mainstream engines than staying in the JS, and
// charCodeAt on ASCII strings is usually optimised to raw bytes. // charCodeAt on ASCII strings is usually optimised to raw bytes.
let start_encoding_as_ascii = format!( let start_encoding_as_ascii = format!(
" "\
{} {}
let size = arg.length; const len = arg.length;
let ptr = wasm.__wbindgen_malloc(size); let ptr = wasm.__wbindgen_malloc(len);
let offset = 0; const offset = encodeAsAscii(arg, ptr, len);
{{
const mem = getUint8Memory();
for (; offset < arg.length; offset++) {{
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}}
}}
", ",
debug debug
); );
@ -876,10 +894,13 @@ impl<'a> Context<'a> {
// The first implementation we have for this is to use // The first implementation we have for this is to use
// `TextEncoder#encode` which has been around for quite some time. // `TextEncoder#encode` which has been around for quite some time.
let use_encode = format!( let use_encode = format!(
" "\
{} {}
if (offset !== arg.length) {{ if (offset !== len) {{
const buf = cachedTextEncoder.encode(arg.slice(offset)); if (offset !== 0) {{
arg = arg.slice(offset);
}}
const buf = cachedTextEncoder.encode(arg);
ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length); ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length);
getUint8Memory().set(buf, ptr + offset); getUint8Memory().set(buf, ptr + offset);
offset += buf.length; offset += buf.length;
@ -894,11 +915,13 @@ impl<'a> Context<'a> {
// newer and isn't implemented everywhere yet. It's more efficient, // newer and isn't implemented everywhere yet. It's more efficient,
// however, becaues it allows us to elide an intermediate allocation. // however, becaues it allows us to elide an intermediate allocation.
let use_encode_into = format!( let use_encode_into = format!(
" "\
{} {}
if (offset !== arg.length) {{ if (offset !== len) {{
arg = arg.slice(offset); if (offset !== 0) {{
ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + arg.length * 3); arg = arg.slice(offset);
}}
ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + len * 3);
const view = getUint8Memory().subarray(ptr + offset, ptr + size); const view = getUint8Memory().subarray(ptr + offset, ptr + size);
const ret = cachedTextEncoder.encodeInto(arg, view); const ret = cachedTextEncoder.encodeInto(arg, view);
{} {}
@ -909,7 +932,7 @@ impl<'a> Context<'a> {
", ",
start_encoding_as_ascii, start_encoding_as_ascii,
if self.config.debug { if self.config.debug {
"if (ret.read != arg.length) throw new Error('failed to pass whole string');" "if (ret.read != len) throw new Error('failed to pass whole string');"
} else { } else {
"" ""
}, },
@ -932,12 +955,9 @@ impl<'a> Context<'a> {
self.require_internal_export("__wbindgen_realloc")?; self.require_internal_export("__wbindgen_realloc")?;
self.global(&format!( self.global(&format!(
" "
let passStringToWasm; const passStringToWasm = (typeof cachedTextEncoder.encodeInto === 'function'
if (typeof cachedTextEncoder.encodeInto === 'function') {{ ? function (arg) {{ {} }}
passStringToWasm = function(arg) {{ {} }}; : function (arg) {{ {} }});
}} else {{
passStringToWasm = function(arg) {{ {} }};
}}
", ",
use_encode_into, use_encode, use_encode_into, use_encode,
)); ));