1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | #ifndef QV4REGEXP_H |
4 | #define QV4REGEXP_H |
5 | |
6 | // |
7 | // W A R N I N G |
8 | // ------------- |
9 | // |
10 | // This file is not part of the Qt API. It exists purely as an |
11 | // implementation detail. This header file may change from version to |
12 | // version without notice, or even be removed. |
13 | // |
14 | // We mean it. |
15 | // |
16 | |
17 | #include <QString> |
18 | #include <QVector> |
19 | |
20 | #include <wtf/RefPtr.h> |
21 | #include <wtf/FastAllocBase.h> |
22 | #include <wtf/BumpPointerAllocator.h> |
23 | |
24 | #include <limits.h> |
25 | |
26 | #include <yarr/Yarr.h> |
27 | #include <yarr/YarrInterpreter.h> |
28 | #include <yarr/YarrJIT.h> |
29 | |
30 | #include "qv4managed_p.h" |
31 | #include "qv4engine_p.h" |
32 | |
33 | QT_BEGIN_NAMESPACE |
34 | |
35 | namespace QV4 { |
36 | |
37 | struct ExecutionEngine; |
38 | struct RegExpCacheKey; |
39 | |
40 | namespace Heap { |
41 | |
42 | struct RegExp : Base { |
43 | void init(ExecutionEngine *engine, const QString& pattern, uint flags); |
44 | void destroy(); |
45 | |
46 | QString *pattern; |
47 | JSC::Yarr::BytecodePattern *byteCode; |
48 | #if ENABLE(YARR_JIT) |
49 | JSC::Yarr::YarrCodeBlock *jitCode; |
50 | #endif |
51 | bool hasValidJITCode() const { |
52 | #if ENABLE(YARR_JIT) |
53 | return jitCode && !jitCode->failureReason().has_value() && jitCode->has16BitCode(); |
54 | #else |
55 | return false; |
56 | #endif |
57 | } |
58 | |
59 | bool ignoreCase() const { return flags & CompiledData::RegExp::RegExp_IgnoreCase; } |
60 | bool multiLine() const { return flags & CompiledData::RegExp::RegExp_Multiline; } |
61 | bool global() const { return flags & CompiledData::RegExp::RegExp_Global; } |
62 | bool unicode() const { return flags & CompiledData::RegExp::RegExp_Unicode; } |
63 | bool sticky() const { return flags & CompiledData::RegExp::RegExp_Sticky; } |
64 | |
65 | RegExpCache *cache; |
66 | int subPatternCount; |
67 | uint flags; |
68 | bool valid; |
69 | |
70 | QString flagsAsString() const; |
71 | int captureCount() const { return subPatternCount + 1; } |
72 | }; |
73 | Q_STATIC_ASSERT(std::is_trivial_v<RegExp>); |
74 | |
75 | } |
76 | |
77 | struct RegExp : public Managed |
78 | { |
79 | V4_MANAGED(RegExp, Managed) |
80 | Q_MANAGED_TYPE(RegExp) |
81 | V4_NEEDS_DESTROY |
82 | V4_INTERNALCLASS(RegExp) |
83 | |
84 | QString pattern() const { return *d()->pattern; } |
85 | JSC::Yarr::BytecodePattern *byteCode() { return d()->byteCode; } |
86 | #if ENABLE(YARR_JIT) |
87 | JSC::Yarr::YarrCodeBlock *jitCode() const { return d()->jitCode; } |
88 | #endif |
89 | RegExpCache *cache() const { return d()->cache; } |
90 | int subPatternCount() const { return d()->subPatternCount; } |
91 | bool ignoreCase() const { return d()->ignoreCase(); } |
92 | bool multiLine() const { return d()->multiLine(); } |
93 | bool global() const { return d()->global(); } |
94 | bool unicode() const { return d()->unicode(); } |
95 | bool sticky() const { return d()->sticky(); } |
96 | |
97 | static Heap::RegExp *create(ExecutionEngine* engine, const QString& pattern, uint flags = CompiledData::RegExp::RegExp_NoFlags); |
98 | |
99 | bool isValid() const { return d()->valid; } |
100 | |
101 | uint match(const QString& string, int start, uint *matchOffsets); |
102 | |
103 | int captureCount() const { return subPatternCount() + 1; } |
104 | |
105 | static QString getSubstitution(const QString &matched, const QString &str, int position, const Value *captures, int nCaptures, const QString &replacement); |
106 | |
107 | friend class RegExpCache; |
108 | }; |
109 | |
110 | struct RegExpCacheKey |
111 | { |
112 | RegExpCacheKey(const QString &pattern, uint flags) |
113 | : pattern(pattern), flags(flags) |
114 | { } |
115 | explicit inline RegExpCacheKey(const RegExp::Data *re); |
116 | |
117 | bool operator==(const RegExpCacheKey &other) const |
118 | { return pattern == other.pattern && flags == other.flags;; } |
119 | bool operator!=(const RegExpCacheKey &other) const |
120 | { return !operator==(other); } |
121 | |
122 | QString pattern; |
123 | uint flags; |
124 | }; |
125 | |
126 | inline RegExpCacheKey::RegExpCacheKey(const RegExp::Data *re) |
127 | : pattern(*re->pattern) |
128 | , flags(re->flags) |
129 | {} |
130 | |
131 | inline size_t qHash(const RegExpCacheKey& key, size_t seed = 0) noexcept |
132 | { return qHash(key: key.pattern, seed); } |
133 | |
134 | class RegExpCache : public QHash<RegExpCacheKey, WeakValue> |
135 | { |
136 | public: |
137 | ~RegExpCache(); |
138 | }; |
139 | |
140 | |
141 | |
142 | } |
143 | |
144 | QT_END_NAMESPACE |
145 | |
146 | #endif // QV4REGEXP_H |
147 | |