소스 검색

LibJS: Pass prototype to Error constructors

Andreas Kling 5 년 전
부모
커밋
205ac0090d

+ 1 - 1
Libraries/LibJS/Interpreter.h

@@ -154,7 +154,7 @@ public:
     template<typename T, typename... 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*);

+ 20 - 9
Libraries/LibJS/Runtime/Error.cpp

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

+ 6 - 2
Libraries/LibJS/Runtime/Error.h

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

+ 2 - 2
Libraries/LibJS/Runtime/ErrorConstructor.cpp

@@ -51,7 +51,7 @@ Value ErrorConstructor::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<Error>("Error", message);
+    return Error::create(interpreter.global_object(), "Error", message);
 }
 
 #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName)                                        \
@@ -70,7 +70,7 @@ Value ErrorConstructor::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<ClassName>(message);                                                      \
+        return ClassName::create(interpreter.global_object(), message);                                              \
     }
 
 JS_ENUMERATE_ERROR_SUBCLASSES

+ 1 - 1
Libraries/LibJS/Runtime/FunctionConstructor.cpp

@@ -70,7 +70,7 @@ Value FunctionConstructor::construct(Interpreter& interpreter)
     auto function_expression = parser.parse_function_node<FunctionExpression>();
     if (parser.has_errors()) {
         // 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);
 }