Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add From<i/u128> for JsBigInt #1971

Closed
wants to merge 1 commit into from
Closed

Add From<i/u128> for JsBigInt #1971

wants to merge 1 commit into from

Conversation

dranikpg
Copy link

This Pull Request fixes 1970.

It changes the following:

  • Added From, From for JsBigInt
  • Added From, From for Numeric

@dranikpg dranikpg changed the title Add From<i/u128> for JsBitInt Add From<i/u128> for JsBigInt Mar 23, 2022
@dranikpg
Copy link
Author

Should i128 really be clamped to f64 like i64 is?

impl From<i64> for JsValue {
    #[inline]
    fn from(value: i64) -> Self {
        if let Ok(value) = i32::try_from(value) {
            Self::Integer(value)
        } else {
            Self::Rational(value as f64)
        }
    }
}

I'd rather expect something like this, as accuracy would be very low for big values otherwise

impl From<i128> for JsValue {
    #[inline]
    fn from(value: i128) -> Self {
        if let Ok(value) = i32::try_from(value) {
            Self::Integer(value)
        } else {
            Self::BigInt(value.into()) // i.e. JsBigInt::from()
        }
    }    
}

Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution!! Looks great :)

@Razican Razican added this to the v0.15.0 milestone Mar 23, 2022
@Razican Razican added API enhancement New feature or request labels Mar 23, 2022
@codecov
Copy link

codecov bot commented Mar 23, 2022

Codecov Report

Merging #1971 (5d9154e) into main (e2630fa) will decrease coverage by 0.03%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##             main    #1971      +/-   ##
==========================================
- Coverage   45.90%   45.87%   -0.04%     
==========================================
  Files         206      206              
  Lines       17116    17124       +8     
==========================================
- Hits         7857     7855       -2     
- Misses       9259     9269      +10     
Impacted Files Coverage Δ
boa_engine/src/bigint.rs 35.03% <0.00%> (-4.07%) ⬇️
boa_engine/src/value/mod.rs 51.09% <0.00%> (-0.76%) ⬇️
boa_engine/src/value/operations.rs 38.85% <0.00%> (-0.32%) ⬇️
boa_engine/src/builtins/string/mod.rs 62.74% <0.00%> (+0.21%) ⬆️
...ine/src/syntax/parser/expression/assignment/mod.rs 30.84% <0.00%> (+1.86%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e2630fa...5d9154e. Read the comment docs.

Copy link
Member

@jasonwilliams jasonwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@Razican
Copy link
Member

Razican commented Mar 24, 2022

Should i128 really be clamped to f64 like i64 is?

impl From<i64> for JsValue {

    #[inline]

    fn from(value: i64) -> Self {

        if let Ok(value) = i32::try_from(value) {

            Self::Integer(value)

        } else {

            Self::Rational(value as f64)

        }

    }

}

I'd rather expect something like this, as accuracy would be very low for big values otherwise

impl From<i128> for JsValue {

    #[inline]

    fn from(value: i128) -> Self {

        if let Ok(value) = i32::try_from(value) {

            Self::Integer(value)

        } else {

            Self::BigInt(value.into()) // i.e. JsBigInt::from()

        }

    }    

}

I would say this can be treated in a separate issue, it's a subjective topic :)

Comment on lines +1003 to +1009
impl From<i128> for Numeric {
#[inline]
fn from(value: i128) -> Self {
Self::BigInt(value.into())
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a number (f64) instead of BigInt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we are already doing this with i64, and BigInt would make sure that it doesn't lose precision:

impl From<i64> for Numeric {
#[inline]
fn from(value: i64) -> Self {
Self::BigInt(value.into())
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we are already doing this with i64

Ummm.... This is wrong, It should be a number, not bigint.

BigInt would make sure that it doesn't lose precision

It's fine if we lose precision (we lose precision if we type a number value which is too big for f64 in JavaScript, same with From<i64> for JsValue), If we don't want loss of precision we create a bigint and we can convert it into Numeric.
The behaviour of From<u/iN> should be uniform, to do some number and others bigint is confuzing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was some discussion here too: #1961

From my point of view, we should be able to convert an f64 to JsValue or Numeric, and a BigInt too. But nothing else (at most an i32). If the user wants to convert a i128 to a BigInt, they can first convert it to a BigInt and then convert the BigInt to a Numeric or a JsValue.

We shouldn't probably force anything, but give some options. Maybe a TryFrom implementation could be nice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my point of view, we should be able to convert an f64 to JsValue or Numeric, and a BigInt too. But nothing else (at most an i32). If the user wants to convert a i128 to a BigInt, they can first convert it to a BigInt and then convert the BigInt to a Numeric or a JsValue.

We shouldn't probably force anything, but give some options. Maybe a TryFrom implementation could be nice.

Yup. agreed

boa_engine/src/value/mod.rs Show resolved Hide resolved
Comment on lines +1003 to +1008
impl From<i128> for Numeric {
#[inline]
fn from(value: i128) -> Self {
Self::BigInt(value.into())
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove this, as well as From<u128> for Numeric. If the user wants to a bigint or number they should explicitly say so.

Besides it's out of the scope of this PR of adding From<i/u128> for JsBigInt

@lastmjs
Copy link
Contributor

lastmjs commented Mar 30, 2022

Don't we want to implement the From<i128> or From<u128> trait for JsValue? Why aren't we adding an implementation in here: https://github.com/boa-dev/boa/blob/main/boa_engine/src/value/conversions.rs?

I would like to be able to do the following:

pub fn into_js_value_i128(number: i128) -> boa_engine::JsValue {
    number.into()
}

pub fn into_js_value_u128(number: u128) -> boa_engine::JsValue {
    number.into()
}

I've noticed that f32, i128, i16, i8, u128, u16, and u8 are all missing implementations for From for JsValue, and if I'm not mistaken that seems like the most ergonomic way to use .into() or JsValue::from().

@lastmjs
Copy link
Contributor

lastmjs commented May 20, 2022

What can we do to move this forward? I am currently in need of this now and it would be nice to get back on the main branch of Boa.

@Razican Razican removed this from the v0.15.0 milestone Jun 1, 2022
@Razican
Copy link
Member

Razican commented Oct 10, 2022

This will be handled as part of #2276.

@Razican Razican closed this Oct 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement i128 to JsValue conversions
5 participants