14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/base/builtins_base.h"
204514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_string.h"
214514f5e3Sopenharmony_ci#include "ecmascript/ecma_runtime_call_info.h"
224514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h"
234514f5e3Sopenharmony_ci#include "ecmascript/regexp/regexp_parser.h"
244514f5e3Sopenharmony_ci#include "ecmascript/tagged_array-inl.h"
254514f5e3Sopenharmony_ci
264514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins {
274514f5e3Sopenharmony_ciclass BuiltinsRegExp : public base::BuiltinsBase {
284514f5e3Sopenharmony_cipublic:
294514f5e3Sopenharmony_ci    enum RegExpSymbol {
304514f5e3Sopenharmony_ci        SPLIT,
314514f5e3Sopenharmony_ci        SEARCH,
324514f5e3Sopenharmony_ci        MATCH,
334514f5e3Sopenharmony_ci        MATCHALL,
344514f5e3Sopenharmony_ci        REPLACE,
354514f5e3Sopenharmony_ci        UNKNOWN
364514f5e3Sopenharmony_ci    };
374514f5e3Sopenharmony_ci    // 21.2.3.1 RegExp ( pattern, flags )
384514f5e3Sopenharmony_ci    static JSTaggedValue RegExpConstructor(EcmaRuntimeCallInfo *argv);
394514f5e3Sopenharmony_ci
404514f5e3Sopenharmony_ci    // prototype
414514f5e3Sopenharmony_ci    // 21.2.5.2 RegExp.prototype.exec ( string )
424514f5e3Sopenharmony_ci    static JSTaggedValue Exec(EcmaRuntimeCallInfo *argv);
434514f5e3Sopenharmony_ci    // 21.2.5.13 RegExp.prototype.test( S )
444514f5e3Sopenharmony_ci    static JSTaggedValue Test(EcmaRuntimeCallInfo *argv);
454514f5e3Sopenharmony_ci    // 21.2.5.14 RegExp.prototype.toString ( )
464514f5e3Sopenharmony_ci    static JSTaggedValue ToString(EcmaRuntimeCallInfo *argv);
474514f5e3Sopenharmony_ci    // 21.2.5.3 get RegExp.prototype.flags
484514f5e3Sopenharmony_ci    static JSTaggedValue GetFlags(EcmaRuntimeCallInfo *argv);
494514f5e3Sopenharmony_ci    // 21.2.5.4 get RegExp.prototype.global
504514f5e3Sopenharmony_ci    static JSTaggedValue GetGlobal(EcmaRuntimeCallInfo *argv);
514514f5e3Sopenharmony_ci    // 21.2.5.5 get RegExp.prototype.ignoreCase
524514f5e3Sopenharmony_ci    static JSTaggedValue GetIgnoreCase(EcmaRuntimeCallInfo *argv);
534514f5e3Sopenharmony_ci    // 21.2.5.7 get RegExp.prototype.multiline
544514f5e3Sopenharmony_ci    static JSTaggedValue GetMultiline(EcmaRuntimeCallInfo *argv);
554514f5e3Sopenharmony_ci    static JSTaggedValue GetDotAll(EcmaRuntimeCallInfo *argv);
564514f5e3Sopenharmony_ci    // 21.2.5.10 get RegExp.prototype.source
574514f5e3Sopenharmony_ci    static JSTaggedValue GetSource(EcmaRuntimeCallInfo *argv);
584514f5e3Sopenharmony_ci    // 21.2.5.12 get RegExp.prototype.sticky
594514f5e3Sopenharmony_ci    static JSTaggedValue GetSticky(EcmaRuntimeCallInfo *argv);
604514f5e3Sopenharmony_ci    // 21.2.5.15 get RegExp.prototype.unicode
614514f5e3Sopenharmony_ci    static JSTaggedValue GetUnicode(EcmaRuntimeCallInfo *argv);
624514f5e3Sopenharmony_ci    // 21.2.4.2 get RegExp [ @@species ]
634514f5e3Sopenharmony_ci    static JSTaggedValue GetSpecies(EcmaRuntimeCallInfo *argv);
644514f5e3Sopenharmony_ci    // 21.2.5.6 RegExp.prototype [ @@match ] ( string )
654514f5e3Sopenharmony_ci    static JSTaggedValue Match(EcmaRuntimeCallInfo *argv);
664514f5e3Sopenharmony_ci    // 22.2.5.8 RegExp.prototype [ @@matchAll ] ( string )
674514f5e3Sopenharmony_ci    static JSTaggedValue MatchAll(EcmaRuntimeCallInfo *argv);
684514f5e3Sopenharmony_ci    // 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
694514f5e3Sopenharmony_ci    static JSTaggedValue Replace(EcmaRuntimeCallInfo *argv);
704514f5e3Sopenharmony_ci    // 21.2.5.9 RegExp.prototype [ @@search ] ( string )
714514f5e3Sopenharmony_ci    static JSTaggedValue Search(EcmaRuntimeCallInfo *argv);
724514f5e3Sopenharmony_ci    // 21.2.5.11 RegExp.prototype [ @@split ] ( string, limit )
734514f5e3Sopenharmony_ci    static JSTaggedValue Split(EcmaRuntimeCallInfo *argv);
744514f5e3Sopenharmony_ci    // 21.2.3.2.3 Runtime Semantics: RegExpCreate ( P, F )
754514f5e3Sopenharmony_ci    static JSTaggedValue RegExpCreate(JSThread *thread, const JSHandle<JSTaggedValue> &pattern,
764514f5e3Sopenharmony_ci                                      const JSHandle<JSTaggedValue> &flags);
774514f5e3Sopenharmony_ci    static JSTaggedValue FlagsBitsToString(JSThread *thread, uint8_t flags);
784514f5e3Sopenharmony_ci    // 21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
794514f5e3Sopenharmony_ci    static JSTaggedValue RegExpExec(JSThread *thread, const JSHandle<JSTaggedValue> &regexp,
804514f5e3Sopenharmony_ci                                    const JSHandle<JSTaggedValue> &inputString, bool useCache,
814514f5e3Sopenharmony_ci                                    bool isIntermediateResult = false);
824514f5e3Sopenharmony_ci    // 21.2.5.2.3 AdvanceStringIndex ( S, index, unicode )
834514f5e3Sopenharmony_ci    static int64_t AdvanceStringIndex(const JSHandle<JSTaggedValue> &inputStr, int64_t index,
844514f5e3Sopenharmony_ci                                      bool unicode);
854514f5e3Sopenharmony_ci    // 22.2.6.6 get RegExp.prototype.hasIndices
864514f5e3Sopenharmony_ci    static JSTaggedValue GetHasIndices(EcmaRuntimeCallInfo *argv);
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_ci    static JSTaggedValue ReplaceInternal(JSThread *thread,
894514f5e3Sopenharmony_ci                                         JSHandle<JSTaggedValue> thisObj,
904514f5e3Sopenharmony_ci                                         JSHandle<JSTaggedValue> string,
914514f5e3Sopenharmony_ci                                         JSHandle<JSTaggedValue> inputReplaceValue);
924514f5e3Sopenharmony_ci    static JSTaggedValue GetAllFlagsInternal(JSThread *thread, JSHandle<JSTaggedValue> &thisObj);
934514f5e3Sopenharmony_ci    static bool IsFastRegExp(JSThread *thread, JSHandle<JSTaggedValue> regexp,
944514f5e3Sopenharmony_ci                             RegExpSymbol symbolTag = RegExpSymbol::UNKNOWN);
954514f5e3Sopenharmony_ci    static bool GetFlag(JSThread *thread, const JSHandle<JSTaggedValue> regexp, uint32_t flag, bool isFastPath);
964514f5e3Sopenharmony_ci    static bool GetOriginalFlag(JSThread *thread, const JSHandle<JSTaggedValue> regexp, uint32_t flag);
974514f5e3Sopenharmony_ci    static void SetLastIndex(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
984514f5e3Sopenharmony_ci        JSTaggedValue lastIndex, bool isFastPath);
994514f5e3Sopenharmony_ci    static int64_t GetLastIndex(JSThread *thread, const JSHandle<JSTaggedValue> regexp, bool isFastPath);
1004514f5e3Sopenharmony_ci    static JSTaggedValue RegExpBuiltinExecWithoutResult(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1014514f5e3Sopenharmony_ci                                                        const JSHandle<JSTaggedValue> inputStr,
1024514f5e3Sopenharmony_ci                                                        bool isFastPath, uint32_t lastIndex, bool useCache);
1034514f5e3Sopenharmony_ci    // 21.2.5.2.2 Runtime Semantics: RegExpBuiltinExec ( R, S )
1044514f5e3Sopenharmony_ci    static JSTaggedValue RegExpBuiltinExec(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1054514f5e3Sopenharmony_ci                                           const JSHandle<JSTaggedValue> inputStr,
1064514f5e3Sopenharmony_ci                                           bool isFastPath, bool useCache, bool isIntermediateResult = false);
1074514f5e3Sopenharmony_ci    static JSTaggedValue RegExpSearch(JSThread *thread,
1084514f5e3Sopenharmony_ci                                      const JSHandle<JSTaggedValue> regexp,
1094514f5e3Sopenharmony_ci                                      const JSHandle<JSTaggedValue> string);
1104514f5e3Sopenharmony_ci    static JSTaggedValue RegExpSearchFast(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1114514f5e3Sopenharmony_ci                                          const JSHandle<JSTaggedValue> string);
1124514f5e3Sopenharmony_ci    static JSTaggedValue RegExpSplit(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1134514f5e3Sopenharmony_ci                                     JSHandle<JSTaggedValue> jsString, JSHandle<JSTaggedValue> limit,
1144514f5e3Sopenharmony_ci                                     bool isFastPath);
1154514f5e3Sopenharmony_ci    static JSTaggedValue GetExecResultIndex(JSThread *thread, const JSHandle<JSTaggedValue> &execResults,
1164514f5e3Sopenharmony_ci                                            bool isFastPath);
1174514f5e3Sopenharmony_ci    static JSTaggedValue GetExecResultGroups(JSThread *thread, const JSHandle<JSTaggedValue> &execResults,
1184514f5e3Sopenharmony_ci                                             bool isFastPath);
1194514f5e3Sopenharmony_ci    static JSTaggedValue RegExpMatch(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1204514f5e3Sopenharmony_ci                                     const JSHandle<JSTaggedValue> string, bool isFastPath);
1214514f5e3Sopenharmony_ci    static JSTaggedValue RegExpMatchAll(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1224514f5e3Sopenharmony_ci                                        const JSHandle<EcmaString> string, bool isFastPath);
1234514f5e3Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
1244514f5e3Sopenharmony_ci#define SET_GET_CAPTURE(index)                                                                                \
1254514f5e3Sopenharmony_ci    static JSTaggedValue GetCapture##index(JSThread *thread, const JSHandle<JSObject> &obj);                  \
1264514f5e3Sopenharmony_ci    static bool SetCapture##index(JSThread *thread, const JSHandle<JSObject> &obj,                            \
1274514f5e3Sopenharmony_ci                                 const JSHandle<JSTaggedValue> &value, bool mayThrow);
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ci    SET_GET_CAPTURE(1)
1304514f5e3Sopenharmony_ci    SET_GET_CAPTURE(2)
1314514f5e3Sopenharmony_ci    SET_GET_CAPTURE(3)
1324514f5e3Sopenharmony_ci    SET_GET_CAPTURE(4)
1334514f5e3Sopenharmony_ci    SET_GET_CAPTURE(5)
1344514f5e3Sopenharmony_ci    SET_GET_CAPTURE(6)
1354514f5e3Sopenharmony_ci    SET_GET_CAPTURE(7)
1364514f5e3Sopenharmony_ci    SET_GET_CAPTURE(8)
1374514f5e3Sopenharmony_ci    SET_GET_CAPTURE(9)
1384514f5e3Sopenharmony_ci#undef SET_GET_CAPTURE
1394514f5e3Sopenharmony_ci
1404514f5e3Sopenharmony_ci#define REGEXP_SYMBOL_FUNCTION_LIST(V)    \
1414514f5e3Sopenharmony_ci    V(SPLIT, Split)                       \
1424514f5e3Sopenharmony_ci    V(SEARCH, Search)                     \
1434514f5e3Sopenharmony_ci    V(MATCH, Match)                       \
1444514f5e3Sopenharmony_ci    V(MATCHALL, MatchAll)                 \
1454514f5e3Sopenharmony_ci    V(REPLACE, Replace)
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ciprivate:
1484514f5e3Sopenharmony_ci    static constexpr uint32_t MIN_REPLACE_STRING_LENGTH = 1000;
1494514f5e3Sopenharmony_ci    static constexpr uint32_t MAX_SPLIT_LIMIT = 0xFFFFFFFFu;
1504514f5e3Sopenharmony_ci    static constexpr uint32_t REGEXP_GLOBAL_ARRAY_SIZE = 9;
1514514f5e3Sopenharmony_ci    static constexpr uint32_t LAST_INDEX_OFFSET = 0;
1524514f5e3Sopenharmony_ci    static constexpr uint32_t EXEC_RESULT_INDEX_OFFSET = 1;
1534514f5e3Sopenharmony_ci    static constexpr uint32_t EXEC_RESULT_INPUT_OFFSET = 2;
1544514f5e3Sopenharmony_ci    static constexpr uint32_t EXEC_RESULT_GROUPS_OFFSET = 3;
1554514f5e3Sopenharmony_ci
1564514f5e3Sopenharmony_ci    static constexpr uint32_t REPLACE_RESULT_VAL = 2;
1574514f5e3Sopenharmony_ci    static constexpr unsigned REPLACE_LENGTH_BITS = 30;
1584514f5e3Sopenharmony_ci    static constexpr unsigned REPLACE_POSITION_BITS = 30;
1594514f5e3Sopenharmony_ci    using ReplaceLengthField = BitField<uint32_t, 0, REPLACE_LENGTH_BITS>; // 30
1604514f5e3Sopenharmony_ci    using ReplacePositionField = ReplaceLengthField::NextField<uint32_t, REPLACE_POSITION_BITS>; // 60
1614514f5e3Sopenharmony_ci
1624514f5e3Sopenharmony_ci    static bool Matcher(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1634514f5e3Sopenharmony_ci                        const uint8_t *buffer, size_t length, int32_t lastindex, bool isUtf16);
1644514f5e3Sopenharmony_ci
1654514f5e3Sopenharmony_ci    static JSTaggedValue GetFlagsInternal(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1664514f5e3Sopenharmony_ci                                          const JSHandle<JSTaggedValue> &constructor, const uint8_t mask);
1674514f5e3Sopenharmony_ci    // 21.2.3.2.1 Runtime Semantics: RegExpAlloc ( newTarget )
1684514f5e3Sopenharmony_ci    static JSTaggedValue RegExpAlloc(JSThread *thread, const JSHandle<JSTaggedValue> &newTarget);
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ci    static uint32_t UpdateExpressionFlags(JSThread *thread, const CString &checkStr);
1714514f5e3Sopenharmony_ci
1724514f5e3Sopenharmony_ci    // 21.2.3.2.2 Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
1734514f5e3Sopenharmony_ci    static JSTaggedValue RegExpInitialize(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1744514f5e3Sopenharmony_ci                                          const JSHandle<JSTaggedValue> &pattern, const JSHandle<JSTaggedValue> &flags);
1754514f5e3Sopenharmony_ci    // 21.2.3.2.4 Runtime Semantics: EscapeRegExpPattern ( P, F )
1764514f5e3Sopenharmony_ci    static EcmaString *EscapeRegExpPattern(JSThread *thread, const JSHandle<JSTaggedValue> &src,
1774514f5e3Sopenharmony_ci                                           const JSHandle<JSTaggedValue> &flags);
1784514f5e3Sopenharmony_ci    static JSTaggedValue RegExpReplaceFast(JSThread *thread, JSHandle<JSTaggedValue> regexp,
1794514f5e3Sopenharmony_ci                                           JSHandle<EcmaString> inputString, uint32_t inputLength);
1804514f5e3Sopenharmony_ci    static JSTaggedValue GetLastIndex(JSThread *thread, JSHandle<JSTaggedValue> regexp,
1814514f5e3Sopenharmony_ci                                      uint32_t &lastIndex);
1824514f5e3Sopenharmony_ci    static bool ShouldUseCache(JSThread *thread, JSHandle<EcmaString> inputString);
1834514f5e3Sopenharmony_ci    static JSTaggedValue MatchAndReplace(JSThread *thread, JSHandle<JSTaggedValue> regexp,
1844514f5e3Sopenharmony_ci                                         JSHandle<EcmaString> inputString, uint32_t &flags,
1854514f5e3Sopenharmony_ci                                         uint32_t lastIndex, uint32_t inputLength,
1864514f5e3Sopenharmony_ci                                         std::string &resultString);
1874514f5e3Sopenharmony_ci    static JSTaggedValue RegExpTestFast(JSThread *thread, JSHandle<JSTaggedValue> regexp,
1884514f5e3Sopenharmony_ci                                        const JSHandle<JSTaggedValue> inputString, bool useCache);
1894514f5e3Sopenharmony_ci    static JSTaggedValue RegExpExecForTestFast(JSThread *thread, JSHandle<JSTaggedValue> regexp,
1904514f5e3Sopenharmony_ci                                               const JSHandle<JSTaggedValue> inputStr, bool useCache);
1914514f5e3Sopenharmony_ci    // 22.2.7.8 MakeMatchIndicesIndexPairArray ( S, indices, groupNames, hasGroups )
1924514f5e3Sopenharmony_ci    static JSHandle<JSTaggedValue> MakeMatchIndicesIndexPairArray(JSThread* thread,
1934514f5e3Sopenharmony_ci        const std::vector<std::pair<JSTaggedValue, JSTaggedValue>>& indices,
1944514f5e3Sopenharmony_ci        const std::vector<JSHandle<JSTaggedValue>>& groupNames, bool hasGroups);
1954514f5e3Sopenharmony_ci    static bool RegExpExecInternal(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1964514f5e3Sopenharmony_ci                                   JSHandle<EcmaString> inputString, int32_t lastIndex);
1974514f5e3Sopenharmony_ci    static JSTaggedValue RegExpSplitFast(JSThread *thread, const JSHandle<JSTaggedValue> regexp,
1984514f5e3Sopenharmony_ci                                         JSHandle<JSTaggedValue> string, uint32_t limit, bool useCache);
1994514f5e3Sopenharmony_ci    static JSHandle<EcmaString> CreateStringFromResultArray(JSThread *thread, const JSHandle<TaggedArray> resultArray,
2004514f5e3Sopenharmony_ci        const std::vector<uint64_t> &resultLengthArray, JSHandle<EcmaString> srcString,
2014514f5e3Sopenharmony_ci        uint32_t resultStrLength, bool isUtf8);
2024514f5e3Sopenharmony_ci};
2034514f5e3Sopenharmony_ci
2044514f5e3Sopenharmony_ciclass RegExpExecResultCache : public TaggedArray {
2054514f5e3Sopenharmony_cipublic:
2064514f5e3Sopenharmony_ci    enum CacheType {
2074514f5e3Sopenharmony_ci        REPLACE_TYPE,
2084514f5e3Sopenharmony_ci        SPLIT_TYPE,
2094514f5e3Sopenharmony_ci        MATCH_TYPE,
2104514f5e3Sopenharmony_ci        EXEC_TYPE,
2114514f5e3Sopenharmony_ci        INTERMEDIATE_REPLACE_TYPE,
2124514f5e3Sopenharmony_ci        TEST_TYPE,
2134514f5e3Sopenharmony_ci        SEARCH_TYPE,
2144514f5e3Sopenharmony_ci    };
2154514f5e3Sopenharmony_ci    static RegExpExecResultCache *Cast(TaggedObject *object)
2164514f5e3Sopenharmony_ci    {
2174514f5e3Sopenharmony_ci        return reinterpret_cast<RegExpExecResultCache *>(object);
2184514f5e3Sopenharmony_ci    }
2194514f5e3Sopenharmony_ci    static JSTaggedValue CreateCacheTable(JSThread *thread);
2204514f5e3Sopenharmony_ci    // extend as an additional parameter to judge cached
2214514f5e3Sopenharmony_ci    JSTaggedValue FindCachedResult(JSThread *thread, const JSHandle<JSTaggedValue> input,
2224514f5e3Sopenharmony_ci                                   CacheType type, const JSHandle<JSTaggedValue> regexp,
2234514f5e3Sopenharmony_ci                                   JSTaggedValue lastIndexInput, JSHandle<JSTaggedValue> extend,
2244514f5e3Sopenharmony_ci                                   bool isIntermediateResult = false);
2254514f5e3Sopenharmony_ci    // extend as an additional parameter to judge cached
2264514f5e3Sopenharmony_ci    static void AddResultInCache(JSThread *thread, JSHandle<RegExpExecResultCache> cache,
2274514f5e3Sopenharmony_ci                                 const JSHandle<JSTaggedValue> regexp,
2284514f5e3Sopenharmony_ci                                 const JSHandle<JSTaggedValue> input, const JSHandle<JSTaggedValue> resultArray,
2294514f5e3Sopenharmony_ci                                 CacheType type, uint32_t lastIndexInput, uint32_t lastIndex,
2304514f5e3Sopenharmony_ci                                 const JSHandle<JSTaggedValue> extend,
2314514f5e3Sopenharmony_ci                                 bool isIntermediateResult = false);
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ci    static void GrowRegexpCache(JSThread *thread, JSHandle<RegExpExecResultCache> cache);
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_ci    void ClearEntry(JSThread *thread, int entry);
2364514f5e3Sopenharmony_ci    void SetEntry(JSThread *thread, int entry, JSTaggedValue &patten, JSTaggedValue &flags, JSTaggedValue &input,
2374514f5e3Sopenharmony_ci                  JSTaggedValue &lastIndexInputValue, JSTaggedValue &lastIndexValue, JSTaggedValue &extendValue,
2384514f5e3Sopenharmony_ci                  JSTaggedValue &resTableArray);
2394514f5e3Sopenharmony_ci    void UpdateResultArray(JSThread *thread, int entry, JSTaggedValue resultArray, CacheType type);
2404514f5e3Sopenharmony_ci    bool Match(int entry, JSTaggedValue &pattenStr, JSTaggedValue &flagsStr, JSTaggedValue &inputStr,
2414514f5e3Sopenharmony_ci               JSTaggedValue &lastIndexInputValue, JSTaggedValue &extend, CacheType type);
2424514f5e3Sopenharmony_ci    inline void SetHitCount(JSThread *thread, int hitCount)
2434514f5e3Sopenharmony_ci    {
2444514f5e3Sopenharmony_ci        Set(thread, CACHE_HIT_COUNT_INDEX, JSTaggedValue(hitCount));
2454514f5e3Sopenharmony_ci    }
2464514f5e3Sopenharmony_ci
2474514f5e3Sopenharmony_ci    inline int GetHitCount()
2484514f5e3Sopenharmony_ci    {
2494514f5e3Sopenharmony_ci        return Get(CACHE_HIT_COUNT_INDEX).GetInt();
2504514f5e3Sopenharmony_ci    }
2514514f5e3Sopenharmony_ci
2524514f5e3Sopenharmony_ci    inline void SetCacheCount(JSThread *thread, int hitCount)
2534514f5e3Sopenharmony_ci    {
2544514f5e3Sopenharmony_ci        Set(thread, CACHE_COUNT_INDEX, JSTaggedValue(hitCount));
2554514f5e3Sopenharmony_ci    }
2564514f5e3Sopenharmony_ci
2574514f5e3Sopenharmony_ci    inline int GetCacheCount()
2584514f5e3Sopenharmony_ci    {
2594514f5e3Sopenharmony_ci        return Get(CACHE_COUNT_INDEX).GetInt();
2604514f5e3Sopenharmony_ci    }
2614514f5e3Sopenharmony_ci
2624514f5e3Sopenharmony_ci    void Print()
2634514f5e3Sopenharmony_ci    {
2644514f5e3Sopenharmony_ci        std::cout << "cache count: " << GetCacheCount() << std::endl;
2654514f5e3Sopenharmony_ci        std::cout << "cache hit count: " << GetHitCount() << std::endl;
2664514f5e3Sopenharmony_ci    }
2674514f5e3Sopenharmony_ci
2684514f5e3Sopenharmony_ci    inline void SetLargeStrCount(JSThread *thread, uint32_t newCount)
2694514f5e3Sopenharmony_ci    {
2704514f5e3Sopenharmony_ci        Set(thread, LARGE_STRING_COUNT_INDEX, JSTaggedValue(newCount));
2714514f5e3Sopenharmony_ci    }
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ci    inline void SetConflictCount(JSThread *thread, uint32_t newCount)
2744514f5e3Sopenharmony_ci    {
2754514f5e3Sopenharmony_ci        Set(thread, CONFLICT_COUNT_INDEX, JSTaggedValue(newCount));
2764514f5e3Sopenharmony_ci    }
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_ci    inline void SetStrLenThreshold(JSThread *thread, uint32_t newThreshold)
2794514f5e3Sopenharmony_ci    {
2804514f5e3Sopenharmony_ci        Set(thread, STRING_LENGTH_THRESHOLD_INDEX, JSTaggedValue(newThreshold));
2814514f5e3Sopenharmony_ci    }
2824514f5e3Sopenharmony_ci
2834514f5e3Sopenharmony_ci    inline uint32_t GetLargeStrCount()
2844514f5e3Sopenharmony_ci    {
2854514f5e3Sopenharmony_ci        return Get(LARGE_STRING_COUNT_INDEX).GetInt();
2864514f5e3Sopenharmony_ci    }
2874514f5e3Sopenharmony_ci
2884514f5e3Sopenharmony_ci    inline uint32_t GetConflictCount()
2894514f5e3Sopenharmony_ci    {
2904514f5e3Sopenharmony_ci        return Get(CONFLICT_COUNT_INDEX).GetInt();
2914514f5e3Sopenharmony_ci    }
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci    inline uint32_t GetStrLenThreshold()
2944514f5e3Sopenharmony_ci    {
2954514f5e3Sopenharmony_ci        return Get(STRING_LENGTH_THRESHOLD_INDEX).GetInt();
2964514f5e3Sopenharmony_ci    }
2974514f5e3Sopenharmony_ci
2984514f5e3Sopenharmony_ci    inline void SetCacheLength(JSThread *thread, int length)
2994514f5e3Sopenharmony_ci    {
3004514f5e3Sopenharmony_ci        Set(thread, CACHE_LENGTH_INDEX, JSTaggedValue(length));
3014514f5e3Sopenharmony_ci    }
3024514f5e3Sopenharmony_ci
3034514f5e3Sopenharmony_ci    inline int GetCacheLength()
3044514f5e3Sopenharmony_ci    {
3054514f5e3Sopenharmony_ci        return Get(CACHE_LENGTH_INDEX).GetInt();
3064514f5e3Sopenharmony_ci    }
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ciprivate:
3094514f5e3Sopenharmony_ci    static constexpr int DEFAULT_LARGE_STRING_COUNT = 10;
3104514f5e3Sopenharmony_ci    static constexpr int DEFAULT_CONFLICT_COUNT = 100;
3114514f5e3Sopenharmony_ci    static constexpr int INITIAL_CACHE_NUMBER = 0x10;
3124514f5e3Sopenharmony_ci    static constexpr int DEFAULT_CACHE_NUMBER = 0x1000;
3134514f5e3Sopenharmony_ci    static constexpr int CACHE_COUNT_INDEX = 0;
3144514f5e3Sopenharmony_ci    static constexpr int CACHE_HIT_COUNT_INDEX = 1;
3154514f5e3Sopenharmony_ci    static constexpr int LARGE_STRING_COUNT_INDEX = 2;
3164514f5e3Sopenharmony_ci    static constexpr int CONFLICT_COUNT_INDEX = 3;
3174514f5e3Sopenharmony_ci    static constexpr int STRING_LENGTH_THRESHOLD_INDEX = 4;
3184514f5e3Sopenharmony_ci    static constexpr int CACHE_LENGTH_INDEX = 5;
3194514f5e3Sopenharmony_ci    static constexpr int CACHE_TABLE_HEADER_SIZE = 6;
3204514f5e3Sopenharmony_ci    static constexpr int PATTERN_INDEX = 0;
3214514f5e3Sopenharmony_ci    static constexpr int FLAG_INDEX = 1;
3224514f5e3Sopenharmony_ci    static constexpr int INPUT_STRING_INDEX = 2;
3234514f5e3Sopenharmony_ci    static constexpr int LAST_INDEX_INPUT_INDEX = 3;
3244514f5e3Sopenharmony_ci    static constexpr int LAST_INDEX_INDEX = 4;
3254514f5e3Sopenharmony_ci    static constexpr int RESULT_REPLACE_INDEX = 5;
3264514f5e3Sopenharmony_ci    static constexpr int RESULT_SPLIT_INDEX = 6;
3274514f5e3Sopenharmony_ci    static constexpr int RESULT_MATCH_INDEX = 7;
3284514f5e3Sopenharmony_ci    static constexpr int RESULT_EXEC_INDEX = 8;
3294514f5e3Sopenharmony_ci    static constexpr int RESULT_INTERMEDIATE_REPLACE_INDEX = 9;
3304514f5e3Sopenharmony_ci    static constexpr int RESULT_TEST_INDEX = 10;
3314514f5e3Sopenharmony_ci    static constexpr int RESULT_SEARCH_INDEX = 11;
3324514f5e3Sopenharmony_ci    // Extend index used for saving an additional parameter to judge cached
3334514f5e3Sopenharmony_ci    static constexpr int EXTEND_INDEX = 12;
3344514f5e3Sopenharmony_ci    static constexpr int CAPTURE_SIZE = 13;
3354514f5e3Sopenharmony_ci    static constexpr int ENTRY_SIZE = 14;
3364514f5e3Sopenharmony_ci};
3374514f5e3Sopenharmony_ci
3384514f5e3Sopenharmony_ciclass RegExpGlobalResult : public TaggedArray {
3394514f5e3Sopenharmony_cipublic:
3404514f5e3Sopenharmony_ci    static RegExpGlobalResult *Cast(TaggedObject *object)
3414514f5e3Sopenharmony_ci    {
3424514f5e3Sopenharmony_ci        return reinterpret_cast<RegExpGlobalResult *>(object);
3434514f5e3Sopenharmony_ci    }
3444514f5e3Sopenharmony_ci    static JSTaggedValue CreateGlobalResultTable(JSThread *thread);
3454514f5e3Sopenharmony_ci
3464514f5e3Sopenharmony_ci    void SetCapture(JSThread *thread, int index, JSTaggedValue value)
3474514f5e3Sopenharmony_ci    {
3484514f5e3Sopenharmony_ci        ASSERT(CAPTURE_START_INDEX + index - 1 < GLOBAL_TABLE_SIZE);
3494514f5e3Sopenharmony_ci        Set(thread, CAPTURE_START_INDEX + index - 1, value);
3504514f5e3Sopenharmony_ci    }
3514514f5e3Sopenharmony_ci
3524514f5e3Sopenharmony_ci    void ResetDollar(JSThread *thread)
3534514f5e3Sopenharmony_ci    {
3544514f5e3Sopenharmony_ci        for (uint32_t i = 0; i < DOLLAR_NUMBER; i++) {
3554514f5e3Sopenharmony_ci            Set(thread, CAPTURE_START_INDEX + i, JSTaggedValue::Hole());
3564514f5e3Sopenharmony_ci        }
3574514f5e3Sopenharmony_ci    }
3584514f5e3Sopenharmony_ci
3594514f5e3Sopenharmony_ci    template <int N>
3604514f5e3Sopenharmony_ci    static JSTaggedValue GetCapture(JSThread *thread);
3614514f5e3Sopenharmony_ci
3624514f5e3Sopenharmony_ci    void SetTotalCaptureCounts(JSThread *thread, JSTaggedValue counts)
3634514f5e3Sopenharmony_ci    {
3644514f5e3Sopenharmony_ci        Set(thread, TOTAL_CAPTURE_COUNTS_INDEX, counts);
3654514f5e3Sopenharmony_ci    }
3664514f5e3Sopenharmony_ci
3674514f5e3Sopenharmony_ci    JSTaggedValue GetTotalCaptureCounts()
3684514f5e3Sopenharmony_ci    {
3694514f5e3Sopenharmony_ci        return Get(TOTAL_CAPTURE_COUNTS_INDEX);
3704514f5e3Sopenharmony_ci    }
3714514f5e3Sopenharmony_ci
3724514f5e3Sopenharmony_ci    void SetEndIndex(JSThread *thread, JSTaggedValue endIndex)
3734514f5e3Sopenharmony_ci    {
3744514f5e3Sopenharmony_ci        Set(thread, END_INDEX, endIndex);
3754514f5e3Sopenharmony_ci    }
3764514f5e3Sopenharmony_ci
3774514f5e3Sopenharmony_ci    JSTaggedValue GetEndIndex()
3784514f5e3Sopenharmony_ci    {
3794514f5e3Sopenharmony_ci        return Get(END_INDEX);
3804514f5e3Sopenharmony_ci    }
3814514f5e3Sopenharmony_ci
3824514f5e3Sopenharmony_ci    void SetInputString(JSThread *thread, JSTaggedValue string)
3834514f5e3Sopenharmony_ci    {
3844514f5e3Sopenharmony_ci        Set(thread, INPUT_STRING_INDEX, string);
3854514f5e3Sopenharmony_ci    }
3864514f5e3Sopenharmony_ci
3874514f5e3Sopenharmony_ci    JSTaggedValue GetInputString()
3884514f5e3Sopenharmony_ci    {
3894514f5e3Sopenharmony_ci        return Get(INPUT_STRING_INDEX);
3904514f5e3Sopenharmony_ci    }
3914514f5e3Sopenharmony_ci
3924514f5e3Sopenharmony_ci    void SetStartOfCaptureIndex(JSThread *thread, uint32_t index, JSTaggedValue value)
3934514f5e3Sopenharmony_ci    {
3944514f5e3Sopenharmony_ci        Set(thread, FIRST_CAPTURE_INDEX + index * 2, value); // 2 : double
3954514f5e3Sopenharmony_ci    }
3964514f5e3Sopenharmony_ci
3974514f5e3Sopenharmony_ci    void SetEndOfCaptureIndex(JSThread *thread, uint32_t index, JSTaggedValue value)
3984514f5e3Sopenharmony_ci    {
3994514f5e3Sopenharmony_ci        Set(thread, FIRST_CAPTURE_INDEX + index * 2 + 1, value); // 2 : double
4004514f5e3Sopenharmony_ci    }
4014514f5e3Sopenharmony_ci
4024514f5e3Sopenharmony_ci    JSTaggedValue GetStartOfCaptureIndex(uint32_t index)
4034514f5e3Sopenharmony_ci    {
4044514f5e3Sopenharmony_ci        return Get(FIRST_CAPTURE_INDEX + index * 2); // 2 : double
4054514f5e3Sopenharmony_ci    }
4064514f5e3Sopenharmony_ci
4074514f5e3Sopenharmony_ci    JSTaggedValue GetEndOfCaptureIndex(uint32_t index)
4084514f5e3Sopenharmony_ci    {
4094514f5e3Sopenharmony_ci        return Get(FIRST_CAPTURE_INDEX + index * 2 + 1); // 2 : double
4104514f5e3Sopenharmony_ci    }
4114514f5e3Sopenharmony_ci
4124514f5e3Sopenharmony_ci    static JSHandle<RegExpGlobalResult> GrowCapturesCapacity(JSThread *thread,
4134514f5e3Sopenharmony_ci        JSHandle<RegExpGlobalResult>result, uint32_t length);
4144514f5e3Sopenharmony_ci
4154514f5e3Sopenharmony_ci    static constexpr int FIRST_CAPTURE_INDEX = 12;  // capture index starts here
4164514f5e3Sopenharmony_ci
4174514f5e3Sopenharmony_ciprivate:
4184514f5e3Sopenharmony_ci    static constexpr int GLOBAL_TABLE_SIZE = 12; // initial length
4194514f5e3Sopenharmony_ci    static constexpr int DOLLAR_NUMBER = 9;
4204514f5e3Sopenharmony_ci    static constexpr int CAPTURE_START_INDEX = 0;
4214514f5e3Sopenharmony_ci
4224514f5e3Sopenharmony_ci    static constexpr int TOTAL_CAPTURE_COUNTS_INDEX = 9;  // save total capture size
4234514f5e3Sopenharmony_ci    static constexpr int INPUT_STRING_INDEX = 10; // save input string
4244514f5e3Sopenharmony_ci    static constexpr int END_INDEX = 11; // save last index
4254514f5e3Sopenharmony_ci    static constexpr int INITIAL_CAPTURE_INDICES = 18;  // length: pairs of capture start index and end index
4264514f5e3Sopenharmony_ci};
4274514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::builtins
4284514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H
429