Skip to content

Commit

Permalink
Implement support of Symbol.toPrimitive (#1020)
Browse files Browse the repository at this point in the history
Co-authored-by: João Borges <rageknify@gmail.com>
Co-authored-by: tofpie <tofpie@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 1, 2021
1 parent 9e9bf65 commit d6a5947
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
20 changes: 17 additions & 3 deletions boa/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
14 changes: 14 additions & 0 deletions boa/src/value/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down

0 comments on commit d6a5947

Please sign in to comment.