diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 675a938f14d..66582e4622a 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -49,9 +49,13 @@ String Value::to_string() const if (is_undefined()) return "undefined"; - if (is_number()) + if (is_number()) { + if (is_nan()) + return "NaN"; + // FIXME: This needs improvement. return String::number((i32)as_double()); + } if (is_object()) return as_object()->to_primitive(Object::PreferredType::String).to_string(); @@ -108,14 +112,10 @@ Value Value::to_number() const if (ok) return Value(parsed_int); - //FIXME: Implement 'NaN' - ASSERT_NOT_REACHED(); - - break; + return js_nan(); } case Type::Undefined: - //FIXME: Implement 'NaN' - ASSERT_NOT_REACHED(); + return js_nan(); case Type::Object: return m_value.as_object->to_primitive(Object::PreferredType::Number).to_number(); } diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 5dfe6001016..8e2a1daeaff 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -53,6 +53,8 @@ public: bool is_cell() const { return is_string() || is_object(); } bool is_array() const; + bool is_nan() const { return is_number() && __builtin_isnan( as_double()); } + Value() : m_type(Type::Undefined) { @@ -166,6 +168,11 @@ inline Value js_null() return Value(Value::Type::Null); } +inline Value js_nan() +{ + return Value(__builtin_nan("")); +} + Value greater_than(Value lhs, Value rhs); Value greater_than_equals(Value lhs, Value rhs); Value less_than(Value lhs, Value rhs); diff --git a/Libraries/LibJS/Tests/NaN-basic.js b/Libraries/LibJS/Tests/NaN-basic.js new file mode 100644 index 00000000000..1f849beefe8 --- /dev/null +++ b/Libraries/LibJS/Tests/NaN-basic.js @@ -0,0 +1,9 @@ +function assert(x) { if (!x) throw 1; } + +try { + var nan = undefined + 1; + assert(nan + "" == "NaN"); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}