mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-25 06:02: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 = []
|
std = []
|
||||||
serde-serialize = ["serde", "serde_json", "std"]
|
serde-serialize = ["serde", "serde_json", "std"]
|
||||||
nightly = []
|
nightly = []
|
||||||
|
disable-interning = []
|
||||||
|
|
||||||
# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
|
# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
|
||||||
# all unused attributes
|
# 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" }
|
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.48" }
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
serde_json = { 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]
|
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||||
js-sys = { path = 'crates/js-sys', version = '0.3.25' }
|
js-sys = { path = 'crates/js-sys', version = '0.3.25' }
|
||||||
@ -89,6 +92,5 @@ exclude = ['crates/typescript']
|
|||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
wasm-bindgen = { path = '.' }
|
wasm-bindgen = { path = '.' }
|
||||||
wasm-bindgen-futures = { path = 'crates/futures' }
|
wasm-bindgen-futures = { path = 'crates/futures' }
|
||||||
wasm-bindgen-cache = { path = 'crates/cache' }
|
|
||||||
js-sys = { path = 'crates/js-sys' }
|
js-sys = { path = 'crates/js-sys' }
|
||||||
web-sys = { path = 'crates/web-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 {
|
impl FromWasmAbi for JsValue {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use std::prelude::v1::*;
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use crate::convert::OptionIntoWasmAbi;
|
use crate::convert::OptionIntoWasmAbi;
|
||||||
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
|
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
|
||||||
|
|
||||||
@ -148,6 +149,8 @@ if_std! {
|
|||||||
fn is_none(abi: &WasmSlice) -> bool { abi.ptr == 0 }
|
fn is_none(abi: &WasmSlice) -> bool { abi.ptr == 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "disable-interning")] {
|
||||||
impl IntoWasmAbi for String {
|
impl IntoWasmAbi for String {
|
||||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||||
|
|
||||||
@ -158,7 +161,27 @@ if_std! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OptionIntoWasmAbi for String {
|
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 {
|
impl FromWasmAbi for String {
|
||||||
@ -175,6 +198,9 @@ if_std! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "disable-interning")] {
|
||||||
impl<'a> IntoWasmAbi for &'a str {
|
impl<'a> IntoWasmAbi for &'a str {
|
||||||
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
type Abi = <&'a [u8] as IntoWasmAbi>::Abi;
|
||||||
|
|
||||||
@ -185,8 +211,25 @@ impl<'a> IntoWasmAbi for &'a str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> OptionIntoWasmAbi for &'a str {
|
impl<'a> OptionIntoWasmAbi for &'a str {
|
||||||
fn none() -> WasmSlice {
|
fn none() -> Self::Abi { null_slice() }
|
||||||
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 {
|
macro_rules! simple {
|
||||||
($($t:ident => $d:ident)*) => ($(
|
($($t:ident => $d:expr)*) => ($(
|
||||||
impl WasmDescribe for $t {
|
impl WasmDescribe for $t {
|
||||||
fn describe() { inform($d) }
|
fn describe() { inform($d) }
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ simple! {
|
|||||||
f64 => F64
|
f64 => F64
|
||||||
bool => BOOLEAN
|
bool => BOOLEAN
|
||||||
char => CHAR
|
char => CHAR
|
||||||
str => STRING
|
str => if cfg!(feature = "disable-interning") { STRING } else { ANYREF }
|
||||||
JsValue => ANYREF
|
JsValue => ANYREF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ if_std! {
|
|||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
impl WasmDescribe for String {
|
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]> {
|
impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
|
||||||
|
@ -57,6 +57,8 @@ pub mod prelude {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
mod cache;
|
||||||
pub mod convert;
|
pub mod convert;
|
||||||
pub mod describe;
|
pub mod describe;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user