Prechádzať zdrojové kódy

LibJS: Separate RegExpCreate into RegExpAlloc and RegExpInitialize

RegExp.prototype.compile will require invoking RegExpInitialize on an
already-existing RegExpObject. Break up RegExpCreate into RegExpAlloc
and RegExpInitialize to support this.
Timothy Flynn 3 rokov pred
rodič
commit
7c54b6bd45

+ 27 - 6
Userland/Libraries/LibJS/Runtime/RegExpObject.cpp

@@ -103,18 +103,28 @@ String parse_regex_pattern(StringView pattern, bool unicode)
     return builder.build();
     return builder.build();
 }
 }
 
 
+RegExpObject* RegExpObject::create(GlobalObject& global_object)
+{
+    return global_object.heap().allocate<RegExpObject>(global_object, *global_object.regexp_prototype());
+}
+
 RegExpObject* RegExpObject::create(GlobalObject& global_object, Regex<ECMA262> regex, String pattern, String flags)
 RegExpObject* RegExpObject::create(GlobalObject& global_object, Regex<ECMA262> regex, String pattern, String flags)
 {
 {
     return global_object.heap().allocate<RegExpObject>(global_object, move(regex), move(pattern), move(flags), *global_object.regexp_prototype());
     return global_object.heap().allocate<RegExpObject>(global_object, move(regex), move(pattern), move(flags), *global_object.regexp_prototype());
 }
 }
 
 
+RegExpObject::RegExpObject(Object& prototype)
+    : Object(prototype)
+{
+}
+
 RegExpObject::RegExpObject(Regex<ECMA262> regex, String pattern, String flags, Object& prototype)
 RegExpObject::RegExpObject(Regex<ECMA262> regex, String pattern, String flags, Object& prototype)
     : Object(prototype)
     : Object(prototype)
     , m_pattern(move(pattern))
     , m_pattern(move(pattern))
     , m_flags(move(flags))
     , m_flags(move(flags))
     , m_regex(move(regex))
     , m_regex(move(regex))
 {
 {
-    VERIFY(m_regex.parser_result.error == regex::Error::NoError);
+    VERIFY(m_regex->parser_result.error == regex::Error::NoError);
 }
 }
 
 
 RegExpObject::~RegExpObject()
 RegExpObject::~RegExpObject()
@@ -128,8 +138,8 @@ void RegExpObject::initialize(GlobalObject& global_object)
     define_direct_property(vm.names.lastIndex, Value(0), Attribute::Writable);
     define_direct_property(vm.names.lastIndex, Value(0), Attribute::Writable);
 }
 }
 
 
-// 22.2.3.2.4 RegExpCreate ( P, F ), https://tc39.es/ecma262/#sec-regexpcreate
-RegExpObject* regexp_create(GlobalObject& global_object, Value pattern, Value flags)
+// 22.2.3.2.2 RegExpInitialize ( obj, pattern, flags ), https://tc39.es/ecma262/#sec-regexpinitialize
+RegExpObject* RegExpObject::regexp_initialize(GlobalObject& global_object, Value pattern, Value flags)
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
@@ -169,11 +179,22 @@ RegExpObject* regexp_create(GlobalObject& global_object, Value pattern, Value fl
         return {};
         return {};
     }
     }
 
 
-    auto* object = RegExpObject::create(global_object, move(regex), move(original_pattern), move(f));
-    object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes);
+    m_pattern = move(original_pattern);
+    m_flags = move(f);
+    m_regex = move(regex);
+
+    set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes);
     if (vm.exception())
     if (vm.exception())
         return {};
         return {};
-    return object;
+
+    return this;
+}
+
+// 22.2.3.2.4 RegExpCreate ( P, F ), https://tc39.es/ecma262/#sec-regexpcreate
+RegExpObject* regexp_create(GlobalObject& global_object, Value pattern, Value flags)
+{
+    auto* regexp_object = RegExpObject::create(global_object);
+    return regexp_object->regexp_initialize(global_object, pattern, flags);
 }
 }
 
 
 }
 }

+ 9 - 3
Userland/Libraries/LibJS/Runtime/RegExpObject.h

@@ -6,6 +6,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <AK/Optional.h>
 #include <AK/Result.h>
 #include <AK/Result.h>
 #include <LibJS/AST.h>
 #include <LibJS/AST.h>
 #include <LibJS/Runtime/Object.h>
 #include <LibJS/Runtime/Object.h>
@@ -26,21 +27,26 @@ public:
     // FIXME: Enable 'BrowserExtended' only if in a browser context.
     // FIXME: Enable 'BrowserExtended' only if in a browser context.
     static constexpr regex::RegexOptions<ECMAScriptFlags> default_flags { (regex::ECMAScriptFlags)regex::AllFlags::Global | (regex::ECMAScriptFlags)regex::AllFlags::SkipTrimEmptyMatches | regex::ECMAScriptFlags::BrowserExtended };
     static constexpr regex::RegexOptions<ECMAScriptFlags> default_flags { (regex::ECMAScriptFlags)regex::AllFlags::Global | (regex::ECMAScriptFlags)regex::AllFlags::SkipTrimEmptyMatches | regex::ECMAScriptFlags::BrowserExtended };
 
 
+    static RegExpObject* create(GlobalObject&);
     static RegExpObject* create(GlobalObject&, Regex<ECMA262> regex, String pattern, String flags);
     static RegExpObject* create(GlobalObject&, Regex<ECMA262> regex, String pattern, String flags);
 
 
+    RegExpObject(Object& prototype);
     RegExpObject(Regex<ECMA262> regex, String pattern, String flags, Object& prototype);
     RegExpObject(Regex<ECMA262> regex, String pattern, String flags, Object& prototype);
+
+    RegExpObject* regexp_initialize(GlobalObject&, Value pattern, Value flags);
+
     virtual void initialize(GlobalObject&) override;
     virtual void initialize(GlobalObject&) override;
     virtual ~RegExpObject() override;
     virtual ~RegExpObject() override;
 
 
     const String& pattern() const { return m_pattern; }
     const String& pattern() const { return m_pattern; }
     const String& flags() const { return m_flags; }
     const String& flags() const { return m_flags; }
-    const Regex<ECMA262>& regex() { return m_regex; }
-    const Regex<ECMA262>& regex() const { return m_regex; }
+    const Regex<ECMA262>& regex() { return *m_regex; }
+    const Regex<ECMA262>& regex() const { return *m_regex; }
 
 
 private:
 private:
     String m_pattern;
     String m_pattern;
     String m_flags;
     String m_flags;
-    Regex<ECMA262> m_regex;
+    Optional<Regex<ECMA262>> m_regex;
 };
 };
 
 
 }
 }