summaryrefslogtreecommitdiff
path: root/Libraries/LibJS
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-04-10 12:48:31 +0200
committerAndreas Kling <kling@serenityos.org>2020-04-10 13:09:35 +0200
commite5da1cc5660f6a284b9b21c7bcb1a547fac1cabe (patch)
treeb50d524eccafa9a5df7d1db9ec97b92da0026ac5 /Libraries/LibJS
parent58ab76269c44945faf502bca333e7dac0562b972 (diff)
downloadserenity-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.cpp8
-rw-r--r--Libraries/LibJS/Heap/Heap.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Array.cpp2
-rw-r--r--Libraries/LibJS/Runtime/ArrayPrototype.cpp2
-rw-r--r--Libraries/LibJS/Runtime/BooleanPrototype.cpp4
-rw-r--r--Libraries/LibJS/Runtime/DatePrototype.cpp2
-rw-r--r--Libraries/LibJS/Runtime/ErrorPrototype.cpp11
-rw-r--r--Libraries/LibJS/Runtime/FunctionPrototype.cpp8
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp2
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.cpp10
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.cpp2
-rw-r--r--Libraries/LibJS/Runtime/StringPrototype.cpp6
-rw-r--r--Libraries/LibJS/Runtime/Value.cpp2
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;
}