11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ 61cb0ef41Sopenharmony_ci#define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/strings.h" 91cb0ef41Sopenharmony_ci#include "src/regexp/regexp-ast.h" 101cb0ef41Sopenharmony_ci#include "src/regexp/regexp.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass ByteArray; 161cb0ef41Sopenharmony_ciclass JSRegExp; 171cb0ef41Sopenharmony_ciclass Label; 181cb0ef41Sopenharmony_ciclass String; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cistatic const base::uc32 kLeadSurrogateStart = 0xd800; 211cb0ef41Sopenharmony_cistatic const base::uc32 kLeadSurrogateEnd = 0xdbff; 221cb0ef41Sopenharmony_cistatic const base::uc32 kTrailSurrogateStart = 0xdc00; 231cb0ef41Sopenharmony_cistatic const base::uc32 kTrailSurrogateEnd = 0xdfff; 241cb0ef41Sopenharmony_cistatic const base::uc32 kNonBmpStart = 0x10000; 251cb0ef41Sopenharmony_cistatic const base::uc32 kNonBmpEnd = 0x10ffff; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciclass RegExpMacroAssembler { 281cb0ef41Sopenharmony_ci public: 291cb0ef41Sopenharmony_ci // The implementation must be able to handle at least: 301cb0ef41Sopenharmony_ci static constexpr int kMaxRegisterCount = (1 << 16); 311cb0ef41Sopenharmony_ci static constexpr int kMaxRegister = kMaxRegisterCount - 1; 321cb0ef41Sopenharmony_ci static constexpr int kMaxCPOffset = (1 << 15) - 1; 331cb0ef41Sopenharmony_ci static constexpr int kMinCPOffset = -(1 << 15); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci static constexpr int kTableSizeBits = 7; 361cb0ef41Sopenharmony_ci static constexpr int kTableSize = 1 << kTableSizeBits; 371cb0ef41Sopenharmony_ci static constexpr int kTableMask = kTableSize - 1; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci static constexpr int kUseCharactersValue = -1; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci RegExpMacroAssembler(Isolate* isolate, Zone* zone); 421cb0ef41Sopenharmony_ci virtual ~RegExpMacroAssembler() = default; 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci virtual Handle<HeapObject> GetCode(Handle<String> source) = 0; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // This function is called when code generation is aborted, so that 471cb0ef41Sopenharmony_ci // the assembler could clean up internal data structures. 481cb0ef41Sopenharmony_ci virtual void AbortedCodeGeneration() {} 491cb0ef41Sopenharmony_ci // The maximal number of pushes between stack checks. Users must supply 501cb0ef41Sopenharmony_ci // kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck) 511cb0ef41Sopenharmony_ci // at least once for every stack_limit() pushes that are executed. 521cb0ef41Sopenharmony_ci virtual int stack_limit_slack() = 0; 531cb0ef41Sopenharmony_ci virtual bool CanReadUnaligned() const = 0; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci virtual void AdvanceCurrentPosition(int by) = 0; // Signed cp change. 561cb0ef41Sopenharmony_ci virtual void AdvanceRegister(int reg, int by) = 0; // r[reg] += by. 571cb0ef41Sopenharmony_ci // Continues execution from the position pushed on the top of the backtrack 581cb0ef41Sopenharmony_ci // stack by an earlier PushBacktrack(Label*). 591cb0ef41Sopenharmony_ci virtual void Backtrack() = 0; 601cb0ef41Sopenharmony_ci virtual void Bind(Label* label) = 0; 611cb0ef41Sopenharmony_ci // Dispatch after looking the current character up in a 2-bits-per-entry 621cb0ef41Sopenharmony_ci // map. The destinations vector has up to 4 labels. 631cb0ef41Sopenharmony_ci virtual void CheckCharacter(unsigned c, Label* on_equal) = 0; 641cb0ef41Sopenharmony_ci // Bitwise and the current character with the given constant and then 651cb0ef41Sopenharmony_ci // check for a match with c. 661cb0ef41Sopenharmony_ci virtual void CheckCharacterAfterAnd(unsigned c, 671cb0ef41Sopenharmony_ci unsigned and_with, 681cb0ef41Sopenharmony_ci Label* on_equal) = 0; 691cb0ef41Sopenharmony_ci virtual void CheckCharacterGT(base::uc16 limit, Label* on_greater) = 0; 701cb0ef41Sopenharmony_ci virtual void CheckCharacterLT(base::uc16 limit, Label* on_less) = 0; 711cb0ef41Sopenharmony_ci virtual void CheckGreedyLoop(Label* on_tos_equals_current_position) = 0; 721cb0ef41Sopenharmony_ci virtual void CheckAtStart(int cp_offset, Label* on_at_start) = 0; 731cb0ef41Sopenharmony_ci virtual void CheckNotAtStart(int cp_offset, Label* on_not_at_start) = 0; 741cb0ef41Sopenharmony_ci virtual void CheckNotBackReference(int start_reg, bool read_backward, 751cb0ef41Sopenharmony_ci Label* on_no_match) = 0; 761cb0ef41Sopenharmony_ci virtual void CheckNotBackReferenceIgnoreCase(int start_reg, 771cb0ef41Sopenharmony_ci bool read_backward, bool unicode, 781cb0ef41Sopenharmony_ci Label* on_no_match) = 0; 791cb0ef41Sopenharmony_ci // Check the current character for a match with a literal character. If we 801cb0ef41Sopenharmony_ci // fail to match then goto the on_failure label. End of input always 811cb0ef41Sopenharmony_ci // matches. If the label is nullptr then we should pop a backtrack address 821cb0ef41Sopenharmony_ci // off the stack and go to that. 831cb0ef41Sopenharmony_ci virtual void CheckNotCharacter(unsigned c, Label* on_not_equal) = 0; 841cb0ef41Sopenharmony_ci virtual void CheckNotCharacterAfterAnd(unsigned c, 851cb0ef41Sopenharmony_ci unsigned and_with, 861cb0ef41Sopenharmony_ci Label* on_not_equal) = 0; 871cb0ef41Sopenharmony_ci // Subtract a constant from the current character, then and with the given 881cb0ef41Sopenharmony_ci // constant and then check for a match with c. 891cb0ef41Sopenharmony_ci virtual void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus, 901cb0ef41Sopenharmony_ci base::uc16 and_with, 911cb0ef41Sopenharmony_ci Label* on_not_equal) = 0; 921cb0ef41Sopenharmony_ci virtual void CheckCharacterInRange(base::uc16 from, 931cb0ef41Sopenharmony_ci base::uc16 to, // Both inclusive. 941cb0ef41Sopenharmony_ci Label* on_in_range) = 0; 951cb0ef41Sopenharmony_ci virtual void CheckCharacterNotInRange(base::uc16 from, 961cb0ef41Sopenharmony_ci base::uc16 to, // Both inclusive. 971cb0ef41Sopenharmony_ci Label* on_not_in_range) = 0; 981cb0ef41Sopenharmony_ci // Returns true if the check was emitted, false otherwise. 991cb0ef41Sopenharmony_ci virtual bool CheckCharacterInRangeArray( 1001cb0ef41Sopenharmony_ci const ZoneList<CharacterRange>* ranges, Label* on_in_range) = 0; 1011cb0ef41Sopenharmony_ci virtual bool CheckCharacterNotInRangeArray( 1021cb0ef41Sopenharmony_ci const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) = 0; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // The current character (modulus the kTableSize) is looked up in the byte 1051cb0ef41Sopenharmony_ci // array, and if the found byte is non-zero, we jump to the on_bit_set label. 1061cb0ef41Sopenharmony_ci virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) = 0; 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci // Checks whether the given offset from the current position is before 1091cb0ef41Sopenharmony_ci // the end of the string. May overwrite the current character. 1101cb0ef41Sopenharmony_ci virtual void CheckPosition(int cp_offset, Label* on_outside_input); 1111cb0ef41Sopenharmony_ci // Check whether a standard/default character class matches the current 1121cb0ef41Sopenharmony_ci // character. Returns false if the type of special character class does 1131cb0ef41Sopenharmony_ci // not have custom support. 1141cb0ef41Sopenharmony_ci // May clobber the current loaded character. 1151cb0ef41Sopenharmony_ci virtual bool CheckSpecialCharacterClass(StandardCharacterSet type, 1161cb0ef41Sopenharmony_ci Label* on_no_match) { 1171cb0ef41Sopenharmony_ci return false; 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci // Control-flow integrity: 1211cb0ef41Sopenharmony_ci // Define a jump target and bind a label. 1221cb0ef41Sopenharmony_ci virtual void BindJumpTarget(Label* label) { Bind(label); } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci virtual void Fail() = 0; 1251cb0ef41Sopenharmony_ci virtual void GoTo(Label* label) = 0; 1261cb0ef41Sopenharmony_ci // Check whether a register is >= a given constant and go to a label if it 1271cb0ef41Sopenharmony_ci // is. Backtracks instead if the label is nullptr. 1281cb0ef41Sopenharmony_ci virtual void IfRegisterGE(int reg, int comparand, Label* if_ge) = 0; 1291cb0ef41Sopenharmony_ci // Check whether a register is < a given constant and go to a label if it is. 1301cb0ef41Sopenharmony_ci // Backtracks instead if the label is nullptr. 1311cb0ef41Sopenharmony_ci virtual void IfRegisterLT(int reg, int comparand, Label* if_lt) = 0; 1321cb0ef41Sopenharmony_ci // Check whether a register is == to the current position and go to a 1331cb0ef41Sopenharmony_ci // label if it is. 1341cb0ef41Sopenharmony_ci virtual void IfRegisterEqPos(int reg, Label* if_eq) = 0; 1351cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void LoadCurrentCharacter( 1361cb0ef41Sopenharmony_ci int cp_offset, Label* on_end_of_input, bool check_bounds = true, 1371cb0ef41Sopenharmony_ci int characters = 1, int eats_at_least = kUseCharactersValue); 1381cb0ef41Sopenharmony_ci virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input, 1391cb0ef41Sopenharmony_ci bool check_bounds, int characters, 1401cb0ef41Sopenharmony_ci int eats_at_least) = 0; 1411cb0ef41Sopenharmony_ci virtual void PopCurrentPosition() = 0; 1421cb0ef41Sopenharmony_ci virtual void PopRegister(int register_index) = 0; 1431cb0ef41Sopenharmony_ci // Pushes the label on the backtrack stack, so that a following Backtrack 1441cb0ef41Sopenharmony_ci // will go to this label. Always checks the backtrack stack limit. 1451cb0ef41Sopenharmony_ci virtual void PushBacktrack(Label* label) = 0; 1461cb0ef41Sopenharmony_ci virtual void PushCurrentPosition() = 0; 1471cb0ef41Sopenharmony_ci enum StackCheckFlag { kNoStackLimitCheck = false, kCheckStackLimit = true }; 1481cb0ef41Sopenharmony_ci virtual void PushRegister(int register_index, 1491cb0ef41Sopenharmony_ci StackCheckFlag check_stack_limit) = 0; 1501cb0ef41Sopenharmony_ci virtual void ReadCurrentPositionFromRegister(int reg) = 0; 1511cb0ef41Sopenharmony_ci virtual void ReadStackPointerFromRegister(int reg) = 0; 1521cb0ef41Sopenharmony_ci virtual void SetCurrentPositionFromEnd(int by) = 0; 1531cb0ef41Sopenharmony_ci virtual void SetRegister(int register_index, int to) = 0; 1541cb0ef41Sopenharmony_ci // Return whether the matching (with a global regexp) will be restarted. 1551cb0ef41Sopenharmony_ci virtual bool Succeed() = 0; 1561cb0ef41Sopenharmony_ci virtual void WriteCurrentPositionToRegister(int reg, int cp_offset) = 0; 1571cb0ef41Sopenharmony_ci virtual void ClearRegisters(int reg_from, int reg_to) = 0; 1581cb0ef41Sopenharmony_ci virtual void WriteStackPointerToRegister(int reg) = 0; 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci // Check that we are not in the middle of a surrogate pair. 1611cb0ef41Sopenharmony_ci void CheckNotInSurrogatePair(int cp_offset, Label* on_failure); 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci#define IMPLEMENTATIONS_LIST(V) \ 1641cb0ef41Sopenharmony_ci V(IA32) \ 1651cb0ef41Sopenharmony_ci V(ARM) \ 1661cb0ef41Sopenharmony_ci V(ARM64) \ 1671cb0ef41Sopenharmony_ci V(MIPS) \ 1681cb0ef41Sopenharmony_ci V(LOONG64) \ 1691cb0ef41Sopenharmony_ci V(RISCV) \ 1701cb0ef41Sopenharmony_ci V(S390) \ 1711cb0ef41Sopenharmony_ci V(PPC) \ 1721cb0ef41Sopenharmony_ci V(X64) \ 1731cb0ef41Sopenharmony_ci V(Bytecode) 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci enum IrregexpImplementation { 1761cb0ef41Sopenharmony_ci#define V(Name) k##Name##Implementation, 1771cb0ef41Sopenharmony_ci IMPLEMENTATIONS_LIST(V) 1781cb0ef41Sopenharmony_ci#undef V 1791cb0ef41Sopenharmony_ci }; 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci inline const char* ImplementationToString(IrregexpImplementation impl) { 1821cb0ef41Sopenharmony_ci static const char* const kNames[] = { 1831cb0ef41Sopenharmony_ci#define V(Name) #Name, 1841cb0ef41Sopenharmony_ci IMPLEMENTATIONS_LIST(V) 1851cb0ef41Sopenharmony_ci#undef V 1861cb0ef41Sopenharmony_ci }; 1871cb0ef41Sopenharmony_ci return kNames[impl]; 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci#undef IMPLEMENTATIONS_LIST 1901cb0ef41Sopenharmony_ci virtual IrregexpImplementation Implementation() = 0; 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci // Compare two-byte strings case insensitively. 1931cb0ef41Sopenharmony_ci // 1941cb0ef41Sopenharmony_ci // Called from generated code. 1951cb0ef41Sopenharmony_ci static int CaseInsensitiveCompareNonUnicode(Address byte_offset1, 1961cb0ef41Sopenharmony_ci Address byte_offset2, 1971cb0ef41Sopenharmony_ci size_t byte_length, 1981cb0ef41Sopenharmony_ci Isolate* isolate); 1991cb0ef41Sopenharmony_ci static int CaseInsensitiveCompareUnicode(Address byte_offset1, 2001cb0ef41Sopenharmony_ci Address byte_offset2, 2011cb0ef41Sopenharmony_ci size_t byte_length, 2021cb0ef41Sopenharmony_ci Isolate* isolate); 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci // `raw_byte_array` is a ByteArray containing a set of character ranges, 2051cb0ef41Sopenharmony_ci // where ranges are encoded as uint16_t elements: 2061cb0ef41Sopenharmony_ci // 2071cb0ef41Sopenharmony_ci // [from0, to0, from1, to1, ..., fromN, toN], or 2081cb0ef41Sopenharmony_ci // [from0, to0, from1, to1, ..., fromN] (open-ended last interval). 2091cb0ef41Sopenharmony_ci // 2101cb0ef41Sopenharmony_ci // fromN is inclusive, toN is exclusive. Returns zero if not in a range, 2111cb0ef41Sopenharmony_ci // non-zero otherwise. 2121cb0ef41Sopenharmony_ci // 2131cb0ef41Sopenharmony_ci // Called from generated code. 2141cb0ef41Sopenharmony_ci static uint32_t IsCharacterInRangeArray(uint32_t current_char, 2151cb0ef41Sopenharmony_ci Address raw_byte_array, 2161cb0ef41Sopenharmony_ci Isolate* isolate); 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci // Controls the generation of large inlined constants in the code. 2191cb0ef41Sopenharmony_ci void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; } 2201cb0ef41Sopenharmony_ci bool slow_safe() const { return slow_safe_compiler_; } 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci // Controls after how many backtracks irregexp should abort execution. If it 2231cb0ef41Sopenharmony_ci // can fall back to the experimental engine (see `set_can_fallback`), it will 2241cb0ef41Sopenharmony_ci // return the appropriate error code, otherwise it will return the number of 2251cb0ef41Sopenharmony_ci // matches found so far (perhaps none). 2261cb0ef41Sopenharmony_ci void set_backtrack_limit(uint32_t backtrack_limit) { 2271cb0ef41Sopenharmony_ci backtrack_limit_ = backtrack_limit; 2281cb0ef41Sopenharmony_ci } 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci // Set whether or not irregexp can fall back to the experimental engine on 2311cb0ef41Sopenharmony_ci // excessive backtracking. The number of backtracks considered excessive can 2321cb0ef41Sopenharmony_ci // be controlled with set_backtrack_limit. 2331cb0ef41Sopenharmony_ci void set_can_fallback(bool val) { can_fallback_ = val; } 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci enum GlobalMode { 2361cb0ef41Sopenharmony_ci NOT_GLOBAL, 2371cb0ef41Sopenharmony_ci GLOBAL_NO_ZERO_LENGTH_CHECK, 2381cb0ef41Sopenharmony_ci GLOBAL, 2391cb0ef41Sopenharmony_ci GLOBAL_UNICODE 2401cb0ef41Sopenharmony_ci }; 2411cb0ef41Sopenharmony_ci // Set whether the regular expression has the global flag. Exiting due to 2421cb0ef41Sopenharmony_ci // a failure in a global regexp may still mean success overall. 2431cb0ef41Sopenharmony_ci inline void set_global_mode(GlobalMode mode) { global_mode_ = mode; } 2441cb0ef41Sopenharmony_ci inline bool global() const { return global_mode_ != NOT_GLOBAL; } 2451cb0ef41Sopenharmony_ci inline bool global_with_zero_length_check() const { 2461cb0ef41Sopenharmony_ci return global_mode_ == GLOBAL || global_mode_ == GLOBAL_UNICODE; 2471cb0ef41Sopenharmony_ci } 2481cb0ef41Sopenharmony_ci inline bool global_unicode() const { return global_mode_ == GLOBAL_UNICODE; } 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci Isolate* isolate() const { return isolate_; } 2511cb0ef41Sopenharmony_ci Zone* zone() const { return zone_; } 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci protected: 2541cb0ef41Sopenharmony_ci bool has_backtrack_limit() const; 2551cb0ef41Sopenharmony_ci uint32_t backtrack_limit() const { return backtrack_limit_; } 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_ci bool can_fallback() const { return can_fallback_; } 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci private: 2601cb0ef41Sopenharmony_ci bool slow_safe_compiler_; 2611cb0ef41Sopenharmony_ci uint32_t backtrack_limit_; 2621cb0ef41Sopenharmony_ci bool can_fallback_ = false; 2631cb0ef41Sopenharmony_ci GlobalMode global_mode_; 2641cb0ef41Sopenharmony_ci Isolate* const isolate_; 2651cb0ef41Sopenharmony_ci Zone* const zone_; 2661cb0ef41Sopenharmony_ci}; 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ciclass NativeRegExpMacroAssembler: public RegExpMacroAssembler { 2691cb0ef41Sopenharmony_ci public: 2701cb0ef41Sopenharmony_ci // Type of input string to generate code for. 2711cb0ef41Sopenharmony_ci enum Mode { LATIN1 = 1, UC16 = 2 }; 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci // Result of calling generated native RegExp code. 2741cb0ef41Sopenharmony_ci // RETRY: Something significant changed during execution, and the matching 2751cb0ef41Sopenharmony_ci // should be retried from scratch. 2761cb0ef41Sopenharmony_ci // EXCEPTION: Something failed during execution. If no exception has been 2771cb0ef41Sopenharmony_ci // thrown, it's an internal out-of-memory, and the caller should 2781cb0ef41Sopenharmony_ci // throw the exception. 2791cb0ef41Sopenharmony_ci // FAILURE: Matching failed. 2801cb0ef41Sopenharmony_ci // SUCCESS: Matching succeeded, and the output array has been filled with 2811cb0ef41Sopenharmony_ci // capture positions. 2821cb0ef41Sopenharmony_ci // FALLBACK_TO_EXPERIMENTAL: Execute the regexp on this subject using the 2831cb0ef41Sopenharmony_ci // experimental engine instead. 2841cb0ef41Sopenharmony_ci enum Result { 2851cb0ef41Sopenharmony_ci FAILURE = RegExp::kInternalRegExpFailure, 2861cb0ef41Sopenharmony_ci SUCCESS = RegExp::kInternalRegExpSuccess, 2871cb0ef41Sopenharmony_ci EXCEPTION = RegExp::kInternalRegExpException, 2881cb0ef41Sopenharmony_ci RETRY = RegExp::kInternalRegExpRetry, 2891cb0ef41Sopenharmony_ci FALLBACK_TO_EXPERIMENTAL = RegExp::kInternalRegExpFallbackToExperimental, 2901cb0ef41Sopenharmony_ci SMALLEST_REGEXP_RESULT = RegExp::kInternalRegExpSmallestResult, 2911cb0ef41Sopenharmony_ci }; 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci NativeRegExpMacroAssembler(Isolate* isolate, Zone* zone) 2941cb0ef41Sopenharmony_ci : RegExpMacroAssembler(isolate, zone) {} 2951cb0ef41Sopenharmony_ci ~NativeRegExpMacroAssembler() override = default; 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci // Returns a {Result} sentinel, or the number of successful matches. 2981cb0ef41Sopenharmony_ci static int Match(Handle<JSRegExp> regexp, Handle<String> subject, 2991cb0ef41Sopenharmony_ci int* offsets_vector, int offsets_vector_length, 3001cb0ef41Sopenharmony_ci int previous_index, Isolate* isolate); 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE static int ExecuteForTesting(String input, int start_offset, 3031cb0ef41Sopenharmony_ci const byte* input_start, 3041cb0ef41Sopenharmony_ci const byte* input_end, 3051cb0ef41Sopenharmony_ci int* output, int output_size, 3061cb0ef41Sopenharmony_ci Isolate* isolate, 3071cb0ef41Sopenharmony_ci JSRegExp regexp); 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci bool CanReadUnaligned() const override; 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input, 3121cb0ef41Sopenharmony_ci bool check_bounds, int characters, 3131cb0ef41Sopenharmony_ci int eats_at_least) override; 3141cb0ef41Sopenharmony_ci // Load a number of characters at the given offset from the 3151cb0ef41Sopenharmony_ci // current position, into the current-character register. 3161cb0ef41Sopenharmony_ci virtual void LoadCurrentCharacterUnchecked(int cp_offset, 3171cb0ef41Sopenharmony_ci int character_count) = 0; 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci // Called from RegExp if the backtrack stack limit is hit. Tries to expand 3201cb0ef41Sopenharmony_ci // the stack. Returns the new stack-pointer if successful, or returns 0 if 3211cb0ef41Sopenharmony_ci // unable to grow the stack. 3221cb0ef41Sopenharmony_ci // This function must not trigger a garbage collection. 3231cb0ef41Sopenharmony_ci // 3241cb0ef41Sopenharmony_ci // Called from generated code. 3251cb0ef41Sopenharmony_ci static Address GrowStack(Isolate* isolate); 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci // Called from generated code. 3281cb0ef41Sopenharmony_ci static int CheckStackGuardState(Isolate* isolate, int start_index, 3291cb0ef41Sopenharmony_ci RegExp::CallOrigin call_origin, 3301cb0ef41Sopenharmony_ci Address* return_address, Code re_code, 3311cb0ef41Sopenharmony_ci Address* subject, const byte** input_start, 3321cb0ef41Sopenharmony_ci const byte** input_end); 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ci static Address word_character_map_address() { 3351cb0ef41Sopenharmony_ci return reinterpret_cast<Address>(&word_character_map[0]); 3361cb0ef41Sopenharmony_ci } 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci protected: 3391cb0ef41Sopenharmony_ci // Byte map of one byte characters with a 0xff if the character is a word 3401cb0ef41Sopenharmony_ci // character (digit, letter or underscore) and 0x00 otherwise. 3411cb0ef41Sopenharmony_ci // Used by generated RegExp code. 3421cb0ef41Sopenharmony_ci static const byte word_character_map[256]; 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci Handle<ByteArray> GetOrAddRangeArray(const ZoneList<CharacterRange>* ranges); 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci private: 3471cb0ef41Sopenharmony_ci // Returns a {Result} sentinel, or the number of successful matches. 3481cb0ef41Sopenharmony_ci static int Execute(String input, int start_offset, const byte* input_start, 3491cb0ef41Sopenharmony_ci const byte* input_end, int* output, int output_size, 3501cb0ef41Sopenharmony_ci Isolate* isolate, JSRegExp regexp); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci std::unordered_map<uint32_t, Handle<ByteArray>> range_array_cache_; 3531cb0ef41Sopenharmony_ci}; 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_ci} // namespace internal 3561cb0ef41Sopenharmony_ci} // namespace v8 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci#endif // V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ 359