mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-21 08:41:35 +00:00
Add support for optional chars
This commit is contained in:
committed by
Alex Crichton
parent
4a0c69ffed
commit
afaf94a428
@ -277,6 +277,13 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
|||||||
self.rust_arguments.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0} ? 1 : 0", name));
|
self.rust_arguments.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0} ? 1 : 0", name));
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
},
|
},
|
||||||
|
Descriptor::Char => {
|
||||||
|
self.cx.expose_is_like_none();
|
||||||
|
self.js_arguments.push((name.clone(), "string".to_string()));
|
||||||
|
self.rust_arguments.push(format!("!isLikeNone({0})", name));
|
||||||
|
self.rust_arguments.push(format!("isLikeNone({0}) ? 0 : {0}.codePointAt(0)", name));
|
||||||
|
return Ok(self);
|
||||||
|
},
|
||||||
_ => bail!("unsupported optional argument type for calling Rust function from JS: {:?}", arg),
|
_ => bail!("unsupported optional argument type for calling Rust function from JS: {:?}", arg),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -514,6 +521,20 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
|||||||
".to_string();
|
".to_string();
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
},
|
},
|
||||||
|
Descriptor::Char => {
|
||||||
|
self.ret_ty = "string".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();
|
||||||
|
return Ok(self);
|
||||||
|
},
|
||||||
_ => bail!("unsupported optional return type for calling Rust function from JS: {:?}", ty),
|
_ => bail!("unsupported optional return type for calling Rust function from JS: {:?}", ty),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,15 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
self.js_arguments.push(format!("{0} === 0xFFFFFF ? undefined : {0} !== 0", abi));
|
self.js_arguments.push(format!("{0} === 0xFFFFFF ? undefined : {0} !== 0", abi));
|
||||||
return Ok(())
|
return Ok(())
|
||||||
},
|
},
|
||||||
|
Descriptor::Char => {
|
||||||
|
let value = self.shim_argument();
|
||||||
|
self.js_arguments.push(format!(
|
||||||
|
"{present} === 0 ? undefined : String.fromCodePoint({value})",
|
||||||
|
value = value,
|
||||||
|
present = abi,
|
||||||
|
));
|
||||||
|
return Ok(())
|
||||||
|
},
|
||||||
_ => bail!("unsupported optional argument type for calling JS function from Rust: {:?}", arg),
|
_ => bail!("unsupported optional argument type for calling JS function from Rust: {:?}", arg),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -439,6 +448,17 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
".to_string();
|
".to_string();
|
||||||
return Ok(());
|
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);
|
||||||
|
".to_string();
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
_ => bail!("unsupported optional return type for calling JS function from Rust: {:?}", ty),
|
_ => bail!("unsupported optional return type for calling JS function from Rust: {:?}", ty),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -248,6 +248,35 @@ impl FromWasmAbi for char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoWasmAbi for Option<char> {
|
||||||
|
type Abi = WasmOptionalU32;
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromWasmAbi for Option<char> {
|
||||||
|
type Abi = WasmOptionalU32;
|
||||||
|
|
||||||
|
unsafe fn from_abi(js: WasmOptionalU32, _extra: &mut Stack) -> Self {
|
||||||
|
if js.present == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(char::from_u32_unchecked(js.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> IntoWasmAbi for *const T {
|
impl<T> IntoWasmAbi for *const T {
|
||||||
type Abi = u32;
|
type Abi = u32;
|
||||||
|
|
||||||
|
@ -80,6 +80,10 @@ exports.test_works = function() {
|
|||||||
assert.strictEqual(wasm.bool_identity(wasm.bool_none()), undefined);
|
assert.strictEqual(wasm.bool_identity(wasm.bool_none()), undefined);
|
||||||
assert.strictEqual(wasm.bool_identity(wasm.bool_false()), false);
|
assert.strictEqual(wasm.bool_identity(wasm.bool_false()), false);
|
||||||
assert.strictEqual(wasm.bool_identity(wasm.bool_true()), true);
|
assert.strictEqual(wasm.bool_identity(wasm.bool_true()), true);
|
||||||
|
|
||||||
|
assert.strictEqual(wasm.char_identity(wasm.char_none()), undefined);
|
||||||
|
assert.strictEqual(wasm.char_identity(wasm.char_letter()), 'a');
|
||||||
|
assert.strictEqual(wasm.char_identity(wasm.char_face()), '😀');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.i32_js_identity = function(a) { return a; };
|
exports.i32_js_identity = function(a) { return a; };
|
||||||
@ -95,3 +99,4 @@ exports.u16_js_identity = function(a) { return a; };
|
|||||||
exports.i64_js_identity = function(a) { return a; };
|
exports.i64_js_identity = function(a) { return a; };
|
||||||
exports.u64_js_identity = function(a) { return a; };
|
exports.u64_js_identity = function(a) { return a; };
|
||||||
exports.bool_js_identity = function(a) { return a; };
|
exports.bool_js_identity = function(a) { return a; };
|
||||||
|
exports.char_js_identity = function(a) { return a; };
|
||||||
|
@ -16,6 +16,7 @@ extern {
|
|||||||
fn i64_js_identity(a: Option<i64>) -> Option<i64>;
|
fn i64_js_identity(a: Option<i64>) -> Option<i64>;
|
||||||
fn u64_js_identity(a: Option<u64>) -> Option<u64>;
|
fn u64_js_identity(a: Option<u64>) -> Option<u64>;
|
||||||
fn bool_js_identity(a: Option<bool>) -> Option<bool>;
|
fn bool_js_identity(a: Option<bool>) -> Option<bool>;
|
||||||
|
fn char_js_identity(a: Option<char>) -> Option<char>;
|
||||||
|
|
||||||
fn test_works();
|
fn test_works();
|
||||||
}
|
}
|
||||||
@ -191,6 +192,15 @@ pub fn bool_true() -> Option<bool> { Some(true) }
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn bool_identity(a: Option<bool>) -> Option<bool> { bool_js_identity(a) }
|
pub fn bool_identity(a: Option<bool>) -> Option<bool> { bool_js_identity(a) }
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn char_none() -> Option<char> { None }
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn char_letter() -> Option<char> { Some('a') }
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn char_face() -> Option<char> { Some('😀') }
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn char_identity(a: Option<char>) -> Option<char> { char_js_identity(a) }
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn works() {
|
fn works() {
|
||||||
test_works();
|
test_works();
|
||||||
|
Reference in New Issue
Block a user