mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-24 21:52:13 +00:00
Changing IntoWasmAbi to use interning
This commit is contained in:
parent
6767371ca7
commit
86a8842f24
@ -25,6 +25,7 @@ spans = ["wasm-bindgen-macro/spans"]
|
||||
std = []
|
||||
serde-serialize = ["serde", "serde_json", "std"]
|
||||
nightly = []
|
||||
disable-interning = []
|
||||
|
||||
# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
|
||||
# all unused attributes
|
||||
@ -38,6 +39,8 @@ xxx_debug_only_print_generated_code = ["wasm-bindgen-macro/xxx_debug_only_print_
|
||||
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.48" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
uluru = "0.3.0"
|
||||
cfg-if = "0.1.9"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
js-sys = { path = 'crates/js-sys', version = '0.3.25' }
|
||||
@ -89,6 +92,5 @@ exclude = ['crates/typescript']
|
||||
[patch.crates-io]
|
||||
wasm-bindgen = { path = '.' }
|
||||
wasm-bindgen-futures = { path = 'crates/futures' }
|
||||
wasm-bindgen-cache = { path = 'crates/cache' }
|
||||
js-sys = { path = 'crates/js-sys' }
|
||||
web-sys = { path = 'crates/web-sys' }
|
||||
|
21
crates/cache/Cargo.toml
vendored
21
crates/cache/Cargo.toml
vendored
@ -1,21 +0,0 @@
|
||||
[package]
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
description = "Utilities for caching JS objects to avoid expensive copying"
|
||||
documentation = "https://docs.rs/wasm-bindgen-cache"
|
||||
homepage = "https://rustwasm.github.io/wasm-bindgen/"
|
||||
license = "MIT/Apache-2.0"
|
||||
name = "wasm-bindgen-cache"
|
||||
repository = "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/cache"
|
||||
readme = "./README.md"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
disabled = []
|
||||
|
||||
[dependencies]
|
||||
js-sys = { path = "../js-sys", version = '0.3.24' }
|
||||
uluru = "0.3.0"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = { path = '../test', version = '0.2.47' }
|
100
crates/cache/src/lib.rs
vendored
100
crates/cache/src/lib.rs
vendored
@ -1,100 +0,0 @@
|
||||
#![deny(missing_docs)]
|
||||
|
||||
//!
|
||||
|
||||
|
||||
///
|
||||
pub mod intern {
|
||||
use js_sys::JsString;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use uluru::{LRUCache, Entry};
|
||||
|
||||
struct Pair {
|
||||
key: String,
|
||||
value: JsString,
|
||||
}
|
||||
|
||||
// TODO figure out a good default capacity
|
||||
type Entries = LRUCache::<[Entry<Pair>; 1_024]>;
|
||||
|
||||
struct Cache {
|
||||
enabled: Cell<bool>,
|
||||
max_str_len: Cell<usize>,
|
||||
entries: RefCell<Entries>,
|
||||
}
|
||||
|
||||
// TODO figure out a good max_str_len
|
||||
thread_local! {
|
||||
static CACHE: Cache = Cache {
|
||||
enabled: Cell::new(true),
|
||||
max_str_len: Cell::new(128),
|
||||
entries: RefCell::new(LRUCache::default()),
|
||||
};
|
||||
}
|
||||
|
||||
fn get_js_string(cache: &mut Entries, key: &str) -> JsString {
|
||||
if let Some(p) = cache.find(|p| p.key == key) {
|
||||
p.value.clone()
|
||||
|
||||
} else {
|
||||
let value = JsString::from(key);
|
||||
|
||||
cache.insert(Pair {
|
||||
key: key.to_owned(),
|
||||
value: value.clone(),
|
||||
});
|
||||
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fn cache_str(s: &str) -> JsString {
|
||||
CACHE.with(|cache| {
|
||||
let should_cache =
|
||||
cache.enabled.get() &&
|
||||
s.len() <= cache.max_str_len.get();
|
||||
|
||||
if should_cache {
|
||||
get_js_string(&mut cache.entries.borrow_mut(), s)
|
||||
|
||||
} else {
|
||||
JsString::from(s)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn str(s: &str) -> JsString {
|
||||
if cfg!(feature = "disabled") {
|
||||
JsString::from(s)
|
||||
|
||||
} else {
|
||||
cache_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn set_max_str_len(len: usize) {
|
||||
if !cfg!(feature = "disabled") {
|
||||
CACHE.with(|cache| cache.max_str_len.set(len));
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn enable() {
|
||||
if !cfg!(feature = "disabled") {
|
||||
CACHE.with(|cache| cache.enabled.set(true));
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn disable() {
|
||||
if !cfg!(feature = "disabled") {
|
||||
CACHE.with(|cache| cache.enabled.set(false));
|
||||
}
|
||||
}
|
||||
}
|
92
src/cache/intern.rs
vendored
Normal file
92
src/cache/intern.rs
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
use std::thread_local;
|
||||
use std::string::String;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use crate::JsValue;
|
||||
use uluru::{LRUCache, Entry};
|
||||
|
||||
|
||||
struct Pair {
|
||||
key: String,
|
||||
value: JsValue,
|
||||
}
|
||||
|
||||
// TODO figure out a good default capacity
|
||||
type Entries = LRUCache::<[Entry<Pair>; 1_024]>;
|
||||
|
||||
struct Cache {
|
||||
enabled: Cell<bool>,
|
||||
max_str_len: Cell<usize>,
|
||||
entries: RefCell<Entries>,
|
||||
}
|
||||
|
||||
// TODO figure out a good max_str_len
|
||||
thread_local! {
|
||||
static CACHE: Cache = Cache {
|
||||
enabled: Cell::new(true),
|
||||
max_str_len: Cell::new(128),
|
||||
entries: RefCell::new(LRUCache::default()),
|
||||
};
|
||||
}
|
||||
|
||||
fn get_js_string(cache: &mut Entries, key: &str) -> JsValue {
|
||||
if let Some(p) = cache.find(|p| p.key == key) {
|
||||
p.value.clone()
|
||||
|
||||
} else {
|
||||
let value = JsValue::from(key);
|
||||
|
||||
cache.insert(Pair {
|
||||
key: key.to_owned(),
|
||||
value: value.clone(),
|
||||
});
|
||||
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fn cache_str(s: &str) -> JsValue {
|
||||
CACHE.with(|cache| {
|
||||
let should_cache =
|
||||
cache.enabled.get() &&
|
||||
s.len() <= cache.max_str_len.get();
|
||||
|
||||
if should_cache {
|
||||
get_js_string(&mut cache.entries.borrow_mut(), s)
|
||||
|
||||
} else {
|
||||
JsValue::from(s)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn str(s: &str) -> JsValue {
|
||||
if cfg!(feature = "disable-interning") {
|
||||
JsValue::from(s)
|
||||
|
||||
} else {
|
||||
cache_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_str_len(len: usize) {
|
||||
if !cfg!(feature = "disable-interning") {
|
||||
CACHE.with(|cache| cache.max_str_len.set(len));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enable() {
|
||||
if !cfg!(feature = "disable-interning") {
|
||||
CACHE.with(|cache| cache.enabled.set(true));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn disable() {
|
||||
if !cfg!(feature = "disable-interning") {
|
||||
CACHE.with(|cache| cache.enabled.set(false));
|
||||
}
|
||||
}
|
1
src/cache/mod.rs
vendored
Normal file
1
src/cache/mod.rs
vendored
Normal file
@ -0,0 +1 @@
|
||||
pub mod intern;
|
@ -315,6 +315,13 @@ impl IntoWasmAbi for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for JsValue {
|
||||
#[inline]
|
||||
fn none() -> u32 {
|
||||
std::u32::MAX
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
|
@ -4,6 +4,7 @@ use std::prelude::v1::*;
|
||||
use core::slice;
|
||||
use core::str;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use crate::convert::OptionIntoWasmAbi;
|
||||
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
|
||||
|
||||
@ -148,6 +149,8 @@ if_std! {
|
||||
fn is_none(abi: &WasmSlice) -> bool { abi.ptr == 0 }
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "disable-interning")] {
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||
|
||||
@ -158,7 +161,27 @@ if_std! {
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for String {
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
#[inline]
|
||||
fn none() -> Self::Abi { null_slice() }
|
||||
}
|
||||
|
||||
} else {
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = <JsValue as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut dyn Stack) -> Self::Abi {
|
||||
crate::cache::intern::str(&self).into_abi(extra)
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for String {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi {
|
||||
<JsValue as OptionIntoWasmAbi>::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for String {
|
||||
@ -175,18 +198,38 @@ if_std! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a str {
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "disable-interning")] {
|
||||
impl<'a> IntoWasmAbi for &'a str {
|
||||
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
self.as_bytes().into_abi()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionIntoWasmAbi for &'a str {
|
||||
fn none() -> WasmSlice {
|
||||
null_slice()
|
||||
impl<'a> OptionIntoWasmAbi for &'a str {
|
||||
fn none() -> Self::Abi { null_slice() }
|
||||
}
|
||||
|
||||
} else {
|
||||
impl<'a> IntoWasmAbi for &'a str {
|
||||
type Abi = <JsValue as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self, extra: &mut dyn Stack) -> Self::Abi {
|
||||
crate::cache::intern::str(self).into_abi(extra)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionIntoWasmAbi for &'a str {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi {
|
||||
<JsValue as OptionIntoWasmAbi>::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ pub trait WasmDescribe {
|
||||
}
|
||||
|
||||
macro_rules! simple {
|
||||
($($t:ident => $d:ident)*) => ($(
|
||||
($($t:ident => $d:expr)*) => ($(
|
||||
impl WasmDescribe for $t {
|
||||
fn describe() { inform($d) }
|
||||
}
|
||||
@ -75,7 +75,7 @@ simple! {
|
||||
f64 => F64
|
||||
bool => BOOLEAN
|
||||
char => CHAR
|
||||
str => STRING
|
||||
str => if cfg!(feature = "disable-interning") { STRING } else { ANYREF }
|
||||
JsValue => ANYREF
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ if_std! {
|
||||
use std::prelude::v1::*;
|
||||
|
||||
impl WasmDescribe for String {
|
||||
fn describe() { inform(STRING) }
|
||||
fn describe() { inform(if cfg!(feature = "disable-interning") { STRING } else { ANYREF }) }
|
||||
}
|
||||
|
||||
impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
|
||||
|
@ -57,6 +57,8 @@ pub mod prelude {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
mod cache;
|
||||
pub mod convert;
|
||||
pub mod describe;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user