diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-28 17:23:54 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-28 17:23:54 +0100 |
commit | 14047ca4328bf55630fa2c01bfcdfd06ed6975ad (patch) | |
tree | b26e110e2fcd6d4257e391c957ba856258b454f7 /Libraries/LibJS | |
parent | a3d92b1210bad42a7563b6a7d9a8787d6d2586ed (diff) | |
download | serenity-14047ca4328bf55630fa2c01bfcdfd06ed6975ad.zip |
LibJS: Add a global "Object" constructor
This patch adds an "Object" constructor to the global object. The only
function it implements so far is Object.getPrototypeOf().
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r-- | Libraries/LibJS/Interpreter.cpp | 3 | ||||
-rw-r--r-- | Libraries/LibJS/Makefile | 1 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/GlobalObject.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/NativeFunction.h | 5 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ObjectConstructor.cpp | 59 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ObjectConstructor.h | 44 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/Value.h | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/Object.getPrototypeOf.js | 11 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/Object.prototype.js | 10 |
9 files changed, 134 insertions, 3 deletions
diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index 186fc8eefb..36d891ef22 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -42,11 +42,12 @@ namespace JS { Interpreter::Interpreter() : m_heap(*this) { - m_global_object = heap().allocate<GlobalObject>(); m_object_prototype = heap().allocate<ObjectPrototype>(); m_string_prototype = heap().allocate<StringPrototype>(); m_array_prototype = heap().allocate<ArrayPrototype>(); m_error_prototype = heap().allocate<ErrorPrototype>(); + + m_global_object = heap().allocate<GlobalObject>(); } Interpreter::~Interpreter() diff --git a/Libraries/LibJS/Makefile b/Libraries/LibJS/Makefile index 97d35be52d..ad85857e3f 100644 --- a/Libraries/LibJS/Makefile +++ b/Libraries/LibJS/Makefile @@ -19,6 +19,7 @@ OBJS = \ Runtime/NativeFunction.o \ Runtime/NativeProperty.o \ Runtime/Object.o \ + Runtime/ObjectConstructor.o \ Runtime/ObjectPrototype.o \ Runtime/PrimitiveString.o \ Runtime/ScriptFunction.o \ diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index b45fb867ca..18553b161d 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -6,6 +6,7 @@ #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/MathObject.h> #include <LibJS/Runtime/NativeFunction.h> +#include <LibJS/Runtime/ObjectConstructor.h> #include <LibJS/Runtime/Value.h> namespace JS { @@ -24,6 +25,7 @@ GlobalObject::GlobalObject() return Value(arguments[0].to_number().is_nan()); }); put("Math", heap().allocate<MathObject>()); + put("Object", heap().allocate<ObjectConstructor>()); } GlobalObject::~GlobalObject() diff --git a/Libraries/LibJS/Runtime/NativeFunction.h b/Libraries/LibJS/Runtime/NativeFunction.h index a57d7b8f47..739a9eac12 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Libraries/LibJS/Runtime/NativeFunction.h @@ -31,13 +31,16 @@ namespace JS { -class NativeFunction final : public Function { +class NativeFunction : public Function { public: explicit NativeFunction(AK::Function<Value(Object*, const Vector<Value>&)>); virtual ~NativeFunction() override; virtual Value call(Interpreter&, const Vector<Value>&) override; +protected: + NativeFunction() {} + private: virtual bool is_native_function() const override { return true; } virtual const char* class_name() const override { return "NativeFunction"; } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp new file mode 100644 index 0000000000..998cb4b512 --- /dev/null +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/Function.h> +#include <LibJS/Heap/Heap.h> +#include <LibJS/Interpreter.h> +#include <LibJS/Runtime/ObjectConstructor.h> + +namespace JS { + +ObjectConstructor::ObjectConstructor() +{ + put("prototype", interpreter().object_prototype()); + + put_native_function("getPrototypeOf", [this](Object*, const Vector<Value>& arguments) -> Value { + if (arguments.size() < 1) + return {}; + auto object = arguments[0].to_object(heap()); + if (interpreter().exception()) + return {}; + if (!object.is_object()) + return {}; + return object.as_object()->prototype(); + }); +} + +ObjectConstructor::~ObjectConstructor() +{ +} + +Value ObjectConstructor::call(Interpreter& interpreter, const Vector<Value>&) +{ + return interpreter.heap().allocate<Object>(); +} + +} diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.h b/Libraries/LibJS/Runtime/ObjectConstructor.h new file mode 100644 index 0000000000..4b8d4a3b12 --- /dev/null +++ b/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <LibJS/Runtime/NativeFunction.h> + +namespace JS { + +class ObjectConstructor final : public NativeFunction { +public: + ObjectConstructor(); + virtual ~ObjectConstructor() override; + + virtual Value call(Interpreter&, const Vector<Value>&) override; + +private: + virtual const char* class_name() const override { return "ObjectConstructor"; } +}; + +} diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 5250d108fd..9d348b56f6 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -79,7 +79,7 @@ public: } Value(Object* object) - : m_type(Type::Object) + : m_type(object ? Type::Object : Type::Null) { m_value.as_object = object; } diff --git a/Libraries/LibJS/Tests/Object.getPrototypeOf.js b/Libraries/LibJS/Tests/Object.getPrototypeOf.js new file mode 100644 index 0000000000..6b48fc28b8 --- /dev/null +++ b/Libraries/LibJS/Tests/Object.getPrototypeOf.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var o1 = new Object(); + var o2 = {}; + assert(Object.getPrototypeOf(o1) === Object.getPrototypeOf(o2)); + assert(Object.getPrototypeOf(Object.getPrototypeOf(o1)) === null); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Object.prototype.js b/Libraries/LibJS/Tests/Object.prototype.js new file mode 100644 index 0000000000..237de47a98 --- /dev/null +++ b/Libraries/LibJS/Tests/Object.prototype.js @@ -0,0 +1,10 @@ +function assert(x) { if (!x) throw 1; } + +try { + var o = new Object(); + Object.prototype.foo = 123; + assert(o.foo === 123); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} |