diff options
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/GlobalObject.h')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/GlobalObject.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h new file mode 100644 index 0000000000..d3b7041e43 --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h @@ -0,0 +1,133 @@ +/* + * 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/Heap/Heap.h> +#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/VM.h> + +namespace JS { + +class GlobalObject : public ScopeObject { + JS_OBJECT(GlobalObject, ScopeObject); + +public: + explicit GlobalObject(); + virtual void initialize(); + + virtual ~GlobalObject() override; + + virtual Optional<Variable> get_from_scope(const FlyString&) const override; + virtual void put_to_scope(const FlyString&, Variable) override; + virtual bool has_this_binding() const override; + virtual Value get_this_binding(GlobalObject&) const override; + + Console& console() { return *m_console; } + + Shape* empty_object_shape() { return m_empty_object_shape; } + + Shape* new_object_shape() { return m_new_object_shape; } + Shape* new_script_function_prototype_object_shape() { return m_new_script_function_prototype_object_shape; } + + // Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype + ProxyConstructor* proxy_constructor() { return m_proxy_constructor; } + +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ + ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } \ + Object* snake_name##_prototype() { return m_##snake_name##_prototype; } + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE + +#define __JS_ENUMERATE(ClassName, snake_name) \ + Object* snake_name##_prototype() { return m_##snake_name##_prototype; } + JS_ENUMERATE_ITERATOR_PROTOTYPES +#undef __JS_ENUMERATE + +protected: + virtual void visit_edges(Visitor&) override; + + template<typename ConstructorType> + void initialize_constructor(const FlyString& property_name, ConstructorType*&, Object* prototype); + template<typename ConstructorType> + void add_constructor(const FlyString& property_name, ConstructorType*&, Object* prototype); + +private: + JS_DECLARE_NATIVE_FUNCTION(gc); + JS_DECLARE_NATIVE_FUNCTION(is_nan); + JS_DECLARE_NATIVE_FUNCTION(is_finite); + JS_DECLARE_NATIVE_FUNCTION(parse_float); + JS_DECLARE_NATIVE_FUNCTION(parse_int); + + NonnullOwnPtr<Console> m_console; + + Shape* m_empty_object_shape { nullptr }; + Shape* m_new_object_shape { nullptr }; + Shape* m_new_script_function_prototype_object_shape { nullptr }; + + // Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype + ProxyConstructor* m_proxy_constructor { nullptr }; + +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ + ConstructorName* m_##snake_name##_constructor { nullptr }; \ + Object* m_##snake_name##_prototype { nullptr }; + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE + +#define __JS_ENUMERATE(ClassName, snake_name) \ + Object* m_##snake_name##_prototype { nullptr }; + JS_ENUMERATE_ITERATOR_PROTOTYPES +#undef __JS_ENUMERATE +}; + +template<typename ConstructorType> +inline void GlobalObject::initialize_constructor(const FlyString& property_name, ConstructorType*& constructor, Object* prototype) +{ + auto& vm = this->vm(); + constructor = heap().allocate<ConstructorType>(*this, *this); + constructor->define_property(vm.names.name, js_string(heap(), property_name), Attribute::Configurable); + if (vm.exception()) + return; + if (prototype) { + prototype->define_property(vm.names.constructor, constructor, Attribute::Writable | Attribute::Configurable); + if (vm.exception()) + return; + } +} + +template<typename ConstructorType> +inline void GlobalObject::add_constructor(const FlyString& property_name, ConstructorType*& constructor, Object* prototype) +{ + initialize_constructor(property_name, constructor, prototype); + define_property(property_name, constructor, Attribute::Writable | Attribute::Configurable); +} + +inline GlobalObject* Shape::global_object() const +{ + return static_cast<GlobalObject*>(m_global_object); +} + +} |