diff options
47 files changed, 78 insertions, 107 deletions
diff --git a/Applications/Spreadsheet/SpreadsheetModel.cpp b/Applications/Spreadsheet/SpreadsheetModel.cpp index 84b34a5e99..70193e4b63 100644 --- a/Applications/Spreadsheet/SpreadsheetModel.cpp +++ b/Applications/Spreadsheet/SpreadsheetModel.cpp @@ -54,7 +54,7 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) auto value = exception->value(); if (value.is_object()) { auto& object = value.as_object(); - if (object.is_error()) { + if (is<JS::Error>(object)) { auto error = object.get("message").to_string_without_side_effects(); builder.append(error); return builder.to_string(); diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index cf45f31dd5..5f1eab55e5 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -61,7 +61,7 @@ static void update_function_name(Value value, const FlyString& name, HashTable<J auto& object = value.as_object(); if (object.is_function()) { auto& function = static_cast<Function&>(object); - if (function.is_script_function() && function.name().is_empty()) + if (is<ScriptFunction>(function) && function.name().is_empty()) static_cast<ScriptFunction&>(function).set_name(name); } else if (object.is_array()) { auto& array = static_cast<Array&>(object); @@ -178,7 +178,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj ASSERT(!callee.is_empty()); if (!callee.is_function() - || (is_new_expression() && (callee.as_object().is_native_function() && !static_cast<NativeFunction&>(callee.as_object()).has_constructor()))) { + || (is_new_expression() && (is<NativeFunction>(callee.as_object()) && !static_cast<NativeFunction&>(callee.as_object()).has_constructor()))) { String error_message; auto call_type = is_new_expression() ? "constructor" : "function"; if (m_callee->is_identifier() || m_callee->is_member_expression()) { @@ -793,7 +793,7 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob update_function_name(class_constructor_value, m_name); - ASSERT(class_constructor_value.is_function() && class_constructor_value.as_function().is_script_function()); + ASSERT(class_constructor_value.is_function() && is<ScriptFunction>(class_constructor_value.as_function())); ScriptFunction* class_constructor = static_cast<ScriptFunction*>(&class_constructor_value.as_function()); class_constructor->set_is_class_constructor(); Value super_constructor = js_undefined(); diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index c46bf48475..b62c5482a0 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -190,7 +190,7 @@ Value Interpreter::execute_statement(GlobalObject& global_object, const Statemen LexicalEnvironment* Interpreter::current_environment() { - ASSERT(vm().call_frame().scope->is_lexical_environment()); + ASSERT(is<LexicalEnvironment>(vm().call_frame().scope)); return static_cast<LexicalEnvironment*>(vm().call_frame().scope); } diff --git a/Libraries/LibJS/MarkupGenerator.cpp b/Libraries/LibJS/MarkupGenerator.cpp index db6f01e767..afdd347098 100644 --- a/Libraries/LibJS/MarkupGenerator.cpp +++ b/Libraries/LibJS/MarkupGenerator.cpp @@ -77,9 +77,9 @@ void MarkupGenerator::value_to_html(Value value, StringBuilder& output_html, Has auto& object = value.as_object(); if (object.is_function()) return function_to_html(object, output_html, seen_objects); - if (object.is_date()) + if (is<Date>(object)) return date_to_html(object, output_html, seen_objects); - if (object.is_error()) + if (is<Error>(object)) return error_to_html(object, output_html, seen_objects); return object_to_html(object, output_html, seen_objects); } diff --git a/Libraries/LibJS/Runtime/ArrayBuffer.h b/Libraries/LibJS/Runtime/ArrayBuffer.h index cd9c92dcd1..d2724cd96e 100644 --- a/Libraries/LibJS/Runtime/ArrayBuffer.h +++ b/Libraries/LibJS/Runtime/ArrayBuffer.h @@ -45,8 +45,6 @@ public: const ByteBuffer& buffer() const { return m_buffer; } private: - virtual bool is_array_buffer() const override { return true; } - ByteBuffer m_buffer; }; diff --git a/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp b/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp index 320895893e..4a2ae30351 100644 --- a/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp @@ -59,7 +59,7 @@ static ArrayBuffer* array_buffer_object_from(VM& vm, GlobalObject& global_object if (!this_value.is_object()) return nullptr; auto& this_object = this_value.as_object(); - if (!this_object.is_array_buffer()) { + if (!is<ArrayBuffer>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "ArrayBuffer"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/ArrayIterator.h b/Libraries/LibJS/Runtime/ArrayIterator.h index bd68d96eeb..30ec25b70f 100644 --- a/Libraries/LibJS/Runtime/ArrayIterator.h +++ b/Libraries/LibJS/Runtime/ArrayIterator.h @@ -46,7 +46,6 @@ public: private: friend class ArrayIteratorPrototype; - virtual bool is_array_iterator_object() const override { return true; } virtual void visit_edges(Cell::Visitor&) override; Value m_array; diff --git a/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp b/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp index 6872f2ddad..c3cbd179b0 100644 --- a/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp @@ -54,7 +54,7 @@ ArrayIteratorPrototype::~ArrayIteratorPrototype() JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next) { auto this_value = vm.this_value(global_object); - if (!this_value.is_object() || !this_value.as_object().is_array_iterator_object()) { + if (!this_value.is_object() || !is<ArrayIterator>(this_value.as_object())) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Array Iterator"); return {}; } diff --git a/Libraries/LibJS/Runtime/BigIntObject.h b/Libraries/LibJS/Runtime/BigIntObject.h index 274e606327..f58183e4c3 100644 --- a/Libraries/LibJS/Runtime/BigIntObject.h +++ b/Libraries/LibJS/Runtime/BigIntObject.h @@ -48,7 +48,6 @@ public: private: virtual void visit_edges(Visitor&) override; - virtual bool is_bigint_object() const override { return true; } BigInt& m_bigint; }; diff --git a/Libraries/LibJS/Runtime/BigIntPrototype.cpp b/Libraries/LibJS/Runtime/BigIntPrototype.cpp index a71c9b260e..84b6617fe5 100644 --- a/Libraries/LibJS/Runtime/BigIntPrototype.cpp +++ b/Libraries/LibJS/Runtime/BigIntPrototype.cpp @@ -58,7 +58,7 @@ static BigIntObject* bigint_object_from(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_bigint_object()) { + if (!is<BigIntObject>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "BigInt"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/BooleanObject.h b/Libraries/LibJS/Runtime/BooleanObject.h index eade92c275..4b9775205a 100644 --- a/Libraries/LibJS/Runtime/BooleanObject.h +++ b/Libraries/LibJS/Runtime/BooleanObject.h @@ -44,7 +44,6 @@ public: } private: - virtual bool is_boolean_object() const override { return true; } bool m_value { false }; }; } diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Libraries/LibJS/Runtime/BooleanPrototype.cpp index aff90c07dc..dd69ff57dc 100644 --- a/Libraries/LibJS/Runtime/BooleanPrototype.cpp +++ b/Libraries/LibJS/Runtime/BooleanPrototype.cpp @@ -50,30 +50,28 @@ BooleanPrototype::~BooleanPrototype() JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::to_string) { - auto this_object = vm.this_value(global_object); - if (this_object.is_boolean()) { - return js_string(vm, this_object.as_bool() ? "true" : "false"); - } - if (!this_object.is_object() || !this_object.as_object().is_boolean_object()) { + auto this_value = vm.this_value(global_object); + if (this_value.is_boolean()) + return js_string(vm, this_value.as_bool() ? "true" : "false"); + if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object())) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean"); return {}; } - bool bool_value = static_cast<BooleanObject&>(this_object.as_object()).value_of().as_bool(); + bool bool_value = static_cast<const BooleanObject&>(this_value.as_object()).value_of().as_bool(); return js_string(vm, bool_value ? "true" : "false"); } JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::value_of) { - auto this_object = vm.this_value(global_object); - if (this_object.is_boolean()) { - return this_object; - } - if (!this_object.is_object() || !this_object.as_object().is_boolean_object()) { + auto this_value = vm.this_value(global_object); + if (this_value.is_boolean()) + return this_value; + if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object())) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean"); return {}; } - return static_cast<BooleanObject&>(this_object.as_object()).value_of(); + return static_cast<const BooleanObject&>(this_value.as_object()).value_of(); } } diff --git a/Libraries/LibJS/Runtime/BoundFunction.h b/Libraries/LibJS/Runtime/BoundFunction.h index e20d1a8a05..8d4c3a443c 100644 --- a/Libraries/LibJS/Runtime/BoundFunction.h +++ b/Libraries/LibJS/Runtime/BoundFunction.h @@ -59,8 +59,6 @@ public: virtual bool is_strict_mode() const override { return m_target_function->is_strict_mode(); } private: - virtual bool is_bound_function() const override { return true; } - Function* m_target_function = nullptr; Object* m_constructor_prototype = nullptr; FlyString m_name; diff --git a/Libraries/LibJS/Runtime/Cell.h b/Libraries/LibJS/Runtime/Cell.h index 4bbcb359f6..0f1ff18860 100644 --- a/Libraries/LibJS/Runtime/Cell.h +++ b/Libraries/LibJS/Runtime/Cell.h @@ -30,6 +30,7 @@ #include <AK/Forward.h> #include <AK/Noncopyable.h> #include <AK/String.h> +#include <AK/TypeCasts.h> #include <LibJS/Forward.h> namespace JS { diff --git a/Libraries/LibJS/Runtime/Date.h b/Libraries/LibJS/Runtime/Date.h index d1b08aa8de..368cc91bc2 100644 --- a/Libraries/LibJS/Runtime/Date.h +++ b/Libraries/LibJS/Runtime/Date.h @@ -85,7 +85,6 @@ public: private: tm to_utc_tm() const; - virtual bool is_date() const final { return true; } Core::DateTime m_datetime; u16 m_milliseconds; diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp index b84cbff3df..72fea9ca25 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -40,7 +40,7 @@ static Date* typed_this(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_date()) { + if (!is<Date>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Date"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/Error.h b/Libraries/LibJS/Runtime/Error.h index e186b13e17..3605825f1d 100644 --- a/Libraries/LibJS/Runtime/Error.h +++ b/Libraries/LibJS/Runtime/Error.h @@ -46,8 +46,6 @@ public: void set_name(const FlyString& name) { m_name = name; } private: - virtual bool is_error() const final { return true; } - FlyString m_name; String m_message; }; diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp index 151924b76a..29dfb72650 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -58,7 +58,7 @@ JS_DEFINE_NATIVE_GETTER(ErrorPrototype::name_getter) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return {}; - if (!this_object->is_error()) { + if (!is<Error>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error"); return {}; } @@ -70,7 +70,7 @@ JS_DEFINE_NATIVE_SETTER(ErrorPrototype::name_setter) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return; - if (!this_object->is_error()) { + if (!is<Error>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error"); return; } @@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_GETTER(ErrorPrototype::message_getter) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return {}; - if (!this_object->is_error()) { + if (!is<Error>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error"); return {}; } diff --git a/Libraries/LibJS/Runtime/Function.cpp b/Libraries/LibJS/Runtime/Function.cpp index e0bd52c0e5..43b7d6e7e1 100644 --- a/Libraries/LibJS/Runtime/Function.cpp +++ b/Libraries/LibJS/Runtime/Function.cpp @@ -50,7 +50,7 @@ Function::~Function() BoundFunction* Function::bind(Value bound_this_value, Vector<Value> arguments) { auto& vm = this->vm(); - Function& target_function = is_bound_function() ? static_cast<BoundFunction&>(*this).target_function() : *this; + Function& target_function = is<BoundFunction>(*this) ? static_cast<BoundFunction&>(*this).target_function() : *this; auto bound_this_object = [&vm, bound_this_value, this]() -> Value { if (!m_bound_this.is_empty()) diff --git a/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Libraries/LibJS/Runtime/FunctionPrototype.cpp index b4dbbee602..515b7fcc41 100644 --- a/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -34,6 +34,7 @@ #include <LibJS/Runtime/FunctionPrototype.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/MarkedValueList.h> +#include <LibJS/Runtime/NativeFunction.h> #include <LibJS/Runtime/ScriptFunction.h> namespace JS { @@ -148,7 +149,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string) String function_parameters = ""; String function_body; - if (this_object->is_native_function() || this_object->is_bound_function()) { + if (is<NativeFunction>(this_object) || is<BoundFunction>(this_object)) { function_body = String::formatted(" [{}]", this_object->class_name()); } else { StringBuilder parameters_builder; diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h index 6e67c4f8fa..0b2163e3f4 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Libraries/LibJS/Runtime/GlobalObject.h @@ -76,8 +76,6 @@ protected: void add_constructor(const FlyString& property_name, ConstructorType*&, Object* prototype); private: - virtual bool is_global_object() const final { return true; } - JS_DECLARE_NATIVE_FUNCTION(gc); JS_DECLARE_NATIVE_FUNCTION(is_nan); JS_DECLARE_NATIVE_FUNCTION(is_finite); diff --git a/Libraries/LibJS/Runtime/JSONObject.cpp b/Libraries/LibJS/Runtime/JSONObject.cpp index 692b0b5566..e6a6f27aee 100644 --- a/Libraries/LibJS/Runtime/JSONObject.cpp +++ b/Libraries/LibJS/Runtime/JSONObject.cpp @@ -30,10 +30,14 @@ #include <AK/JsonParser.h> #include <AK/StringBuilder.h> #include <LibJS/Runtime/Array.h> +#include <LibJS/Runtime/BigIntObject.h> +#include <LibJS/Runtime/BooleanObject.h> #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/JSONObject.h> +#include <LibJS/Runtime/NumberObject.h> #include <LibJS/Runtime/Object.h> +#include <LibJS/Runtime/StringObject.h> namespace JS { @@ -81,7 +85,7 @@ String JSONObject::stringify_impl(GlobalObject& global_object, Value value, Valu return {}; } else if (replacer_value.is_object()) { auto& value_object = replacer_value.as_object(); - if (value_object.is_string_object() || value_object.is_number_object()) { + if (is<StringObject>(value_object) || is<NumberObject>(value_object)) { item = value_object.value_of().to_string(global_object); if (vm.exception()) return {}; @@ -97,7 +101,7 @@ String JSONObject::stringify_impl(GlobalObject& global_object, Value value, Valu if (space.is_object()) { auto& space_obj = space.as_object(); - if (space_obj.is_string_object() || space_obj.is_number_object()) + if (is<StringObject>(space_obj) || is<NumberObject>(space_obj)) space = space_obj.value_of(); } @@ -172,7 +176,7 @@ String JSONObject::serialize_json_property(GlobalObject& global_object, Stringif if (value.is_object()) { auto& value_object = value.as_object(); - if (value_object.is_number_object() || value_object.is_boolean_object() || value_object.is_string_object() || value_object.is_bigint_object()) + if (is<NumberObject>(value_object) || is<BooleanObject>(value_object) || is<StringObject>(value_object) || is<BigIntObject>(value_object)) value = value_object.value_of(); } diff --git a/Libraries/LibJS/Runtime/LexicalEnvironment.h b/Libraries/LibJS/Runtime/LexicalEnvironment.h index 7dade90a8f..1e4b4723d1 100644 --- a/Libraries/LibJS/Runtime/LexicalEnvironment.h +++ b/Libraries/LibJS/Runtime/LexicalEnvironment.h @@ -85,7 +85,6 @@ public: EnvironmentRecordType type() const { return m_environment_record_type; } private: - virtual bool is_lexical_environment() const final { return true; } virtual void visit_edges(Visitor&) override; EnvironmentRecordType m_environment_record_type : 8 { EnvironmentRecordType::Declarative }; diff --git a/Libraries/LibJS/Runtime/NativeFunction.h b/Libraries/LibJS/Runtime/NativeFunction.h index 9f9f966684..a37336329f 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Libraries/LibJS/Runtime/NativeFunction.h @@ -54,7 +54,6 @@ protected: explicit NativeFunction(Object& prototype); private: - virtual bool is_native_function() const override { return true; } virtual LexicalEnvironment* create_environment() override final; FlyString m_name; diff --git a/Libraries/LibJS/Runtime/NumberObject.h b/Libraries/LibJS/Runtime/NumberObject.h index ffb394b6c9..7ae5e71451 100644 --- a/Libraries/LibJS/Runtime/NumberObject.h +++ b/Libraries/LibJS/Runtime/NumberObject.h @@ -39,7 +39,6 @@ public: NumberObject(double, Object& prototype); virtual ~NumberObject() override; - virtual bool is_number_object() const override { return true; } virtual Value value_of() const override { return Value(m_value); } double number() const { return m_value; } diff --git a/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Libraries/LibJS/Runtime/NumberPrototype.cpp index 78ac301606..94add9a146 100644 --- a/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/Libraries/LibJS/Runtime/NumberPrototype.cpp @@ -66,7 +66,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string) auto this_value = vm.this_value(global_object); if (this_value.is_number()) { number_value = this_value; - } else if (this_value.is_object() && this_value.as_object().is_number_object()) { + } else if (this_value.is_object() && is<NumberObject>(this_value.as_object())) { number_value = static_cast<NumberObject&>(this_value.as_object()).value_of(); } else { vm.throw_exception<TypeError>(global_object, ErrorType::NumberIncompatibleThis, "toString"); diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index d5e9976fb0..bb03709e5d 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -191,7 +191,7 @@ Value Object::get_own_properties(const Object& this_object, PropertyKind kind, b auto* properties_array = Array::create(global_object()); // FIXME: Support generic iterables - if (this_object.is_string_object()) { + if (is<StringObject>(this_object)) { auto str = static_cast<const StringObject&>(this_object).primitive_string().string(); for (size_t i = 0; i < str.length(); ++i) { @@ -662,7 +662,7 @@ Value Object::get_by_index(u32 property_index) const { const Object* object = this; while (object) { - if (is_string_object()) { + if (is<StringObject>(*this)) { auto& string = static_cast<const StringObject*>(this)->primitive_string().string(); if (property_index < string.length()) return js_string(heap(), string.substring(property_index, 1)); @@ -841,7 +841,7 @@ bool Object::has_own_property(const PropertyName& property_name) const ASSERT(property_name.is_valid()); auto has_indexed_property = [&](u32 index) -> bool { - if (is_string_object()) + if (is<StringObject>(*this)) return index < static_cast<const StringObject*>(this)->primitive_string().string().length(); return m_indexed_properties.has_index(index); }; diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h index 50d756ab27..1b3d757253 100644 --- a/Libraries/LibJS/Runtime/Object.h +++ b/Libraries/LibJS/Runtime/Object.h @@ -110,25 +110,8 @@ public: virtual Value delete_property(const PropertyName&); virtual bool is_array() const { return false; } - virtual bool is_date() const { return false; } - virtual bool is_error() const { return false; } virtual bool is_function() const { return false; } - virtual bool is_native_function() const { return false; } - virtual bool is_script_function() const { return false; } - virtual bool is_bound_function() const { return false; } - virtual bool is_proxy_object() const { return false; } - virtual bool is_regexp_object() const { return false; } - virtual bool is_boolean_object() const { return false; } - virtual bool is_string_object() const { return false; } - virtual bool is_number_object() const { return false; } - virtual bool is_symbol_object() const { return false; } - virtual bool is_bigint_object() const { return false; } - virtual bool is_string_iterator_object() const { return false; } - virtual bool is_array_iterator_object() const { return false; } - virtual bool is_lexical_environment() const { return false; } - virtual bool is_global_object() const { return false; } virtual bool is_typed_array() const { return false; } - virtual bool is_array_buffer() const { return false; } virtual bool is_node_wrapper() const { return false; } virtual const char* class_name() const override { return "Object"; } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index f2e1bdd354..a5601d9753 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -30,6 +30,7 @@ #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/ObjectConstructor.h> +#include <LibJS/Runtime/ProxyObject.h> #include <LibJS/Runtime/Shape.h> namespace JS { @@ -182,7 +183,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property_) auto& descriptor = vm.argument(2).as_object(); if (!object.define_property(property_key, descriptor)) { if (!vm.exception()) { - if (object.is_proxy_object()) { + if (AK::is<ProxyObject>(object)) { vm.throw_exception<TypeError>(global_object, ErrorType::ObjectDefinePropertyReturnedFalse); } else { vm.throw_exception<TypeError>(global_object, ErrorType::NonExtensibleDefine, property_key.to_display_string()); diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp index b580769980..cfc31c6b91 100644 --- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -27,8 +27,13 @@ #include <AK/Function.h> #include <AK/String.h> #include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/BooleanObject.h> +#include <LibJS/Runtime/Date.h> #include <LibJS/Runtime/GlobalObject.h> +#include <LibJS/Runtime/NumberObject.h> #include <LibJS/Runtime/ObjectPrototype.h> +#include <LibJS/Runtime/RegExpObject.h> +#include <LibJS/Runtime/StringObject.h> #include <LibJS/Runtime/Value.h> namespace JS { @@ -90,17 +95,17 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string) tag = "Array"; } else if (this_object->is_function()) { tag = "Function"; - } else if (this_object->is_error()) { + } else if (is<Error>(this_object)) { tag = "Error"; - } else if (this_object->is_boolean_object()) { + } else if (is<BooleanObject>(this_object)) { tag = "Boolean"; - } else if (this_object->is_number_object()) { + } else if (is<NumberObject>(this_object)) { tag = "Number"; - } else if (this_object->is_string_object()) { + } else if (is<StringObject>(this_object)) { tag = "String"; - } else if (this_object->is_date()) { + } else if (is<Date>(this_object)) { tag = "Date"; - } else if (this_object->is_regexp_object()) { + } else if (is<RegExpObject>(this_object)) { tag = "RegExp"; } else { tag = "Object"; diff --git a/Libraries/LibJS/Runtime/ProxyObject.h b/Libraries/LibJS/Runtime/ProxyObject.h index c896c3f4a0..70f30fac2c 100644 --- a/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Libraries/LibJS/Runtime/ProxyObject.h @@ -63,7 +63,6 @@ public: private: virtual void visit_edges(Visitor&) override; - virtual bool is_proxy_object() const override { return true; } virtual bool is_function() const override { return m_target.is_function(); } virtual bool is_array() const override { return m_target.is_array(); }; diff --git a/Libraries/LibJS/Runtime/ReflectObject.cpp b/Libraries/LibJS/Runtime/ReflectObject.cpp index 9fc7cd429c..0ee99be2df 100644 --- a/Libraries/LibJS/Runtime/ReflectObject.cpp +++ b/Libraries/LibJS/Runtime/ReflectObject.cpp @@ -132,7 +132,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::construct) if (vm.argument_count() > 2) { auto new_target_value = vm.argument(2); if (!new_target_value.is_function() - || (new_target_value.as_object().is_native_function() && !static_cast<NativeFunction&>(new_target_value.as_object()).has_constructor())) { + || (is<NativeFunction>(new_target_value.as_object()) && !static_cast<NativeFunction&>(new_target_value.as_object()).has_constructor())) { vm.throw_exception<TypeError>(global_object, ErrorType::ReflectBadNewTarget); return {}; } diff --git a/Libraries/LibJS/Runtime/RegExpObject.cpp b/Libraries/LibJS/Runtime/RegExpObject.cpp index da72f819ff..cfe0364497 100644 --- a/Libraries/LibJS/Runtime/RegExpObject.cpp +++ b/Libraries/LibJS/Runtime/RegExpObject.cpp @@ -135,7 +135,7 @@ static RegExpObject* regexp_object_from(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_regexp_object()) { + if (!is<RegExpObject>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "RegExp"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/RegExpObject.h b/Libraries/LibJS/Runtime/RegExpObject.h index ef1651298e..7be6b96069 100644 --- a/Libraries/LibJS/Runtime/RegExpObject.h +++ b/Libraries/LibJS/Runtime/RegExpObject.h @@ -54,8 +54,6 @@ public: const Regex<ECMA262>& regex() const { return m_regex; } private: - virtual bool is_regexp_object() const override { return true; } - JS_DECLARE_NATIVE_GETTER(last_index); JS_DECLARE_NATIVE_SETTER(set_last_index); diff --git a/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 65e3eebe95..b3c13ce41c 100644 --- a/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -78,7 +78,7 @@ static RegExpObject* regexp_object_from(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_regexp_object()) { + if (!is<RegExpObject>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "RegExp"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index bea77a1eae..581b73edba 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -106,7 +106,7 @@ LexicalEnvironment* ScriptFunction::create_environment() environment->set_home_object(home_object()); environment->set_current_function(*this); if (m_is_arrow_function) { - if (m_parent_scope->is_lexical_environment()) + if (is<LexicalEnvironment>(m_parent_scope)) environment->set_new_target(static_cast<LexicalEnvironment*>(m_parent_scope)->new_target()); } return environment; diff --git a/Libraries/LibJS/Runtime/ScriptFunction.h b/Libraries/LibJS/Runtime/ScriptFunction.h index cefb2e58e9..e3765509ab 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.h +++ b/Libraries/LibJS/Runtime/ScriptFunction.h @@ -56,7 +56,6 @@ protected: virtual bool is_strict_mode() const final { return m_is_strict; } private: - virtual bool is_script_function() const override { return true; } virtual LexicalEnvironment* create_environment() override; virtual void visit_edges(Visitor&) override; diff --git a/Libraries/LibJS/Runtime/StringIterator.h b/Libraries/LibJS/Runtime/StringIterator.h index 14fe7dac0d..c5754cf147 100644 --- a/Libraries/LibJS/Runtime/StringIterator.h +++ b/Libraries/LibJS/Runtime/StringIterator.h @@ -46,8 +46,6 @@ public: private: friend class StringIteratorPrototype; - virtual bool is_string_iterator_object() const override { return true; } - String m_string; Utf8CodepointIterator m_iterator; bool m_done { false }; diff --git a/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp b/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp index b7c599c485..2259ae7b26 100644 --- a/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringIteratorPrototype.cpp @@ -53,7 +53,7 @@ StringIteratorPrototype::~StringIteratorPrototype() JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next) { auto this_value = vm.this_value(global_object); - if (!this_value.is_object() || !this_value.as_object().is_string_iterator_object()) { + if (!this_value.is_object() || !is<StringIterator>(this_value.as_object())) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "String Iterator"); return {}; } diff --git a/Libraries/LibJS/Runtime/StringObject.h b/Libraries/LibJS/Runtime/StringObject.h index b0ffd30b4a..7fb32ebc63 100644 --- a/Libraries/LibJS/Runtime/StringObject.h +++ b/Libraries/LibJS/Runtime/StringObject.h @@ -47,7 +47,6 @@ public: private: virtual void visit_edges(Visitor&) override; - virtual bool is_string_object() const override { return true; } PrimitiveString& m_string; }; diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 2799bf79aa..596bedb6f1 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -44,7 +44,7 @@ static StringObject* typed_this(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_string_object()) { + if (!is<StringObject>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "String"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/SymbolObject.h b/Libraries/LibJS/Runtime/SymbolObject.h index 7b8418e2be..0ff212ffb5 100644 --- a/Libraries/LibJS/Runtime/SymbolObject.h +++ b/Libraries/LibJS/Runtime/SymbolObject.h @@ -53,7 +53,6 @@ public: private: virtual void visit_edges(Visitor&) override; - virtual bool is_symbol_object() const override { return true; } Symbol& m_symbol; }; diff --git a/Libraries/LibJS/Runtime/SymbolPrototype.cpp b/Libraries/LibJS/Runtime/SymbolPrototype.cpp index b5e7869281..c6af026829 100644 --- a/Libraries/LibJS/Runtime/SymbolPrototype.cpp +++ b/Libraries/LibJS/Runtime/SymbolPrototype.cpp @@ -63,7 +63,7 @@ static SymbolObject* typed_this(VM& vm, GlobalObject& global_object) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return nullptr; - if (!this_object->is_symbol_object()) { + if (!is<SymbolObject>(this_object)) { vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Symbol"); return nullptr; } diff --git a/Libraries/LibJS/Runtime/TypedArray.cpp b/Libraries/LibJS/Runtime/TypedArray.cpp index 1339e6925c..d5bc286e41 100644 --- a/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Libraries/LibJS/Runtime/TypedArray.cpp @@ -132,7 +132,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor) if (first_argument.as_object().is_typed_array()) { \ /* FIXME: Initialize from TypedArray */ \ TODO(); \ - } else if (first_argument.as_object().is_array_buffer()) { \ + } else if (is<ArrayBuffer>(first_argument.as_object())) { \ auto& array_buffer = static_cast<ArrayBuffer&>(first_argument.as_object()); \ initialize_typed_array_from_array_buffer(global_object(), *typed_array, array_buffer, vm.argument(1), vm.argument(2)); \ if (vm.exception()) \ diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp index ee5c96f38e..73842974c7 100644 --- a/Libraries/LibJS/Runtime/VM.cpp +++ b/Libraries/LibJS/Runtime/VM.cpp @@ -198,7 +198,7 @@ Reference VM::get_reference(const FlyString& name) { if (m_call_stack.size()) { for (auto* scope = current_scope(); scope; scope = scope->parent()) { - if (scope->is_global_object()) + if (is<GlobalObject>(scope)) break; auto possible_match = scope->get_from_scope(name); if (possible_match.has_value()) @@ -256,7 +256,7 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal // If we are constructing an instance of a derived class, // set the prototype on objects created by constructors that return an object (i.e. NativeFunction subclasses). if (function.constructor_kind() == Function::ConstructorKind::Base && new_target.constructor_kind() == Function::ConstructorKind::Derived && result.is_object()) { - ASSERT(current_scope()->is_lexical_environment()); + ASSERT(is<LexicalEnvironment>(current_scope())); static_cast<LexicalEnvironment*>(current_scope())->replace_this_binding(result); auto prototype = new_target.get(names.prototype); if (exception()) @@ -280,7 +280,7 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal void VM::throw_exception(Exception* exception) { - if (should_log_exceptions() && exception->value().is_object() && exception->value().as_object().is_error()) { + if (should_log_exceptions() && exception->value().is_object() && is<Error>(exception->value().as_object())) { auto& error = static_cast<Error&>(exception->value().as_object()); dbgln("Throwing JavaScript Error: {}, {}", error.name(), error.message()); @@ -324,7 +324,7 @@ const ScopeObject* VM::find_this_scope() const Value VM::get_new_target() const { - ASSERT(find_this_scope()->is_lexical_environment()); + ASSERT(is<LexicalEnvironment>(find_this_scope())); return static_cast<const LexicalEnvironment*>(find_this_scope())->new_target(); } diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 205f56d186..9731ce80f7 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -44,6 +44,7 @@ #include <LibJS/Runtime/NumberObject.h> #include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/PrimitiveString.h> +#include <LibJS/Runtime/RegExpObject.h> #include <LibJS/Runtime/StringObject.h> #include <LibJS/Runtime/Symbol.h> #include <LibJS/Runtime/SymbolObject.h> @@ -243,7 +244,7 @@ bool Value::is_regexp(GlobalObject& global_object) const if (!matcher.is_empty() && !matcher.is_undefined()) return matcher.to_boolean(); - return as_object().is_regexp_object(); + return is<RegExpObject>(as_object()); } String Value::to_string_without_side_effects() const @@ -926,8 +927,8 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) return Value(false); auto& rhs_function = rhs.as_function(); - if (rhs_function.is_bound_function()) { - auto& bound_target = static_cast<BoundFunction&>(rhs_function); + if (is<BoundFunction>(rhs_function)) { + auto& bound_target = static_cast<const BoundFunction&>(rhs_function); return instance_of(global_object, lhs, Value(&bound_target.target_function())); } diff --git a/Userland/js.cpp b/Userland/js.cpp index 1006bdd171..036c097d7a 100644 --- a/Userland/js.cpp +++ b/Userland/js.cpp @@ -230,9 +230,9 @@ static void print_object(JS::Object& object, HashTable<JS::Object*>& seen_object static void print_function(const JS::Object& object, HashTable<JS::Object*>&) { print_type(object.class_name()); - if (object.is_script_function()) + if (is<JS::ScriptFunction>(object)) out(" {}", static_cast<const JS::ScriptFunction&>(object).name()); - if (object.is_native_function()) + else if (is<JS::NativeFunction>(object)) out(" {}", static_cast<const JS::NativeFunction&>(object).name()); } @@ -357,23 +357,23 @@ static void print_value(JS::Value value, HashTable<JS::Object*>& seen_objects) auto& object = value.as_object(); if (object.is_function()) return print_function(object, seen_objects); - if (object.is_date()) + if (is<JS::Date>(object)) return print_date(object, seen_objects); - if (object.is_error()) + if (is<JS::Error>(object)) return print_error(object, seen_objects); - if (object.is_regexp_object()) + if (is<JS::RegExpObject>(object)) return print_regexp_object(object, seen_objects); - if (object.is_proxy_object()) + if (is<JS::ProxyObject>(object)) return print_proxy_object(object, seen_objects); - if (object.is_array_buffer()) + if (is<JS::ArrayBuffer>(object)) return print_array_buffer(object, seen_objects); if (object.is_typed_array()) return print_typed_array(object, seen_objects); - if (object.is_string_object()) + if (is<JS::StringObject>(object)) return print_primitive_wrapper_object("String", object, seen_objects); - if (object.is_number_object()) + if (is<JS::NumberObject>(object)) return print_primitive_wrapper_object("Number", object, seen_objects); - if (object.is_boolean_object()) + if (is<JS::BooleanObject>(object)) return print_primitive_wrapper_object("Boolean", object, seen_objects); return print_object(object, seen_objects); } |