diff --git a/Libraries/LibJS/Forward.h b/Libraries/LibJS/Forward.h index 130312fd44..6de9b6ce1f 100644 --- a/Libraries/LibJS/Forward.h +++ b/Libraries/LibJS/Forward.h @@ -26,36 +26,41 @@ #pragma once -#define JS_ENUMERATE_ERROR_SUBCLASSES \ - __JS_ENUMERATE_ERROR_SUBCLASS(EvalError, eval_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(InternalError, internal_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(RangeError, range_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(ReferenceError, reference_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(SyntaxError, syntax_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(TypeError, type_error) \ - __JS_ENUMERATE_ERROR_SUBCLASS(URIError, uri_error) +#define JS_ENUMERATE_NATIVE_OBJECTS \ + __JS_ENUMERATE(Array, array, ArrayPrototype, ArrayConstructor) \ + __JS_ENUMERATE(BooleanObject, boolean, BooleanPrototype, BooleanConstructor) \ + __JS_ENUMERATE(Date, date, DatePrototype, DateConstructor) \ + __JS_ENUMERATE(Error, error, ErrorPrototype, ErrorConstructor) \ + __JS_ENUMERATE(Function, function, FunctionPrototype, FunctionConstructor) \ + __JS_ENUMERATE(NumberObject, number, NumberPrototype, NumberConstructor) \ + __JS_ENUMERATE(Object, object, ObjectPrototype, ObjectConstructor) \ + __JS_ENUMERATE(StringObject, string, StringPrototype, StringConstructor) + +#define JS_ENUMERATE_ERROR_SUBCLASSES \ + __JS_ENUMERATE(EvalError, eval_error, EvalErrorPrototype, EvalErrorConstructor) \ + __JS_ENUMERATE(InternalError, internal_error, InternalErrorPrototype, InternalErrorConstructor) \ + __JS_ENUMERATE(RangeError, range_error, RangeErrorPrototype, RangeErrorConstructor) \ + __JS_ENUMERATE(ReferenceError, reference_error, ReferenceErrorPrototype, ReferenceErrorConstructor) \ + __JS_ENUMERATE(SyntaxError, syntax_error, SyntaxErrorPrototype, SyntaxErrorConstructor) \ + __JS_ENUMERATE(TypeError, type_error, TypeErrorPrototype, TypeErrorConstructor) \ + __JS_ENUMERATE(URIError, uri_error, URIErrorPrototype, URIErrorConstructor) + +#define JS_ENUMERATE_BUILTIN_TYPES \ + JS_ENUMERATE_NATIVE_OBJECTS \ + JS_ENUMERATE_ERROR_SUBCLASSES namespace JS { class ASTNode; -class ArrayConstructor; -class BooleanConstructor; class Cell; -class DateConstructor; class Error; -class ErrorConstructor; class Exception; class Expression; -class Function; -class FunctionConstructor; class GlobalObject; class HandleImpl; class Heap; class HeapBlock; class Interpreter; -class NumberConstructor; -class Object; -class ObjectConstructor; class PrimitiveString; class ScopeNode; class Shape; @@ -63,12 +68,12 @@ class Statement; class Value; enum class DeclarationKind; -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - class TitleCase; \ - class TitleCase##Constructor; \ - class TitleCase##Prototype; -JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#define __JS_ENUMERATE(ClassName, snake_name, ConstructorName, PrototypeName) \ + class ClassName; \ + class ConstructorName; \ + class PrototypeName; +JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE struct Argument; diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index b5a40b45f1..3d78095e08 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -49,19 +49,15 @@ Interpreter::Interpreter() { m_empty_object_shape = heap().allocate(); + // These are done first since other prototypes depend on their presence. m_object_prototype = heap().allocate(); m_function_prototype = heap().allocate(); - m_string_prototype = heap().allocate(); - m_array_prototype = heap().allocate(); - m_error_prototype = heap().allocate(); - m_date_prototype = heap().allocate(); - m_number_prototype = heap().allocate(); - m_boolean_prototype = heap().allocate(); -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - m_##snake_case##_prototype = heap().allocate(); - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + if (!m_##snake_name##_prototype) \ + m_##snake_name##_prototype = heap().allocate(); + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE } Interpreter::~Interpreter() @@ -178,25 +174,14 @@ Optional Interpreter::get_variable(const FlyString& name) void Interpreter::gather_roots(Badge, HashTable& roots) { roots.set(m_empty_object_shape); - roots.set(m_global_object); - roots.set(m_string_prototype); - roots.set(m_object_prototype); - roots.set(m_array_prototype); - roots.set(m_date_prototype); - roots.set(m_function_prototype); - roots.set(m_number_prototype); - roots.set(m_boolean_prototype); - - roots.set(m_error_prototype); - -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - roots.set(m_##snake_case##_prototype); - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS - roots.set(m_exception); +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + roots.set(m_##snake_name##_prototype); + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE + if (m_last_value.is_cell()) roots.set(m_last_value.as_cell()); diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 7a23cb9dc0..9d8baff992 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -136,22 +136,15 @@ public: Shape* empty_object_shape() { return m_empty_object_shape; } - Object* string_prototype() { return m_string_prototype; } - Object* object_prototype() { return m_object_prototype; } - Object* array_prototype() { return m_array_prototype; } - Object* date_prototype() { return m_date_prototype; } - Object* function_prototype() { return m_function_prototype; } - Object* number_prototype() { return m_number_prototype; } - Object* boolean_prototype() { return m_boolean_prototype; } +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + Object* snake_name##_prototype() { return m_##snake_name##_prototype; } + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE - Object* error_prototype() { return m_error_prototype; } - -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - Object* snake_case##_prototype() { return m_##snake_case##_prototype; } - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS - - Exception* exception() { return m_exception; } + Exception* exception() + { + return m_exception; + } void clear_exception() { m_exception = nullptr; } template @@ -180,21 +173,12 @@ private: Shape* m_empty_object_shape { nullptr }; +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + Object* m_##snake_name##_prototype { nullptr }; + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE + Object* m_global_object { nullptr }; - Object* m_string_prototype { nullptr }; - Object* m_object_prototype { nullptr }; - Object* m_array_prototype { nullptr }; - Object* m_date_prototype { nullptr }; - Object* m_function_prototype { nullptr }; - Object* m_number_prototype { nullptr }; - Object* m_boolean_prototype { nullptr }; - - Object* m_error_prototype { nullptr }; - -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - Object* m_##snake_case##_prototype; - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS Exception* m_exception { nullptr }; diff --git a/Libraries/LibJS/Runtime/Error.cpp b/Libraries/LibJS/Runtime/Error.cpp index 417f3735f8..3b986da50c 100644 --- a/Libraries/LibJS/Runtime/Error.cpp +++ b/Libraries/LibJS/Runtime/Error.cpp @@ -40,16 +40,16 @@ Error::~Error() { } -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - TitleCase::TitleCase(const String& message) \ - : Error(#TitleCase, message) \ - { \ - set_prototype(interpreter().snake_case##_prototype()); \ - } \ - TitleCase::~TitleCase() {} \ - const char* TitleCase::class_name() const { return #TitleCase; } +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + ClassName::ClassName(const String& message) \ + : Error(#ClassName, message) \ + { \ + set_prototype(interpreter().snake_name##_prototype()); \ + } \ + ClassName::~ClassName() {} \ + const char* ClassName::class_name() const { return #ClassName; } JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/Error.h b/Libraries/LibJS/Runtime/Error.h index fc42332baf..76615b4b9e 100644 --- a/Libraries/LibJS/Runtime/Error.h +++ b/Libraries/LibJS/Runtime/Error.h @@ -47,18 +47,18 @@ private: String m_message; }; -#define DECLARE_ERROR_SUBCLASS(TitleCase, snake_case) \ - class TitleCase final : public Error { \ - public: \ - TitleCase(const String& message); \ - virtual ~TitleCase() override; \ - \ - private: \ - virtual const char* class_name() const override; \ +#define DECLARE_ERROR_SUBCLASS(ClassName, snake_name, PrototypeName, ConstructorName) \ + class ClassName final : public Error { \ + public: \ + ClassName(const String& message); \ + virtual ~ClassName() override; \ + \ + private: \ + virtual const char* class_name() const override; \ }; -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - DECLARE_ERROR_SUBCLASS(TitleCase, snake_case) +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + DECLARE_ERROR_SUBCLASS(ClassName, snake_name, PrototypeName, ConstructorName) JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Libraries/LibJS/Runtime/ErrorConstructor.cpp index a5a2a625a8..b62018fe02 100644 --- a/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/Libraries/LibJS/Runtime/ErrorConstructor.cpp @@ -53,28 +53,26 @@ Value ErrorConstructor::construct(Interpreter& interpreter) return interpreter.heap().allocate("Error", message); } -#define DEFINE_ERROR_SUBCLASS_CONSTRUCTOR(TitleCase, snake_case) \ - TitleCase##Constructor::TitleCase##Constructor() \ +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + ConstructorName::ConstructorName() \ { \ - put("prototype", interpreter().snake_case##_prototype()); \ + put("prototype", interpreter().snake_name##_prototype()); \ put("length", Value(1)); \ } \ - TitleCase##Constructor::~TitleCase##Constructor() {} \ - Value TitleCase##Constructor::call(Interpreter& interpreter) \ + ConstructorName::~ConstructorName() {} \ + Value ConstructorName::call(Interpreter& interpreter) \ { \ return construct(interpreter); \ } \ - Value TitleCase##Constructor::construct(Interpreter& interpreter) \ + Value ConstructorName::construct(Interpreter& interpreter) \ { \ String message = ""; \ if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) \ message = interpreter.call_frame().arguments[0].to_string(); \ - return interpreter.heap().allocate(message); \ + return interpreter.heap().allocate(message); \ } -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - DEFINE_ERROR_SUBCLASS_CONSTRUCTOR(TitleCase, snake_case) JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.h b/Libraries/LibJS/Runtime/ErrorConstructor.h index 39c0cdf075..2e6c4ac337 100644 --- a/Libraries/LibJS/Runtime/ErrorConstructor.h +++ b/Libraries/LibJS/Runtime/ErrorConstructor.h @@ -44,22 +44,22 @@ private: virtual const char* class_name() const override { return "ErrorConstructor"; } }; -#define DECLARE_ERROR_SUBCLASS_CONSTRUCTOR(TitleCase, snake_case) \ - class TitleCase##Constructor final : public NativeFunction { \ - public: \ - TitleCase##Constructor(); \ - virtual ~TitleCase##Constructor() override; \ - virtual Value call(Interpreter&) override; \ - virtual Value construct(Interpreter&) override; \ - \ - private: \ - virtual bool has_constructor() const override { return true; } \ - virtual const char* class_name() const override { return #TitleCase "Constructor"; } \ +#define DECLARE_ERROR_SUBCLASS_CONSTRUCTOR(ClassName, snake_name, PrototypeName, ConstructorName) \ + class ConstructorName final : public NativeFunction { \ + public: \ + ConstructorName(); \ + virtual ~ConstructorName() override; \ + virtual Value call(Interpreter&) override; \ + virtual Value construct(Interpreter&) override; \ + \ + private: \ + virtual bool has_constructor() const override { return true; } \ + virtual const char* class_name() const override { return #ClassName "Constructor"; } \ }; -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - DECLARE_ERROR_SUBCLASS_CONSTRUCTOR(TitleCase, snake_case) +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + DECLARE_ERROR_SUBCLASS_CONSTRUCTOR(ClassName, snake_name, PrototypeName, ConstructorName) JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp index f35d25c4a3..1e193a567b 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -88,17 +88,15 @@ Value ErrorPrototype::to_string(Interpreter& interpreter) return js_string(interpreter, String::format("%s: %s", name.characters(), message.characters())); } -#define DEFINE_ERROR_SUBCLASS_PROTOTYPE(TitleCase, snake_case) \ - TitleCase::TitleCase() \ - { \ - set_prototype(interpreter().error_prototype()); \ - } \ - TitleCase::~TitleCase() {} \ - const char* TitleCase::class_name() const { return #TitleCase; } +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + PrototypeName::PrototypeName() \ + { \ + set_prototype(interpreter().error_prototype()); \ + } \ + PrototypeName::~PrototypeName() {} \ + const char* PrototypeName::class_name() const { return #PrototypeName; } -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - DEFINE_ERROR_SUBCLASS_PROTOTYPE(TitleCase##Prototype, snake_case##_prototype) JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.h b/Libraries/LibJS/Runtime/ErrorPrototype.h index c8ca9f7e85..ffc13a8345 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.h +++ b/Libraries/LibJS/Runtime/ErrorPrototype.h @@ -44,19 +44,19 @@ private: static Value message_getter(Interpreter&); }; -#define DECLARE_ERROR_SUBCLASS_PROTOTYPE(TitleCase, snake_case) \ - class TitleCase final : public Object { \ - public: \ - TitleCase(); \ - virtual ~TitleCase() override; \ - \ - private: \ - virtual const char* class_name() const override; \ +#define DECLARE_ERROR_SUBCLASS_PROTOTYPE(ClassName, snake_name, PrototypeName, ConstructorName) \ + class PrototypeName final : public Object { \ + public: \ + PrototypeName(); \ + virtual ~PrototypeName() override; \ + \ + private: \ + virtual const char* class_name() const override; \ }; -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - DECLARE_ERROR_SUBCLASS_PROTOTYPE(TitleCase##Prototype, snake_case##_prototype) +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + DECLARE_ERROR_SUBCLASS_PROTOTYPE(ClassName, snake_name, PrototypeName, ConstructorName) JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index fdb97aa982..b7eb4f3d05 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -73,10 +73,10 @@ GlobalObject::GlobalObject() add_constructor("Number", m_number_constructor, *interpreter().number_prototype()); add_constructor("Object", m_object_constructor, *interpreter().object_prototype()); -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - add_constructor(#TitleCase, m_##snake_case##_constructor, *interpreter().snake_case##_prototype()); +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + add_constructor(#ClassName, m_##snake_name##_constructor, *interpreter().snake_name##_prototype()); JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#undef __JS_ENUMERATE } GlobalObject::~GlobalObject() diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h index 101403003a..14f7bcf530 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Libraries/LibJS/Runtime/GlobalObject.h @@ -35,18 +35,10 @@ public: explicit GlobalObject(); virtual ~GlobalObject() override; - ArrayConstructor* array_constructor() { return m_array_constructor; } - BooleanConstructor* boolean_constructor() { return m_boolean_constructor; } - DateConstructor* date_constructor() { return m_date_constructor; } - FunctionConstructor* function_constructor() { return m_function_constructor; } - NumberConstructor* number_constructor() { return m_number_constructor; }; - ObjectConstructor* object_constructor() { return m_object_constructor; } - ErrorConstructor* error_constructor() { return m_error_constructor; } - -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - TitleCase##Constructor* snake_case##_constructor() { return m_##snake_case##_constructor; } - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE protected: virtual void visit_children(Visitor&) override; @@ -60,18 +52,10 @@ private: template void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype); - ArrayConstructor* m_array_constructor { nullptr }; - BooleanConstructor* m_boolean_constructor { nullptr }; - DateConstructor* m_date_constructor { nullptr }; - FunctionConstructor* m_function_constructor { nullptr }; - NumberConstructor* m_number_constructor { nullptr }; - ObjectConstructor* m_object_constructor { nullptr }; - ErrorConstructor* m_error_constructor { nullptr }; - -#define __JS_ENUMERATE_ERROR_SUBCLASS(TitleCase, snake_case) \ - TitleCase##Constructor* m_##snake_case##_constructor; - JS_ENUMERATE_ERROR_SUBCLASSES -#undef __JS_ENUMERATE_ERROR_SUBCLASS +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ + ConstructorName* m_##snake_name##_constructor { nullptr }; + JS_ENUMERATE_BUILTIN_TYPES +#undef __JS_ENUMERATE }; }