summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-04-05 18:18:24 +0200
committerAndreas Kling <kling@serenityos.org>2020-04-05 18:19:56 +0200
commit8bfee015bc7d79c7fc3c89edbc88eba503e8ab37 (patch)
tree433321217839a56707563d6cedc4f8074d4e5916
parenta7b21ec0f4a77e6e7cdf2b57f9255a02539b02f4 (diff)
downloadserenity-8bfee015bc7d79c7fc3c89edbc88eba503e8ab37.zip
LibJS: Make Object::to_string() call the "toString" property if present
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp8
-rw-r--r--Libraries/LibJS/Runtime/ObjectPrototype.cpp2
-rw-r--r--Libraries/LibJS/Tests/Array.prototype.toString.js3
-rw-r--r--Libraries/LibJS/Tests/function-TypeError.js2
4 files changed, 13 insertions, 2 deletions
diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp
index c29c7f85d1..6598a3af76 100644
--- a/Libraries/LibJS/Runtime/Object.cpp
+++ b/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()));
}
+
}
diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp
index 92e06048b2..c70c590253 100644
--- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp
+++ b/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)
diff --git a/Libraries/LibJS/Tests/Array.prototype.toString.js b/Libraries/LibJS/Tests/Array.prototype.toString.js
index e9ace65d26..7b33f21183 100644
--- a/Libraries/LibJS/Tests/Array.prototype.toString.js
+++ b/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);
diff --git a/Libraries/LibJS/Tests/function-TypeError.js b/Libraries/LibJS/Tests/function-TypeError.js
index 1939e01f06..2909c802e3 100644
--- a/Libraries/LibJS/Tests/function-TypeError.js
+++ b/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");