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> ®exp, 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