Add support for TextEncoder#encodeInto

This commit adds support for the recently implemented standard of
[`TextEncoder#encodeInto`][standard]. This new function is a "bring your
own buffer" style function where we can avoid an intermediate allocation
and copy by encoding strings directly into wasm's memory.

Currently we feature-detect whether `encodeInto` exists as it is only
implemented in recent browsers and not in all browsers. Additionally
this commit emits the binding using `encodeInto` by default, but this
requires `realloc` functionality to be exposed by the wasm module.
Measured locally an empty binary which takes `&str` previously took
7.6k, but after this commit takes 8.7k due to the extra code needed for
`realloc`.

[standard]: https://encoding.spec.whatwg.org/#dom-textencoder-encodeinto

Closes #1172
This commit is contained in:
Alex Crichton
2019-02-20 08:39:46 -08:00
parent de85d99acd
commit 745b16e3d2
4 changed files with 110 additions and 7 deletions

View File

@ -892,7 +892,7 @@ pub mod __rt {
}
if_std! {
use std::alloc::{alloc, dealloc, Layout};
use std::alloc::{alloc, dealloc, realloc, Layout};
use std::mem;
#[no_mangle]
@ -911,6 +911,27 @@ pub mod __rt {
}
}
malloc_failure();
}
#[no_mangle]
pub extern "C" fn __wbindgen_realloc(ptr: *mut u8, old_size: usize, new_size: usize) -> *mut u8 {
let align = mem::align_of::<usize>();
debug_assert!(old_size > 0);
debug_assert!(new_size > 0);
if let Ok(layout) = Layout::from_size_align(old_size, align) {
unsafe {
let ptr = realloc(ptr, layout, new_size);
if !ptr.is_null() {
return ptr
}
}
}
malloc_failure();
}
#[cold]
fn malloc_failure() -> ! {
if cfg!(debug_assertions) {
super::throw_str("invalid malloc request")
} else {