Browse Source

LibJS: Make Object::to_string() call the "toString" property if present

Andreas Kling 5 years ago
parent
commit
8bfee015bc

+ 8 - 0
Libraries/LibJS/Runtime/Object.cpp

@@ -205,6 +205,14 @@ Value Object::to_primitive(PreferredType preferred_type) const
 
 Value Object::to_string() const
 {
+    auto to_string_property = get("toString");
+    if (to_string_property.has_value()
+        && to_string_property.value().is_object()
+        && to_string_property.value().as_object().is_function()) {
+        auto& to_string_function = static_cast<Function&>(to_string_property.value().as_object());
+        return const_cast<Object*>(this)->interpreter().call(&to_string_function, const_cast<Object*>(this));
+    }
     return js_string(heap(), String::format("[object %s]", class_name()));
 }
+
 }

+ 1 - 1
Libraries/LibJS/Runtime/ObjectPrototype.cpp

@@ -61,7 +61,7 @@ Value ObjectPrototype::to_string(Interpreter& interpreter)
     auto* this_object = interpreter.this_value().to_object(interpreter.heap());
     if (!this_object)
         return {};
-    return Value(this_object->to_string());
+    return js_string(interpreter, String::format("[object %s]", this_object->class_name()));
 }
 
 Value ObjectPrototype::value_of(Interpreter& interpreter)

+ 3 - 0
Libraries/LibJS/Tests/Array.prototype.toString.js

@@ -3,6 +3,9 @@ try {
     assert(a.toString() === '1,2,3');
     assert([].toString() === '');
     assert([5].toString() === '5');
+
+    assert("rgb(" + [10, 11, 12] + ")" === "rgb(10,11,12)");
+
     console.log("PASS");
 } catch (e) {
     console.log("FAIL: " + e);

+ 1 - 1
Libraries/LibJS/Tests/function-TypeError.js

@@ -41,7 +41,7 @@ try {
         new isNaN();
     } catch(e) {
         assert(e.name === "TypeError");
-        assert(e.message === "[object NativeFunction] is not a constructor");
+        assert(e.message === "function () {\n  [NativeFunction]\n} is not a constructor");
     }
 
     console.log("PASS");