1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 15:57:35 +00:00

LibJS: Pass prototype to Error constructors

This commit is contained in:
Andreas Kling 2020-04-17 19:31:48 +02:00
parent 0df4d2823a
commit 205ac0090d
5 changed files with 30 additions and 15 deletions

View file

@ -154,7 +154,7 @@ public:
template<typename T, typename... Args> template<typename T, typename... Args>
Value throw_exception(Args&&... args) Value throw_exception(Args&&... args)
{ {
return throw_exception(heap().allocate<T>(forward<Args>(args)...)); return throw_exception(T::create(global_object(), forward<Args>(args)...));
} }
Value throw_exception(Exception*); Value throw_exception(Exception*);

View file

@ -26,27 +26,38 @@
#include <LibJS/Interpreter.h> #include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/GlobalObject.h>
namespace JS { namespace JS {
Error::Error(const FlyString& name, const String& message) Error* Error::create(GlobalObject& global_object, const FlyString& name, const String& message)
{
auto& interpreter = global_object.interpreter();
return interpreter.heap().allocate<Error>(name, message, *interpreter.error_prototype());
}
Error::Error(const FlyString& name, const String& message, Object& prototype)
: m_name(name) : m_name(name)
, m_message(message) , m_message(message)
{ {
set_prototype(interpreter().error_prototype()); set_prototype(&prototype);
} }
Error::~Error() Error::~Error()
{ {
} }
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
ClassName::ClassName(const String& message) \ ClassName* ClassName::create(GlobalObject& global_object, const String& message) \
: Error(#ClassName, message) \ { \
{ \ auto& interpreter = global_object.interpreter(); \
set_prototype(interpreter().snake_name##_prototype()); \ return interpreter.heap().allocate<ClassName>(message, *interpreter.snake_name##_prototype()); \
} \ } \
ClassName::~ClassName() {} \ ClassName::ClassName(const String& message, Object& prototype) \
: Error(#ClassName, message, prototype) \
{ \
} \
ClassName::~ClassName() {} \
const char* ClassName::class_name() const { return #ClassName; } const char* ClassName::class_name() const { return #ClassName; }
JS_ENUMERATE_ERROR_SUBCLASSES JS_ENUMERATE_ERROR_SUBCLASSES

View file

@ -33,7 +33,9 @@ namespace JS {
class Error : public Object { class Error : public Object {
public: public:
Error(const FlyString& name, const String& message); static Error* create(GlobalObject&, const FlyString& name, const String& message);
Error(const FlyString& name, const String& message, Object& prototype);
virtual ~Error() override; virtual ~Error() override;
const FlyString& name() const { return m_name; } const FlyString& name() const { return m_name; }
@ -52,7 +54,9 @@ private:
#define DECLARE_ERROR_SUBCLASS(ClassName, snake_name, PrototypeName, ConstructorName) \ #define DECLARE_ERROR_SUBCLASS(ClassName, snake_name, PrototypeName, ConstructorName) \
class ClassName final : public Error { \ class ClassName final : public Error { \
public: \ public: \
ClassName(const String& message); \ static ClassName* create(GlobalObject&, const String& message); \
\
ClassName(const String& message, Object& prototype); \
virtual ~ClassName() override; \ virtual ~ClassName() override; \
\ \
private: \ private: \

View file

@ -51,7 +51,7 @@ Value ErrorConstructor::construct(Interpreter& interpreter)
String message = ""; String message = "";
if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined())
message = interpreter.call_frame().arguments[0].to_string(); message = interpreter.call_frame().arguments[0].to_string();
return interpreter.heap().allocate<Error>("Error", message); return Error::create(interpreter.global_object(), "Error", message);
} }
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
@ -70,7 +70,7 @@ Value ErrorConstructor::construct(Interpreter& interpreter)
String message = ""; \ String message = ""; \
if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) \ if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) \
message = interpreter.call_frame().arguments[0].to_string(); \ message = interpreter.call_frame().arguments[0].to_string(); \
return interpreter.heap().allocate<ClassName>(message); \ return ClassName::create(interpreter.global_object(), message); \
} }
JS_ENUMERATE_ERROR_SUBCLASSES JS_ENUMERATE_ERROR_SUBCLASSES

View file

@ -70,7 +70,7 @@ Value FunctionConstructor::construct(Interpreter& interpreter)
auto function_expression = parser.parse_function_node<FunctionExpression>(); auto function_expression = parser.parse_function_node<FunctionExpression>();
if (parser.has_errors()) { if (parser.has_errors()) {
// FIXME: The parser should expose parsing error strings rather than just fprintf()'ing them // FIXME: The parser should expose parsing error strings rather than just fprintf()'ing them
return interpreter.heap().allocate<Error>("SyntaxError", ""); return Error::create(interpreter.global_object(), "SyntaxError", "");
} }
return function_expression->execute(interpreter); return function_expression->execute(interpreter);
} }