diff --git a/Cargo.lock b/Cargo.lock index 7568ca5174..a86450f8e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -421,9 +421,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.41" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916" +checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2" dependencies = [ "wasm-bindgen", ] @@ -451,9 +451,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", ] @@ -723,9 +723,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" @@ -819,8 +819,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "ryu-js" -version = "1.0.5" -source = "git+https://github.com/Tropid/ryu-js#fe366fa397d04324fa693b5d85134851b09719b3" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1010bb9c1f68556b130d631f92fa5e78a2f15a7befcbfbbba51bdb35088149e9" [[package]] name = "same-file" @@ -924,9 +925,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" +checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" dependencies = [ "proc-macro2", "quote", @@ -1045,9 +1046,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.64" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2" +checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1055,9 +1056,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.64" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df" +checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d" dependencies = [ "bumpalo", "lazy_static", @@ -1070,9 +1071,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.64" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8" +checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1080,9 +1081,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.64" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75" +checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6" dependencies = [ "proc-macro2", "quote", @@ -1093,15 +1094,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.64" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae" +checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87" [[package]] name = "web-sys" -version = "0.3.41" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d" +checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 6518fba2a7..332f84c9d3 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -361,18 +361,8 @@ impl Number { #[allow(clippy::wrong_self_convention)] pub(crate) fn to_native_string(x: f64) -> String { - if x == -0. { - return "0".to_owned(); - } else if x.is_nan() { - return "NaN".to_owned(); - } else if x.is_infinite() && x.is_sign_positive() { - return "Infinity".to_owned(); - } else if x.is_infinite() && x.is_sign_negative() { - return "-Infinity".to_owned(); - } - - // FIXME: This is not spec compliant. - format!("{}", x) + let mut buffer = ryu_js::Buffer::new(); + buffer.format(x).to_string() } /// `Number.prototype.toString( [radix] )` @@ -400,6 +390,11 @@ impl Number { .throw_range_error("radix must be an integer at least 2 and no greater than 36"); } + // 5. If radixNumber = 10, return ! ToString(x). + if radix == 10 { + return Ok(Value::from(Self::to_native_string(x))); + } + if x == -0. { return Ok(Value::from("0")); } else if x.is_nan() { @@ -410,13 +405,6 @@ impl Number { return Ok(Value::from("-Infinity")); } - // 5. If radixNumber = 10, return ! ToString(x). - // This part should use exponential notations for long integer numbers commented tests - if radix == 10 { - // return Ok(to_value(format!("{}", Self::to_number(this).to_num()))); - return Ok(Value::from(Self::to_native_string(x))); - } - // This is a Optimization from the v8 source code to print values that can fit in a single character // Since the actual num_to_string allocates a 2200 bytes buffer for actual conversion // I am not sure if this part is effective as the v8 equivalent https://chromium.googlesource.com/v8/v8/+/refs/heads/master/src/builtins/number.tq#53 diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index 4e7baf1cf8..ec4cd3fdf2 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -328,49 +328,30 @@ fn to_string() { } #[test] -#[ignore] -// This tests fail for now since the Rust's default formatting for exponential format does not match the js spec. -// https://github.com/jasonwilliams/boa/pull/381#discussion_r422458544 fn num_to_string_exponential() { let realm = Realm::create(); let mut engine = Interpreter::new(realm); + assert_eq!("0", forward(&mut engine, "(0).toString()")); + assert_eq!("0", forward(&mut engine, "(-0).toString()")); assert_eq!( - String::from("111111111111111110000"), - forward(&mut engine, "Number(111111111111111111111).toString()") - ); - assert_eq!( - String::from("1.1111111111111111e+21"), - forward(&mut engine, "Number(1111111111111111111111).toString()") - ); - assert_eq!( - String::from("1.1111111111111111e+22"), - forward(&mut engine, "Number(11111111111111111111111).toString()") - ); - assert_eq!( - String::from("1e-7"), - forward(&mut engine, "Number(0.0000001).toString()") - ); - assert_eq!( - String::from("1.2e-7"), - forward(&mut engine, "Number(0.00000012).toString()") - ); - assert_eq!( - String::from("1.23e-7"), - forward(&mut engine, "Number(0.000000123).toString()") - ); - assert_eq!( - String::from("1e-8"), - forward(&mut engine, "Number(0.00000001).toString()") + "111111111111111110000", + forward(&mut engine, "(111111111111111111111).toString()") ); assert_eq!( - String::from("1.2e-8"), - forward(&mut engine, "Number(0.000000012).toString()") + "1.1111111111111111e+21", + forward(&mut engine, "(1111111111111111111111).toString()") ); assert_eq!( - String::from("1.23e-8"), - forward(&mut engine, "Number(0.0000000123).toString()") + "1.1111111111111111e+22", + forward(&mut engine, "(11111111111111111111111).toString()") ); + assert_eq!("1e-7", forward(&mut engine, "(0.0000001).toString()")); + assert_eq!("1.2e-7", forward(&mut engine, "(0.00000012).toString()")); + assert_eq!("1.23e-7", forward(&mut engine, "(0.000000123).toString()")); + assert_eq!("1e-8", forward(&mut engine, "(0.00000001).toString()")); + assert_eq!("1.2e-8", forward(&mut engine, "(0.000000012).toString()")); + assert_eq!("1.23e-8", forward(&mut engine, "(0.0000000123).toString()")); } #[test] diff --git a/boa/src/builtins/value/display.rs b/boa/src/builtins/value/display.rs index 0843a5a2ce..a169884df2 100644 --- a/boa/src/builtins/value/display.rs +++ b/boa/src/builtins/value/display.rs @@ -67,6 +67,14 @@ pub(crate) fn log_string_from(x: &Value, print_internals: bool, print_children: match v.borrow().data { ObjectData::String(ref string) => format!("String {{ \"{}\" }}", string), ObjectData::Boolean(boolean) => format!("Boolean {{ {} }}", boolean), + ObjectData::Number(rational) => { + if rational.is_sign_negative() && rational == 0.0 { + "Number { -0 }".to_string() + } else { + let mut buffer = ryu_js::Buffer::new(); + format!("Number {{ {} }}", buffer.format(rational)) + } + } ObjectData::Array => { let len = i32::from( &v.borrow() @@ -219,7 +227,16 @@ impl Display for Value { } } +/// This is different from the ECMAScript compliant number to string, in the printing of `-0`. +/// +/// This function prints `-0` as `-0` instead of pasitive `0` as the specification says. +/// This is done to make it easer for the user of the REPL to identify what is a `-0` vs `0`, +/// since the REPL is not bound to the ECMAScript specification we can do this. fn format_rational(v: f64, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = ryu_js::Buffer::new(); - write!(f, "{}", buffer.format(v)) + if v.is_sign_negative() && v == 0.0 { + f.write_str("-0") + } else { + let mut buffer = ryu_js::Buffer::new(); + write!(f, "{}", buffer.format(v)) + } }