From 070a8f26892c3822f934e0028996d532924cad4b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 10 Apr 2020 13:04:12 +0200 Subject: [PATCH] LibJS: Boolean, Number and String prototypes should have values too It appears that calling .valueOf() on an objectified primitive's prototype should return a value after all. This matches what other engines are doing. --- Libraries/LibJS/Runtime/BooleanObject.cpp | 2 ++ Libraries/LibJS/Runtime/BooleanPrototype.cpp | 3 ++- Libraries/LibJS/Runtime/BooleanPrototype.h | 4 ++-- Libraries/LibJS/Runtime/NumberObject.h | 2 +- Libraries/LibJS/Runtime/NumberPrototype.cpp | 3 +++ Libraries/LibJS/Runtime/NumberPrototype.h | 4 ++-- Libraries/LibJS/Runtime/StringObject.h | 2 +- Libraries/LibJS/Runtime/StringPrototype.cpp | 2 ++ Libraries/LibJS/Runtime/StringPrototype.h | 4 ++-- Libraries/LibJS/Tests/Number.prototype.js | 8 ++++++++ Libraries/LibJS/Tests/String.prototype.js | 8 ++++++++ 11 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 Libraries/LibJS/Tests/Number.prototype.js create mode 100644 Libraries/LibJS/Tests/String.prototype.js diff --git a/Libraries/LibJS/Runtime/BooleanObject.cpp b/Libraries/LibJS/Runtime/BooleanObject.cpp index 4b30001de7..c0ac80d30b 100644 --- a/Libraries/LibJS/Runtime/BooleanObject.cpp +++ b/Libraries/LibJS/Runtime/BooleanObject.cpp @@ -28,6 +28,7 @@ #include namespace JS { + BooleanObject::BooleanObject(bool value) : m_value(value) { @@ -37,4 +38,5 @@ BooleanObject::BooleanObject(bool value) BooleanObject::~BooleanObject() { } + } diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Libraries/LibJS/Runtime/BooleanPrototype.cpp index 1bae1f8741..84b9639a60 100644 --- a/Libraries/LibJS/Runtime/BooleanPrototype.cpp +++ b/Libraries/LibJS/Runtime/BooleanPrototype.cpp @@ -26,14 +26,15 @@ #include #include -#include #include #include namespace JS { BooleanPrototype::BooleanPrototype() + : BooleanObject(false) { + set_prototype(interpreter().object_prototype()); put_native_function("toString", to_string); put_native_function("valueOf", value_of); } diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.h b/Libraries/LibJS/Runtime/BooleanPrototype.h index 795a058cd3..ea4142ebe2 100644 --- a/Libraries/LibJS/Runtime/BooleanPrototype.h +++ b/Libraries/LibJS/Runtime/BooleanPrototype.h @@ -26,11 +26,11 @@ #pragma once -#include +#include namespace JS { -class BooleanPrototype final : public Object { +class BooleanPrototype final : public BooleanObject { public: BooleanPrototype(); virtual ~BooleanPrototype() override; diff --git a/Libraries/LibJS/Runtime/NumberObject.h b/Libraries/LibJS/Runtime/NumberObject.h index aaa7f2569e..845cb46902 100644 --- a/Libraries/LibJS/Runtime/NumberObject.h +++ b/Libraries/LibJS/Runtime/NumberObject.h @@ -30,7 +30,7 @@ namespace JS { -class NumberObject final : public Object { +class NumberObject : public Object { public: explicit NumberObject(double); virtual ~NumberObject() override; diff --git a/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Libraries/LibJS/Runtime/NumberPrototype.cpp index ef87272141..5cad2b1e2a 100644 --- a/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/Libraries/LibJS/Runtime/NumberPrototype.cpp @@ -24,12 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include namespace JS { NumberPrototype::NumberPrototype() + : NumberObject(0) { + set_prototype(interpreter().object_prototype()); } NumberPrototype::~NumberPrototype() diff --git a/Libraries/LibJS/Runtime/NumberPrototype.h b/Libraries/LibJS/Runtime/NumberPrototype.h index 8ec9c544cc..d60823128d 100644 --- a/Libraries/LibJS/Runtime/NumberPrototype.h +++ b/Libraries/LibJS/Runtime/NumberPrototype.h @@ -26,11 +26,11 @@ #pragma once -#include +#include namespace JS { -class NumberPrototype final : public Object { +class NumberPrototype final : public NumberObject { public: NumberPrototype(); virtual ~NumberPrototype() override; diff --git a/Libraries/LibJS/Runtime/StringObject.h b/Libraries/LibJS/Runtime/StringObject.h index 76f05bbcce..2f914e4246 100644 --- a/Libraries/LibJS/Runtime/StringObject.h +++ b/Libraries/LibJS/Runtime/StringObject.h @@ -30,7 +30,7 @@ namespace JS { -class StringObject final : public Object { +class StringObject : public Object { public: explicit StringObject(PrimitiveString*); virtual ~StringObject() override; diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 4eb2469f16..27332652e5 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -38,7 +38,9 @@ namespace JS { StringPrototype::StringPrototype() + : StringObject(js_string(interpreter(), String::empty())) { + set_prototype(interpreter().object_prototype()); put_native_property("length", length_getter, nullptr); put_native_function("charAt", char_at, 1); put_native_function("repeat", repeat, 1); diff --git a/Libraries/LibJS/Runtime/StringPrototype.h b/Libraries/LibJS/Runtime/StringPrototype.h index b4982b71f9..e5dc6bfdb3 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Libraries/LibJS/Runtime/StringPrototype.h @@ -26,11 +26,11 @@ #pragma once -#include +#include namespace JS { -class StringPrototype final : public Object { +class StringPrototype final : public StringObject { public: StringPrototype(); virtual ~StringPrototype() override; diff --git a/Libraries/LibJS/Tests/Number.prototype.js b/Libraries/LibJS/Tests/Number.prototype.js new file mode 100644 index 0000000000..1ff4705fc0 --- /dev/null +++ b/Libraries/LibJS/Tests/Number.prototype.js @@ -0,0 +1,8 @@ +try { + assert(typeof Number.prototype === "object"); + assert(Number.prototype.valueOf() === 0); + + console.log("PASS"); +} catch (err) { + console.log("FAIL: " + err); +} diff --git a/Libraries/LibJS/Tests/String.prototype.js b/Libraries/LibJS/Tests/String.prototype.js new file mode 100644 index 0000000000..bc84e8dc0a --- /dev/null +++ b/Libraries/LibJS/Tests/String.prototype.js @@ -0,0 +1,8 @@ +try { + assert(typeof Object.getPrototypeOf("") === "object"); + assert(Object.getPrototypeOf("").valueOf() === ''); + + console.log("PASS"); +} catch (err) { + console.log("FAIL: " + err); +}