diff --git a/Userland/Libraries/LibJS/CMakeLists.txt b/Userland/Libraries/LibJS/CMakeLists.txt index 2159ca1671..9ba77f12ce 100644 --- a/Userland/Libraries/LibJS/CMakeLists.txt +++ b/Userland/Libraries/LibJS/CMakeLists.txt @@ -118,6 +118,8 @@ set(SOURCES Runtime/Intl/Segmenter.cpp Runtime/Intl/SegmenterConstructor.cpp Runtime/Intl/SegmenterPrototype.cpp + Runtime/Intl/Segments.cpp + Runtime/Intl/SegmentsPrototype.cpp Runtime/IteratorOperations.cpp Runtime/IteratorPrototype.cpp Runtime/JSONObject.cpp diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 3621ca2874..91197d7ca0 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -218,6 +218,10 @@ namespace Intl { class PrototypeName; JS_ENUMERATE_INTL_OBJECTS #undef __JS_ENUMERATE + +// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor +class Segments; +class SegmentsPrototype; }; namespace Temporal { diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 2c39eec2a1..d5c43448f1 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +182,8 @@ void GlobalObject::initialize_global_object() m_async_from_sync_iterator_prototype = heap().allocate(*this, *this); + m_intl_segments_prototype = heap().allocate(*this, *this); + #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ if (!m_##snake_name##_prototype) \ m_##snake_name##_prototype = heap().allocate(*this, *this); @@ -323,6 +326,7 @@ void GlobalObject::visit_edges(Visitor& visitor) visitor.visit(m_proxy_constructor); visitor.visit(m_generator_prototype); visitor.visit(m_async_from_sync_iterator_prototype); + visitor.visit(m_intl_segments_prototype); visitor.visit(m_array_prototype_values_function); visitor.visit(m_date_constructor_now_function); visitor.visit(m_eval_function); diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h index a1fa0f2a54..172d9888e2 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h @@ -38,6 +38,9 @@ public: GeneratorPrototype* generator_prototype() { return m_generator_prototype; } AsyncFromSyncIteratorPrototype* async_from_sync_iterator_prototype() { return m_async_from_sync_iterator_prototype; } + // Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor + Intl::SegmentsPrototype* intl_segments_prototype() { return m_intl_segments_prototype; } + FunctionObject* array_prototype_values_function() const { return m_array_prototype_values_function; } FunctionObject* date_constructor_now_function() const { return m_date_constructor_now_function; } FunctionObject* eval_function() const { return m_eval_function; } @@ -106,6 +109,9 @@ private: GeneratorPrototype* m_generator_prototype { nullptr }; AsyncFromSyncIteratorPrototype* m_async_from_sync_iterator_prototype { nullptr }; + // Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor + Intl::SegmentsPrototype* m_intl_segments_prototype { nullptr }; + FunctionObject* m_array_prototype_values_function { nullptr }; FunctionObject* m_date_constructor_now_function { nullptr }; FunctionObject* m_eval_function { nullptr }; diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp new file mode 100644 index 0000000000..31907e1edb --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace JS::Intl { + +// 18.5.1 CreateSegmentsObject ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject +Segments* Segments::create(GlobalObject& global_object, Segmenter& segmenter, String string) +{ + // 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ». + // 2. Let segments be ! OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList). + // 3. Set segments.[[SegmentsSegmenter]] to segmenter. + // 4. Set segments.[[SegmentsString]] to string. + // 5. Return segments. + return global_object.heap().allocate(global_object, global_object, segmenter, move(string)); +} + +// 18.5 Segments Objects, https://tc39.es/ecma402/#sec-segments-objects +Segments::Segments(GlobalObject& global_object, Segmenter& segmenter, String string) + : Object(*global_object.intl_segments_prototype()) + , m_segments_segmenter(segmenter) + , m_segments_string(move(string)) +{ +} + +void Segments::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(&m_segments_segmenter); +} + +} diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Segments.h b/Userland/Libraries/LibJS/Runtime/Intl/Segments.h new file mode 100644 index 0000000000..26e1424495 --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Intl/Segments.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace JS::Intl { + +class Segments final : public Object { + JS_OBJECT(Segments, Object); + +public: + static Segments* create(GlobalObject&, Segmenter&, String); + + Segments(GlobalObject&, Segmenter&, String); + virtual ~Segments() override = default; + + Segmenter& segments_segmenter() const { return m_segments_segmenter; } + + String const& segments_string() const { return m_segments_string; } + +private: + virtual void visit_edges(Cell::Visitor&) override; + + Segmenter& m_segments_segmenter; // [[SegmentsSegmenter]] + String m_segments_string; // [[SegmentsString]] +}; + +} diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp new file mode 100644 index 0000000000..7a0bfd999f --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace JS::Intl { + +// 18.5.2 The %SegmentsPrototype% Object, https://tc39.es/ecma402/#sec-%segmentsprototype%-object +SegmentsPrototype::SegmentsPrototype(GlobalObject& global_object) + : PrototypeObject(*global_object.object_prototype()) +{ +} + +void SegmentsPrototype::initialize(GlobalObject& global_object) +{ + Object::initialize(global_object); +} + +} diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.h b/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.h new file mode 100644 index 0000000000..77a526a2b4 --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Intl/SegmentsPrototype.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace JS::Intl { + +class SegmentsPrototype final : public PrototypeObject { + JS_PROTOTYPE_OBJECT(SegmentsPrototype, Segments, Segments); + +public: + explicit SegmentsPrototype(GlobalObject&); + virtual void initialize(GlobalObject&) override; + virtual ~SegmentsPrototype() override = default; +}; + +}