LibJS: Don't handle arrays separately in Value::to_number()

Now that Array.prototype.join() is producing the correct results we
can remove the separate code path for arrays in Value::to_number()
and treat them like all other objects - using to_primitive() with
number as the preferred type and then calling to_number() on the
result.

This is how the spec descibes it.

This also means we don't crash anymore when trying to coerce
[<empty>] to a number - it now does the following:

[<empty>] - to string - "" - to number - 0
[<empty>, <empty>] - to string - "," - to number - NaN
This commit is contained in:
Linus Groh 2020-04-28 23:58:23 +01:00 committed by Andreas Kling
parent 6d6cd64689
commit da0ab16f01
2 changed files with 13 additions and 12 deletions

View file

@ -162,16 +162,7 @@ Value Value::to_number() const
case Type::Undefined:
return js_nan();
case Type::Object:
if (m_value.as_object->is_array()) {
auto& array = *static_cast<Array*>(m_value.as_object);
if (array.length() == 0)
return Value(0);
if (array.length() > 1)
return js_nan();
return array.elements()[0].to_number();
} else {
return m_value.as_object->to_primitive(Object::PreferredType::Number).to_number();
}
return m_value.as_object->to_primitive(Object::PreferredType::Number).to_number();
}
ASSERT_NOT_REACHED();

View file

@ -9,6 +9,12 @@ try {
assert(-null === 0);
assert(+[] === 0);
assert(-[] === 0);
assert(+[,] === 0);
assert(-[,] === 0);
assert(+[null] === 0);
assert(-[null] === 0);
assert(+[undefined] === 0);
assert(-[undefined] === 0);
assert(+[[[[[]]]]] === 0);
assert(-[[[[[]]]]] === 0);
assert(+[[[[[42]]]]] === 42);
@ -35,8 +41,12 @@ try {
assert(isNaN(-undefined));
assert(isNaN(+{}));
assert(isNaN(-{}));
assert(isNaN(+{a: 1}));
assert(isNaN(-{a: 1}));
assert(isNaN(+{ a: 1 }));
assert(isNaN(-{ a: 1 }));
assert(isNaN(+[, , ,]));
assert(isNaN(-[, , ,]));
assert(isNaN(+[undefined, undefined]));
assert(isNaN(-[undefined, undefined]));
assert(isNaN(+[1, 2, 3]));
assert(isNaN(-[1, 2, 3]));
assert(isNaN(+[[[["foo"]]]]));