X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/4e4e5a6f2694187498445a6ac6f1634ce8141119..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/runtime/RegExp.h diff --git a/runtime/RegExp.h b/runtime/RegExp.h index 04022bc..670505f 100644 --- a/runtime/RegExp.h +++ b/runtime/RegExp.h @@ -22,63 +22,114 @@ #ifndef RegExp_h #define RegExp_h -#include "UString.h" #include "ExecutableAllocator.h" +#include "MatchResult.h" +#include "RegExpKey.h" +#include "Structure.h" +#include "yarr/Yarr.h" #include #include -#include "yarr/RegexJIT.h" -#include "yarr/RegexInterpreter.h" +#include -struct JSRegExp; +#if ENABLE(YARR_JIT) +#include "yarr/YarrJIT.h" +#endif namespace JSC { - class JSGlobalData; +struct RegExpRepresentation; +class VM; + +JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&); + +class RegExp final : public JSCell { +public: + typedef JSCell Base; + static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + + JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags); + static const bool needsDestruction = true; + static void destroy(JSCell*); + + bool global() const { return m_flags & FlagGlobal; } + bool ignoreCase() const { return m_flags & FlagIgnoreCase; } + bool multiline() const { return m_flags & FlagMultiline; } + + const String& pattern() const { return m_patternString; } + + bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; } + const char* errorMessage() const { return m_constructionError; } + + JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector& ovector); + JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset); + unsigned numSubpatterns() const { return m_numSubpatterns; } + + bool hasCode() + { + return m_state != NotCompiled; + } - class RegExp : public RefCounted { - public: - static PassRefPtr create(JSGlobalData* globalData, const UString& pattern); - static PassRefPtr create(JSGlobalData* globalData, const UString& pattern, const UString& flags); -#if !ENABLE(YARR) - ~RegExp(); + void invalidateCode(); + +#if ENABLE(REGEXP_TRACING) + void printTraceData(); #endif - bool global() const { return m_flagBits & Global; } - bool ignoreCase() const { return m_flagBits & IgnoreCase; } - bool multiline() const { return m_flagBits & Multiline; } + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info()); + } + + DECLARE_INFO; - const UString& pattern() const { return m_pattern; } + RegExpKey key() { return RegExpKey(m_flags, m_patternString); } - bool isValid() const { return !m_constructionError; } - const char* errorMessage() const { return m_constructionError; } +protected: + void finishCreation(VM&); - int match(const UString&, int startOffset, Vector* ovector = 0); - unsigned numSubpatterns() const { return m_numSubpatterns; } +private: + friend class RegExpCache; + RegExp(VM&, const String&, RegExpFlags); - private: - RegExp(JSGlobalData* globalData, const UString& pattern); - RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags); + static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags); - void compile(JSGlobalData*); + enum RegExpState { + ParseError, + JITCode, + ByteCode, + NotCompiled + }; - enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 }; + RegExpState m_state; - UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this. - int m_flagBits; - const char* m_constructionError; - unsigned m_numSubpatterns; - UString m_lastMatchString; - int m_lastMatchStart; - Vector m_lastOVector; + void compile(VM*, Yarr::YarrCharSize); + void compileIfNecessary(VM&, Yarr::YarrCharSize); + + void compileMatchOnly(VM*, Yarr::YarrCharSize); + void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize); + +#if ENABLE(YARR_JIT_DEBUG) + void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult); +#endif + + String m_patternString; + RegExpFlags m_flags; + const char* m_constructionError; + unsigned m_numSubpatterns; +#if ENABLE(REGEXP_TRACING) + double m_rtMatchOnlyTotalSubjectStringLen; + double m_rtMatchTotalSubjectStringLen; + unsigned m_rtMatchOnlyCallCount; + unsigned m_rtMatchOnlyFoundCount; + unsigned m_rtMatchCallCount; + unsigned m_rtMatchFoundCount; +#endif #if ENABLE(YARR_JIT) - Yarr::RegexCodeBlock m_regExpJITCode; -#elif ENABLE(YARR) - OwnPtr m_regExpBytecode; -#else - JSRegExp* m_regExp; + Yarr::YarrCodeBlock m_regExpJITCode; #endif - }; + std::unique_ptr m_regExpBytecode; +}; } // namespace JSC