Skip to content

Commit

Permalink
Add math-related intrinsics/functions for JsValues (#2629)
Browse files Browse the repository at this point in the history
* Allow accessing JS math operators from Rust

Useful for dealing with JS `BigInt`s

* Add `typeof` and `in` methods/intrinsics

* Add comparison operators

* Remove Object.is intrinsic

* Make conversion into f64 faillible

* Add `#[inline]`s

* Fix methods to make them take references

* cargo fmt

* Add BigInt to js-sys (no constructor yet)

* Remove useless import

* Fix UI tests

* Add BigInt constructor

* Allow catching `to_string` method for BigInt

* Fix tests again

* Add inlines

* Rework PartialEq impl

* Implement FromStr for BigInt

* Add more inlines

* Update formatting

* Add more trait impls and feature for integration with `rust-num`

* Add `PartialOrd` and `Ord` impls for more types

* Cargo fmt

* Remove `num-traits` from `wasm-bindgen`, integrate `js-sys` with `rust-num` further

* Update Cargo.toml

* Update Rust version for CI (to allow proc-macro2 to build again)

* Fix link in Markdown

* Remove all `rust-num` code from `js-sys`
  • Loading branch information
Jules-Bertholet committed Sep 2, 2021
1 parent 965b88c commit d6d056c
Show file tree
Hide file tree
Showing 6 changed files with 1,176 additions and 13 deletions.
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Expand Up @@ -93,7 +93,7 @@ jobs:
steps:
- template: ci/azure-install-rust.yml
parameters:
toolchain: nightly-2021-05-09
toolchain: nightly-2021-09-02
- template: ci/azure-install-node.yml
- script: cargo test --target wasm32-unknown-unknown --features nightly --test wasm

Expand Down Expand Up @@ -210,7 +210,7 @@ jobs:
steps:
- template: ci/azure-install-rust.yml
parameters:
toolchain: nightly-2021-05-09
toolchain: nightly-2021-09-02
- script: rustup component add rust-src
displayName: "install rust-src"
- script: |
Expand Down
78 changes: 78 additions & 0 deletions crates/cli-support/src/intrinsic.rs
Expand Up @@ -85,6 +85,9 @@ intrinsics! {
#[symbol = "__wbindgen_jsval_eq"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
JsvalEq,
#[symbol = "__wbindgen_jsval_loose_eq"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
JsvalLooseEq,
#[symbol = "__wbindgen_is_function"]
#[signature = fn(ref_externref()) -> Boolean]
IsFunction,
Expand All @@ -103,9 +106,81 @@ intrinsics! {
#[symbol = "__wbindgen_is_string"]
#[signature = fn(ref_externref()) -> Boolean]
IsString,
#[symbol = "__wbindgen_is_bigint"]
#[signature = fn(ref_externref()) -> Boolean]
IsBigInt,
#[symbol = "__wbindgen_typeof"]
#[signature = fn(ref_externref()) -> Externref]
Typeof,
#[symbol = "__wbindgen_in"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
In,
#[symbol = "__wbindgen_is_falsy"]
#[signature = fn(ref_externref()) -> Boolean]
IsFalsy,
#[symbol = "__wbindgen_as_number"]
#[signature = fn(ref_externref()) -> F64]
AsNumber,
#[symbol = "__wbindgen_try_into_number"]
#[signature = fn(ref_externref()) -> Externref]
TryIntoNumber,
#[symbol = "__wbindgen_neg"]
#[signature = fn(ref_externref()) -> Externref]
Neg,
#[symbol = "__wbindgen_bit_and"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
BitAnd,
#[symbol = "__wbindgen_bit_or"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
BitOr,
#[symbol = "__wbindgen_bit_xor"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
BitXor,
#[symbol = "__wbindgen_bit_not"]
#[signature = fn(ref_externref()) -> Externref]
BitNot,
#[symbol = "__wbindgen_shl"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Shl,
#[symbol = "__wbindgen_shr"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Shr,
#[symbol = "__wbindgen_unsigned_shr"]
#[signature = fn(ref_externref(), ref_externref()) -> U32]
UnsignedShr,
#[symbol = "__wbindgen_add"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Add,
#[symbol = "__wbindgen_sub"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Sub,
#[symbol = "__wbindgen_div"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Div,
#[symbol = "__wbindgen_checked_div"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
CheckedDiv,
#[symbol = "__wbindgen_mul"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Mul,
#[symbol = "__wbindgen_rem"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Rem,
#[symbol = "__wbindgen_pow"]
#[signature = fn(ref_externref(), ref_externref()) -> Externref]
Pow,
#[symbol = "__wbindgen_lt"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
LT,
#[symbol = "__wbindgen_le"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
LE,
#[symbol = "__wbindgen_ge"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
GE,
#[symbol = "__wbindgen_gt"]
#[signature = fn(ref_externref(), ref_externref()) -> Boolean]
GT,
#[symbol = "__wbindgen_object_clone_ref"]
#[signature = fn(ref_externref()) -> Externref]
ObjectCloneRef,
Expand All @@ -118,6 +193,9 @@ intrinsics! {
#[symbol = "__wbindgen_number_new"]
#[signature = fn(F64) -> Externref]
NumberNew,
#[symbol = "__wbindgen_bigint_new"]
#[signature = fn(ref_string()) -> Externref]
BigIntNew,
#[symbol = "__wbindgen_string_new"]
#[signature = fn(ref_string()) -> Externref]
StringNew,
Expand Down
130 changes: 130 additions & 0 deletions crates/cli-support/src/js/mod.rs
Expand Up @@ -2907,6 +2907,11 @@ impl<'a> Context<'a> {
format!("{} === {}", args[0], args[1])
}

Intrinsic::JsvalLooseEq => {
assert_eq!(args.len(), 2);
format!("{} == {}", args[0], args[1])
}

Intrinsic::IsFunction => {
assert_eq!(args.len(), 1);
format!("typeof({}) === 'function'", args[0])
Expand Down Expand Up @@ -2938,11 +2943,131 @@ impl<'a> Context<'a> {
format!("typeof({}) === 'string'", args[0])
}

Intrinsic::IsBigInt => {
assert_eq!(args.len(), 1);
format!("typeof({}) === 'bigint'", args[0])
}

Intrinsic::Typeof => {
assert_eq!(args.len(), 1);
format!("typeof {}", args[0])
}

Intrinsic::In => {
assert_eq!(args.len(), 2);
format!("{} in {}", args[0], args[1])
}

Intrinsic::IsFalsy => {
assert_eq!(args.len(), 1);
format!("!{}", args[0])
}

Intrinsic::AsNumber => {
assert_eq!(args.len(), 1);
format!("+{}", args[0])
}

Intrinsic::TryIntoNumber => {
assert_eq!(args.len(), 1);
format!("try {{ +{} }} catch(e) {{ e }}", args[0])
}

Intrinsic::Neg => {
assert_eq!(args.len(), 1);
format!("-{}", args[0])
}

Intrinsic::BitAnd => {
assert_eq!(args.len(), 2);
format!("{} & {}", args[0], args[1])
}

Intrinsic::BitOr => {
assert_eq!(args.len(), 2);
format!("{} | {}", args[0], args[1])
}

Intrinsic::BitXor => {
assert_eq!(args.len(), 2);
format!("{} ^ {}", args[0], args[1])
}

Intrinsic::BitNot => {
assert_eq!(args.len(), 1);
format!("~{}", args[0])
}

Intrinsic::Shl => {
assert_eq!(args.len(), 2);
format!("{} << {}", args[0], args[1])
}

Intrinsic::Shr => {
assert_eq!(args.len(), 2);
format!("{} >> {}", args[0], args[1])
}

Intrinsic::UnsignedShr => {
assert_eq!(args.len(), 2);
format!("{} >>> {}", args[0], args[1])
}

Intrinsic::Add => {
assert_eq!(args.len(), 2);
format!("{} + {}", args[0], args[1])
}

Intrinsic::Sub => {
assert_eq!(args.len(), 2);
format!("{} - {}", args[0], args[1])
}

Intrinsic::Div => {
assert_eq!(args.len(), 2);
format!("{} / {}", args[0], args[1])
}

Intrinsic::CheckedDiv => {
assert_eq!(args.len(), 2);
format!("try {{ {} / {} }} catch (e) {{ if (e instanceof RangeError) {{ e }} else {{ throw e }} }}", args[0], args[1])
}

Intrinsic::Mul => {
assert_eq!(args.len(), 2);
format!("{} * {}", args[0], args[1])
}

Intrinsic::Rem => {
assert_eq!(args.len(), 2);
format!("{} % {}", args[0], args[1])
}

Intrinsic::Pow => {
assert_eq!(args.len(), 2);
format!("{} ** {}", args[0], args[1])
}

Intrinsic::LT => {
assert_eq!(args.len(), 2);
format!("{} < {}", args[0], args[1])
}

Intrinsic::LE => {
assert_eq!(args.len(), 2);
format!("{} <= {}", args[0], args[1])
}

Intrinsic::GE => {
assert_eq!(args.len(), 2);
format!("{} >= {}", args[0], args[1])
}

Intrinsic::GT => {
assert_eq!(args.len(), 2);
format!("{} > {}", args[0], args[1])
}

Intrinsic::ObjectCloneRef => {
assert_eq!(args.len(), 1);
args[0].clone()
Expand All @@ -2968,6 +3093,11 @@ impl<'a> Context<'a> {
args[0].clone()
}

Intrinsic::BigIntNew => {
assert_eq!(args.len(), 1);
format!("BigInt({})", args[0])
}

Intrinsic::StringNew => {
assert_eq!(args.len(), 1);
args[0].clone()
Expand Down

0 comments on commit d6d056c

Please sign in to comment.