diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-10 12:48:31 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-10 13:09:35 +0200 |
commit | e5da1cc5660f6a284b9b21c7bcb1a547fac1cabe (patch) | |
tree | b50d524eccafa9a5df7d1db9ec97b92da0026ac5 /Libraries/LibJS | |
parent | 58ab76269c44945faf502bca333e7dac0562b972 (diff) | |
download | serenity-e5da1cc5660f6a284b9b21c7bcb1a547fac1cabe.zip |
LibJS: Throw real TypeError, ReferenceError, etc objects
Instead of just throwing Error objects with a name string, we now throw
the real Error subclass types. :^)
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r-- | Libraries/LibJS/AST.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibJS/Heap/Heap.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/Array.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ArrayPrototype.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/BooleanPrototype.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/DatePrototype.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ErrorPrototype.cpp | 11 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/FunctionPrototype.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/Object.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ObjectConstructor.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/ScriptFunction.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/StringPrototype.cpp | 6 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/Value.cpp | 2 |
13 files changed, 32 insertions, 29 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 07b97edd07..86f4dc0bc0 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -97,11 +97,11 @@ Value CallExpression::execute(Interpreter& interpreter) const || !callee.as_object().is_function() || (callee.as_object().is_native_function() && !static_cast<NativeFunction&>(callee.as_object()).has_constructor())) - return interpreter.throw_exception<Error>("TypeError", String::format("%s is not a constructor", callee.to_string().characters())); + return interpreter.throw_exception<TypeError>(String::format("%s is not a constructor", callee.to_string().characters())); } if (!callee.is_object() || !callee.as_object().is_function()) - return interpreter.throw_exception<Error>("TypeError", String::format("%s is not a function", callee.to_string().characters())); + return interpreter.throw_exception<TypeError>(String::format("%s is not a function", callee.to_string().characters())); auto& function = static_cast<Function&>(callee.as_object()); @@ -651,7 +651,7 @@ Value Identifier::execute(Interpreter& interpreter) const { auto variable = interpreter.get_variable(string()); if (!variable.has_value()) - return interpreter.throw_exception<Error>("ReferenceError", String::format("'%s' not known", string().characters())); + return interpreter.throw_exception<ReferenceError>(String::format("'%s' not known", string().characters())); return variable.value(); } @@ -711,7 +711,7 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const object->put(property_name, rhs_result); } } else { - return interpreter.throw_exception<Error>("ReferenceError", "Invalid left-hand side in assignment"); + return interpreter.throw_exception<ReferenceError>("Invalid left-hand side in assignment"); } return rhs_result; diff --git a/Libraries/LibJS/Heap/Heap.cpp b/Libraries/LibJS/Heap/Heap.cpp index 3dd3902ca5..ca98e33b91 100644 --- a/Libraries/LibJS/Heap/Heap.cpp +++ b/Libraries/LibJS/Heap/Heap.cpp @@ -41,7 +41,7 @@ #endif #ifdef __serenity__ -#define HEAP_DEBUG +//#define HEAP_DEBUG #endif namespace JS { diff --git a/Libraries/LibJS/Runtime/Array.cpp b/Libraries/LibJS/Runtime/Array.cpp index e779630c2c..57589264bb 100644 --- a/Libraries/LibJS/Runtime/Array.cpp +++ b/Libraries/LibJS/Runtime/Array.cpp @@ -66,7 +66,7 @@ Value Array::length_getter(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_array()) - return interpreter.throw_exception<Error>("TypeError", "Not an array"); + return interpreter.throw_exception<TypeError>("Not an array"); return Value(static_cast<const Array*>(this_object)->length()); } diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 56b007158c..26fefa99e3 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -54,7 +54,7 @@ static Array* array_from(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_array()) { - interpreter.throw_exception<Error>("TypeError", "Not an Array"); + interpreter.throw_exception<TypeError>("Not an Array"); return nullptr; } return static_cast<Array*>(this_object); diff --git a/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Libraries/LibJS/Runtime/BooleanPrototype.cpp index a63ab9a110..1bae1f8741 100644 --- a/Libraries/LibJS/Runtime/BooleanPrototype.cpp +++ b/Libraries/LibJS/Runtime/BooleanPrototype.cpp @@ -47,7 +47,7 @@ Value BooleanPrototype::to_string(Interpreter& interpreter) return js_string(interpreter.heap(), this_object.as_bool() ? "true" : "false"); } if (!this_object.is_object() || !this_object.as_object().is_boolean()) { - interpreter.throw_exception<Error>("TypeError", "Not a Boolean"); + interpreter.throw_exception<TypeError>("Not a Boolean"); return {}; } @@ -62,7 +62,7 @@ Value BooleanPrototype::value_of(Interpreter& interpreter) return this_object; } if (!this_object.is_object() || !this_object.as_object().is_boolean()) { - interpreter.throw_exception<Error>("TypeError", "Not a Boolean"); + interpreter.throw_exception<TypeError>("Not a Boolean"); return {}; } diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp index 5e75843e11..9c827a0de3 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -41,7 +41,7 @@ static Date* this_date_from_interpreter(Interpreter& interpreter) if (!this_object) return nullptr; if (!this_object->is_date()) { - interpreter.throw_exception<Error>("TypeError", "object must be of type Date"); + interpreter.throw_exception<TypeError>("object must be of type Date"); return nullptr; } return static_cast<Date*>(this_object); diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp index 3e9c923282..f35d25c4a3 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -51,7 +51,7 @@ Value ErrorPrototype::name_getter(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_error()) - return interpreter.throw_exception<Error>("TypeError", "Not an Error object"); + return interpreter.throw_exception<TypeError>("Not an Error object"); return js_string(interpreter, static_cast<const Error*>(this_object)->name()); } @@ -61,14 +61,14 @@ Value ErrorPrototype::message_getter(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_error()) - return interpreter.throw_exception<Error>("TypeError", "Not an Error object"); + return interpreter.throw_exception<TypeError>("Not an Error object"); return js_string(interpreter, static_cast<const Error*>(this_object)->message()); } Value ErrorPrototype::to_string(Interpreter& interpreter) { if (!interpreter.this_value().is_object()) - return interpreter.throw_exception<Error>("TypeError", "Not an object"); + return interpreter.throw_exception<TypeError>("Not an object"); auto& this_object = interpreter.this_value().as_object(); String name = "Error"; @@ -89,7 +89,10 @@ Value ErrorPrototype::to_string(Interpreter& interpreter) } #define DEFINE_ERROR_SUBCLASS_PROTOTYPE(TitleCase, snake_case) \ - TitleCase::TitleCase() {} \ + TitleCase::TitleCase() \ + { \ + set_prototype(interpreter().error_prototype()); \ + } \ TitleCase::~TitleCase() {} \ const char* TitleCase::class_name() const { return #TitleCase; } diff --git a/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Libraries/LibJS/Runtime/FunctionPrototype.cpp index a0a976181d..bfe63ec9f6 100644 --- a/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -54,14 +54,14 @@ Value FunctionPrototype::apply(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_function()) - return interpreter.throw_exception<Error>("TypeError", "Not a Function object"); + return interpreter.throw_exception<TypeError>("Not a Function object"); auto function = static_cast<Function*>(this_object); auto this_arg = interpreter.argument(0); auto arg_array = interpreter.argument(1); if (arg_array.is_null() || arg_array.is_undefined()) return interpreter.call(function, this_arg); if (!arg_array.is_object()) - return interpreter.throw_exception<Error>("TypeError", "argument array must be an object"); + return interpreter.throw_exception<TypeError>("argument array must be an object"); size_t length = 0; auto length_property = arg_array.as_object().get("length"); if (length_property.has_value()) @@ -87,7 +87,7 @@ Value FunctionPrototype::call(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_function()) - return interpreter.throw_exception<Error>("TypeError", "Not a Function object"); + return interpreter.throw_exception<TypeError>("Not a Function object"); auto function = static_cast<Function*>(this_object); auto this_arg = interpreter.argument(0); Vector<Value> arguments; @@ -104,7 +104,7 @@ Value FunctionPrototype::to_string(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_function()) - return interpreter.throw_exception<Error>("TypeError", "Not a Function object"); + return interpreter.throw_exception<TypeError>("Not a Function object"); // FIXME: Functions should be able to know their name, if any if (this_object->is_native_function()) { auto function_source = String::format("function () {\n [%s]\n}", this_object->class_name()); diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index 15456d79c7..9382f4d878 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -110,7 +110,7 @@ void Object::put_own_property(Object& this_object, const FlyString& property_nam if (mode == PutOwnPropertyMode::DefineProperty && !(metadata.value().attributes & Attribute::Configurable) && attributes != metadata.value().attributes) { dbg() << "Disallow reconfig of non-configurable property"; - interpreter().throw_exception<Error>("TypeError", String::format("Cannot redefine property '%s'", property_name.characters())); + interpreter().throw_exception<TypeError>(String::format("Cannot redefine property '%s'", property_name.characters())); return; } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 0ed34c26b5..ad00184707 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -101,9 +101,9 @@ Value ObjectConstructor::set_prototype_of(Interpreter& interpreter) Value ObjectConstructor::get_own_property_descriptor(Interpreter& interpreter) { if (interpreter.argument_count() < 2) - return interpreter.throw_exception<Error>("TypeError", "Object.getOwnPropertyDescriptor() needs 2 arguments"); + return interpreter.throw_exception<TypeError>("Object.getOwnPropertyDescriptor() needs 2 arguments"); if (!interpreter.argument(0).is_object()) - return interpreter.throw_exception<Error>("TypeError", "Object argument is not an object"); + return interpreter.throw_exception<TypeError>("Object argument is not an object"); auto& object = interpreter.argument(0).as_object(); auto metadata = object.shape().lookup(interpreter.argument(1).to_string()); if (!metadata.has_value()) @@ -119,11 +119,11 @@ Value ObjectConstructor::get_own_property_descriptor(Interpreter& interpreter) Value ObjectConstructor::define_property(Interpreter& interpreter) { if (interpreter.argument_count() < 3) - return interpreter.throw_exception<Error>("TypeError", "Object.defineProperty() needs 3 arguments"); + return interpreter.throw_exception<TypeError>("Object.defineProperty() needs 3 arguments"); if (!interpreter.argument(0).is_object()) - return interpreter.throw_exception<Error>("TypeError", "Object argument is not an object"); + return interpreter.throw_exception<TypeError>("Object argument is not an object"); if (!interpreter.argument(2).is_object()) - return interpreter.throw_exception<Error>("TypeError", "Descriptor argument is not an object"); + return interpreter.throw_exception<TypeError>("Descriptor argument is not an object"); auto& object = interpreter.argument(0).as_object(); auto& descriptor = interpreter.argument(2).as_object(); diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 8a30d7898b..2f196bc2e0 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -70,7 +70,7 @@ Value ScriptFunction::length_getter(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_function()) - return interpreter.throw_exception<Error>("TypeError", "Not a function"); + return interpreter.throw_exception<TypeError>("Not a function"); return Value(static_cast<i32>(static_cast<const ScriptFunction*>(this_object)->parameters().size())); } diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index fc0fbf344e..4eb2469f16 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -120,7 +120,7 @@ Value StringPrototype::index_of(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_string_object()) - return interpreter.throw_exception<Error>("TypeError", "Not a String object"); + return interpreter.throw_exception<TypeError>("Not a String object"); Value needle_value = js_undefined(); if (interpreter.argument_count() >= 1) @@ -141,7 +141,7 @@ static StringObject* string_object_from(Interpreter& interpreter) if (!this_object) return nullptr; if (!this_object->is_string_object()) { - interpreter.throw_exception<Error>("TypeError", "Not a String object"); + interpreter.throw_exception<TypeError>("Not a String object"); return nullptr; } return static_cast<StringObject*>(this_object); @@ -169,7 +169,7 @@ Value StringPrototype::length_getter(Interpreter& interpreter) if (!this_object) return {}; if (!this_object->is_string_object()) - return interpreter.throw_exception<Error>("TypeError", "Not a String object"); + return interpreter.throw_exception<TypeError>("Not a String object"); return Value((i32) static_cast<const StringObject*>(this_object)->primitive_string()->string().length()); } diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 889e4e18f6..90af4d1a26 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -115,7 +115,7 @@ Object* Value::to_object(Heap& heap) const return heap.allocate<BooleanObject>(m_value.as_bool); if (is_null() || is_undefined()) { - heap.interpreter().throw_exception<Error>("TypeError", "ToObject on null or undefined."); + heap.interpreter().throw_exception<TypeError>("ToObject on null or undefined."); return nullptr; } |