Browse Source

Make `BigInt.prototype.toString` spec compliant (#1503)

pull/1495/head
raskad 3 years ago committed by GitHub
parent
commit
8c733c3821
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      boa/src/builtins/bigint/mod.rs

44
boa/src/builtins/bigint/mod.rs

@ -17,6 +17,7 @@ use crate::{
object::{ConstructorBuilder, ObjectData}, object::{ConstructorBuilder, ObjectData},
property::Attribute, property::Attribute,
symbol::WellKnownSymbols, symbol::WellKnownSymbols,
value::IntegerOrInfinity,
BoaProfiler, Context, JsBigInt, JsResult, JsValue, BoaProfiler, Context, JsBigInt, JsResult, JsValue,
}; };
#[cfg(test)] #[cfg(test)]
@ -45,7 +46,7 @@ impl BuiltIn for BigInt {
) )
.name(Self::NAME) .name(Self::NAME)
.length(Self::LENGTH) .length(Self::LENGTH)
.method(Self::to_string, "toString", 1) .method(Self::to_string, "toString", 0)
.method(Self::value_of, "valueOf", 0) .method(Self::value_of, "valueOf", 0)
.static_method(Self::as_int_n, "asIntN", 2) .static_method(Self::as_int_n, "asIntN", 2)
.static_method(Self::as_uint_n, "asUintN", 2) .static_method(Self::as_uint_n, "asUintN", 2)
@ -131,18 +132,41 @@ impl BigInt {
args: &[JsValue], args: &[JsValue],
context: &mut Context, context: &mut Context,
) -> JsResult<JsValue> { ) -> JsResult<JsValue> {
let radix = if !args.is_empty() { // 1. Let x be ? thisBigIntValue(this value).
args[0].to_integer(context)? as i32 let x = Self::this_bigint_value(this, context)?;
let radix = args.get(0).cloned().unwrap_or_default();
// 2. If radix is undefined, let radixMV be 10.
let radix_mv = if radix.is_undefined() {
// 5. If radixMV = 10, return ! ToString(x).
// Note: early return optimization.
return Ok(x.to_string().into());
// 3. Else, let radixMV be ? ToIntegerOrInfinity(radix).
} else { } else {
10 radix.to_integer_or_infinity(context)?
};
// 4. If radixMV < 2 or radixMV > 36, throw a RangeError exception.
let radix_mv = match radix_mv {
IntegerOrInfinity::Integer(i) if (2..=36).contains(&i) => i,
_ => {
return context.throw_range_error(
"radix must be an integer at least 2 and no greater than 36",
)
}
}; };
if !(2..=36).contains(&radix) {
return context // 5. If radixMV = 10, return ! ToString(x).
.throw_range_error("radix must be an integer at least 2 and no greater than 36"); if radix_mv == 10 {
return Ok(x.to_string().into());
} }
Ok(JsValue::new(
Self::this_bigint_value(this, context)?.to_string_radix(radix as u32), // 1. Let x be ? thisBigIntValue(this value).
)) // 6. Return the String representation of this Number value using the radix specified by radixMV.
// Letters a-z are used for digits with values 10 through 35.
// The precise algorithm is implementation-defined, however the algorithm should be a generalization of that specified in 6.1.6.2.23.
Ok(JsValue::new(x.to_string_radix(radix_mv as u32)))
} }
/// `BigInt.prototype.valueOf()` /// `BigInt.prototype.valueOf()`

Loading…
Cancel
Save