From 5f742ca4c473af3e529e1d5700e11dea281bfc78 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Tue, 26 Mar 2019 18:12:24 +0000 Subject: [PATCH] Simplify ABI for Option Flatten None to a special u32 value instead of using an intermediate pointer. --- crates/cli-support/src/js/js2rust.rs | 16 ++++----------- crates/cli-support/src/js/rust2js.rs | 14 +++----------- src/convert/impls.rs | 29 ++++++---------------------- 3 files changed, 13 insertions(+), 46 deletions(-) diff --git a/crates/cli-support/src/js/js2rust.rs b/crates/cli-support/src/js/js2rust.rs index 1b25307a..07831b44 100644 --- a/crates/cli-support/src/js/js2rust.rs +++ b/crates/cli-support/src/js/js2rust.rs @@ -343,9 +343,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> { self.cx.expose_is_like_none(); self.js_arguments .push((name.clone(), "string | undefined".to_string())); - self.rust_arguments.push(format!("!isLikeNone({0})", name)); self.rust_arguments - .push(format!("isLikeNone({0}) ? 0 : {0}.codePointAt(0)", name)); + .push(format!("isLikeNone({0}) ? 0xFFFFFF : {0}.codePointAt(0)", name)); return Ok(self); } Descriptor::Enum { hole } => { @@ -632,17 +631,10 @@ impl<'a, 'b> Js2Rust<'a, 'b> { } Descriptor::Char => { self.ret_ty = "string | undefined".to_string(); - self.cx.expose_global_argument_ptr()?; - self.cx.expose_uint32_memory(); - self.prelude("const retptr = globalArgumentPtr();"); - self.rust_arguments.insert(0, "retptr".to_string()); self.ret_expr = " - RET; - const present = getUint32Memory()[retptr / 4]; - const value = getUint32Memory()[retptr / 4 + 1]; - return present === 0 ? undefined : String.fromCodePoint(value); - " - .to_string(); + const ret = RET; + return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); + ".to_string(); return Ok(self); } Descriptor::Enum { hole } => { diff --git a/crates/cli-support/src/js/rust2js.rs b/crates/cli-support/src/js/rust2js.rs index de4640a1..366fd84b 100644 --- a/crates/cli-support/src/js/rust2js.rs +++ b/crates/cli-support/src/js/rust2js.rs @@ -215,12 +215,8 @@ impl<'a, 'b> Rust2Js<'a, 'b> { return Ok(()); } Descriptor::Char => { - let value = self.shim_argument(); - self.js_arguments.push(format!( - "{present} === 0 ? undefined : String.fromCodePoint({value})", - value = value, - present = abi, - )); + self.js_arguments + .push(format!("{0} === 0xFFFFFF ? undefined : String.fromCodePoint({0})", abi)); return Ok(()); } Descriptor::RustStruct(ref class) => { @@ -468,13 +464,9 @@ impl<'a, 'b> Rust2Js<'a, 'b> { return Ok(()); } Descriptor::Char => { - self.cx.expose_is_like_none(); - self.cx.expose_uint32_memory(); - self.shim_arguments.insert(0, "ret".to_string()); self.ret_expr = " const val = JS; - getUint32Memory()[ret / 4] = !isLikeNone(val); - getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0); + return isLikeNone(val) ? 0xFFFFFF : val.codePointAt(0); " .to_string(); return Ok(()); diff --git a/src/convert/impls.rs b/src/convert/impls.rs index ec66a9aa..c779ef13 100644 --- a/src/convert/impls.rs +++ b/src/convert/impls.rs @@ -258,34 +258,17 @@ impl FromWasmAbi for char { } } -impl IntoWasmAbi for Option { - type Abi = WasmOptionalU32; - +impl OptionIntoWasmAbi for char { #[inline] - fn into_abi(self, _extra: &mut Stack) -> WasmOptionalU32 { - match self { - None => WasmOptionalU32 { - present: 0, - value: 0, - }, - Some(me) => WasmOptionalU32 { - present: 1, - value: me as u32, - }, - } + fn none() -> u32 { + 0xFFFFFFu32 } } -impl FromWasmAbi for Option { - type Abi = WasmOptionalU32; - +impl OptionFromWasmAbi for char { #[inline] - unsafe fn from_abi(js: WasmOptionalU32, _extra: &mut Stack) -> Self { - if js.present == 0 { - None - } else { - Some(char::from_u32_unchecked(js.value)) - } + fn is_none(js: &u32) -> bool { + *js == 0xFFFFFFu32 } }