Browse Source

Implement support of Symbol.toPrimitive (#1020)

Co-authored-by: João Borges <rageknify@gmail.com>
Co-authored-by: tofpie <tofpie@users.noreply.github.com>
pull/1023/head
tofpie 4 years ago committed by GitHub
parent
commit
d6a594757f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      boa/src/value/mod.rs
  2. 14
      boa/src/value/tests.rs

20
boa/src/value/mod.rs

@ -527,11 +527,25 @@ impl Value {
// 1. Assert: input is an ECMAScript language value. (always a value not need to check)
// 2. If Type(input) is Object, then
if let Value::Object(obj) = self {
if let Some(exotic_to_prim) =
obj.get_method(context, context.well_known_symbols().to_primitive_symbol())?
{
let hint = match preferred_type {
PreferredType::String => "string",
PreferredType::Number => "number",
PreferredType::Default => "default",
}
.into();
let result = exotic_to_prim.call(&self, &[hint], context)?;
return if result.is_object() {
Err(context.construct_type_error("Symbol.toPrimitive cannot return an object"))
} else {
Ok(result)
};
}
let mut hint = preferred_type;
// Skip d, e we don't support Symbols yet
// TODO: add when symbols are supported
// TODO: Add other steps.
if hint == PreferredType::Default {
hint = PreferredType::Number;
};

14
boa/src/value/tests.rs

@ -619,6 +619,20 @@ fn test_accessors() {
assert_eq!(forward(&mut context, "arr"), r#"[ "a" ]"#);
}
#[test]
fn to_primitive() {
let mut context = Context::new();
let src = r#"
let a = {};
a[Symbol.toPrimitive] = function() {
return 42;
};
let primitive = a + 0;
"#;
context.eval(src).unwrap();
assert_eq!(forward(&mut context, "primitive"), "42");
}
/// Test cyclic conversions that previously caused stack overflows
/// Relevant mitigations for these are in `GcObject::ordinary_to_primitive` and
/// `GcObject::to_json`

Loading…
Cancel
Save