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// Yarr.h is not self-contained. Make sure it sees uint8_t
18#include <cstdint>
19
20#include <yarr/Yarr.h>
21#include <yarr/YarrInterpreter.h>
22#include <yarr/YarrJIT.h>
23
24#include <private/qv4compileddata_p.h>
25#include <private/qv4managed_p.h>
26
27#include <QtCore/qstring.h>
28#include <QtCore/qvector.h>
29
30QT_BEGIN_NAMESPACE
31
32namespace QV4 {
33
34struct ExecutionEngine;
35struct RegExpCacheKey;
36
37namespace Heap {
38
39struct RegExp : Base {
40 void init(ExecutionEngine *engine, const QString& pattern, uint flags);
41 void destroy();
42
43 QString *pattern;
44 JSC::Yarr::BytecodePattern *byteCode;
45#if ENABLE(YARR_JIT)
46 JSC::Yarr::YarrCodeBlock *jitCode;
47#endif
48 bool hasValidJITCode() const {
49#if ENABLE(YARR_JIT)
50 return jitCode && !jitCode->failureReason().has_value() && jitCode->has16BitCode();
51#else
52 return false;
53#endif
54 }
55
56 bool ignoreCase() const { return flags & CompiledData::RegExp::RegExp_IgnoreCase; }
57 bool multiLine() const { return flags & CompiledData::RegExp::RegExp_Multiline; }
58 bool global() const { return flags & CompiledData::RegExp::RegExp_Global; }
59 bool unicode() const { return flags & CompiledData::RegExp::RegExp_Unicode; }
60 bool sticky() const { return flags & CompiledData::RegExp::RegExp_Sticky; }
61
62 RegExpCache *cache;
63 int subPatternCount;
64
65#if ENABLE(YARR_JIT)
66 bool isJittable() const { return !jitFailed; }
67 int interpreterCallCount;
68 bool jitFailed;
69#endif
70
71 quint8 flags;
72 bool valid;
73
74 int captureCount() const { return subPatternCount + 1; }
75};
76Q_STATIC_ASSERT(std::is_trivial_v<RegExp>);
77
78}
79
80struct RegExp : public Managed
81{
82 V4_MANAGED(RegExp, Managed)
83 Q_MANAGED_TYPE(RegExp)
84 V4_NEEDS_DESTROY
85 V4_INTERNALCLASS(RegExp)
86
87 QString pattern() const { return *d()->pattern; }
88 JSC::Yarr::BytecodePattern *byteCode() { return d()->byteCode; }
89#if ENABLE(YARR_JIT)
90 JSC::Yarr::YarrCodeBlock *jitCode() const { return d()->jitCode; }
91#endif
92 RegExpCache *cache() const { return d()->cache; }
93 int subPatternCount() const { return d()->subPatternCount; }
94 bool ignoreCase() const { return d()->ignoreCase(); }
95 bool multiLine() const { return d()->multiLine(); }
96 bool global() const { return d()->global(); }
97 bool unicode() const { return d()->unicode(); }
98 bool sticky() const { return d()->sticky(); }
99
100 static Heap::RegExp *create(
101 ExecutionEngine *engine, const QString &pattern,
102 CompiledData::RegExp::Flags flags = CompiledData::RegExp::RegExp_NoFlags);
103
104 bool isValid() const { return d()->valid; }
105
106 uint match(const QString& string, int start, uint *matchOffsets);
107
108 int captureCount() const { return subPatternCount() + 1; }
109
110 static QString getSubstitution(const QString &matched, const QString &str, int position, const Value *captures, int nCaptures, const QString &replacement);
111
112 friend class RegExpCache;
113};
114
115struct RegExpCacheKey
116{
117 RegExpCacheKey(const QString &pattern, uint flags)
118 : pattern(pattern), flags(flags)
119 { }
120 explicit inline RegExpCacheKey(const RegExp::Data *re);
121
122 bool operator==(const RegExpCacheKey &other) const
123 { return pattern == other.pattern && flags == other.flags;; }
124 bool operator!=(const RegExpCacheKey &other) const
125 { return !operator==(other); }
126
127 QString pattern;
128 quint8 flags;
129};
130
131inline RegExpCacheKey::RegExpCacheKey(const RegExp::Data *re)
132 : pattern(*re->pattern)
133 , flags(re->flags)
134{}
135
136inline size_t qHash(const RegExpCacheKey& key, size_t seed = 0) noexcept
137{ return qHashMulti(seed, args: key.pattern, args: key.flags); }
138
139class RegExpCache : public QHash<RegExpCacheKey, WeakValue>
140{
141public:
142 ~RegExpCache();
143};
144
145
146
147}
148
149QT_END_NAMESPACE
150
151#endif // QV4REGEXP_H
152

source code of qtdeclarative/src/qml/jsruntime/qv4regexp_p.h