1/*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Torch Mobile, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#ifndef RegExp_h
23#define RegExp_h
24
25#include "ExecutableAllocator.h"
26#include "MatchResult.h"
27#include "RegExpKey.h"
28#include "Structure.h"
29#include "yarr/Yarr.h"
30#include <wtf/Forward.h>
31#include <wtf/RefCounted.h>
32#include <wtf/text/WTFString.h>
33
34#if ENABLE(YARR_JIT)
35#include "yarr/YarrJIT.h"
36#endif
37
38namespace JSC {
39
40struct RegExpRepresentation;
41class VM;
42
43JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
44
45class RegExp final : public JSCell {
46public:
47 typedef JSCell Base;
48 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
49
50 JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
51 static const bool needsDestruction = true;
52 static void destroy(JSCell*);
53 static size_t estimatedSize(JSCell*);
54
55 bool global() const { return m_flags & FlagGlobal; }
56 bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
57 bool multiline() const { return m_flags & FlagMultiline; }
58
59 const String& pattern() const { return m_patternString; }
60
61 bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
62 const char* errorMessage() const { return m_constructionError; }
63
64 JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
65 JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset);
66 unsigned numSubpatterns() const { return m_numSubpatterns; }
67
68 bool hasCode()
69 {
70 return m_state != NotCompiled;
71 }
72
73 void deleteCode();
74
75#if ENABLE(REGEXP_TRACING)
76 void printTraceData();
77#endif
78
79 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
80 {
81 return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
82 }
83
84 DECLARE_INFO;
85
86 RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
87
88protected:
89 void finishCreation(VM&);
90
91private:
92 friend class RegExpCache;
93 RegExp(VM&, const String&, RegExpFlags);
94
95 static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
96
97 enum RegExpState {
98 ParseError,
99 JITCode,
100 ByteCode,
101 NotCompiled
102 };
103
104 RegExpState m_state;
105
106 void compile(VM*, Yarr::YarrCharSize);
107 void compileIfNecessary(VM&, Yarr::YarrCharSize);
108
109 void compileMatchOnly(VM*, Yarr::YarrCharSize);
110 void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
111
112#if ENABLE(YARR_JIT_DEBUG)
113 void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
114#endif
115
116 String m_patternString;
117 RegExpFlags m_flags;
118 const char* m_constructionError;
119 unsigned m_numSubpatterns;
120#if ENABLE(REGEXP_TRACING)
121 double m_rtMatchOnlyTotalSubjectStringLen;
122 double m_rtMatchTotalSubjectStringLen;
123 unsigned m_rtMatchOnlyCallCount;
124 unsigned m_rtMatchOnlyFoundCount;
125 unsigned m_rtMatchCallCount;
126 unsigned m_rtMatchFoundCount;
127#endif
128
129#if ENABLE(YARR_JIT)
130 Yarr::YarrCodeBlock m_regExpJITCode;
131#endif
132 std::unique_ptr<Yarr::BytecodePattern> m_regExpBytecode;
133};
134
135} // namespace JSC
136
137#endif // RegExp_h
138