11cb0ef41Sopenharmony_ci// Copyright 2008-2009 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#include "src/regexp/regexp-bytecode-generator.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
81cb0ef41Sopenharmony_ci#include "src/objects/fixed-array-inl.h"
91cb0ef41Sopenharmony_ci#include "src/regexp/regexp-bytecode-generator-inl.h"
101cb0ef41Sopenharmony_ci#include "src/regexp/regexp-bytecode-peephole.h"
111cb0ef41Sopenharmony_ci#include "src/regexp/regexp-bytecodes.h"
121cb0ef41Sopenharmony_ci#include "src/regexp/regexp-macro-assembler.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciRegExpBytecodeGenerator::RegExpBytecodeGenerator(Isolate* isolate, Zone* zone)
181cb0ef41Sopenharmony_ci    : RegExpMacroAssembler(isolate, zone),
191cb0ef41Sopenharmony_ci      buffer_(kInitialBufferSize, zone),
201cb0ef41Sopenharmony_ci      pc_(0),
211cb0ef41Sopenharmony_ci      advance_current_end_(kInvalidPC),
221cb0ef41Sopenharmony_ci      jump_edges_(zone),
231cb0ef41Sopenharmony_ci      isolate_(isolate) {}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciRegExpBytecodeGenerator::~RegExpBytecodeGenerator() {
261cb0ef41Sopenharmony_ci  if (backtrack_.is_linked()) backtrack_.Unuse();
271cb0ef41Sopenharmony_ci}
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciRegExpBytecodeGenerator::IrregexpImplementation
301cb0ef41Sopenharmony_ciRegExpBytecodeGenerator::Implementation() {
311cb0ef41Sopenharmony_ci  return kBytecodeImplementation;
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::Bind(Label* l) {
351cb0ef41Sopenharmony_ci  advance_current_end_ = kInvalidPC;
361cb0ef41Sopenharmony_ci  DCHECK(!l->is_bound());
371cb0ef41Sopenharmony_ci  if (l->is_linked()) {
381cb0ef41Sopenharmony_ci    int pos = l->pos();
391cb0ef41Sopenharmony_ci    while (pos != 0) {
401cb0ef41Sopenharmony_ci      int fixup = pos;
411cb0ef41Sopenharmony_ci      pos = *reinterpret_cast<int32_t*>(buffer_.data() + fixup);
421cb0ef41Sopenharmony_ci      *reinterpret_cast<uint32_t*>(buffer_.data() + fixup) = pc_;
431cb0ef41Sopenharmony_ci      jump_edges_.emplace(fixup, pc_);
441cb0ef41Sopenharmony_ci    }
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci  l->bind_to(pc_);
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::EmitOrLink(Label* l) {
501cb0ef41Sopenharmony_ci  if (l == nullptr) l = &backtrack_;
511cb0ef41Sopenharmony_ci  int pos = 0;
521cb0ef41Sopenharmony_ci  if (l->is_bound()) {
531cb0ef41Sopenharmony_ci    pos = l->pos();
541cb0ef41Sopenharmony_ci    jump_edges_.emplace(pc_, pos);
551cb0ef41Sopenharmony_ci  } else {
561cb0ef41Sopenharmony_ci    if (l->is_linked()) {
571cb0ef41Sopenharmony_ci      pos = l->pos();
581cb0ef41Sopenharmony_ci    }
591cb0ef41Sopenharmony_ci    l->link_to(pc_);
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci  Emit32(pos);
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::PopRegister(int register_index) {
651cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
661cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
671cb0ef41Sopenharmony_ci  Emit(BC_POP_REGISTER, register_index);
681cb0ef41Sopenharmony_ci}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::PushRegister(int register_index,
711cb0ef41Sopenharmony_ci                                           StackCheckFlag check_stack_limit) {
721cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
731cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
741cb0ef41Sopenharmony_ci  Emit(BC_PUSH_REGISTER, register_index);
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::WriteCurrentPositionToRegister(int register_index,
781cb0ef41Sopenharmony_ci                                                             int cp_offset) {
791cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
801cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
811cb0ef41Sopenharmony_ci  Emit(BC_SET_REGISTER_TO_CP, register_index);
821cb0ef41Sopenharmony_ci  Emit32(cp_offset);  // Current position offset.
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::ClearRegisters(int reg_from, int reg_to) {
861cb0ef41Sopenharmony_ci  DCHECK(reg_from <= reg_to);
871cb0ef41Sopenharmony_ci  for (int reg = reg_from; reg <= reg_to; reg++) {
881cb0ef41Sopenharmony_ci    SetRegister(reg, -1);
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::ReadCurrentPositionFromRegister(
931cb0ef41Sopenharmony_ci    int register_index) {
941cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
951cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
961cb0ef41Sopenharmony_ci  Emit(BC_SET_CP_TO_REGISTER, register_index);
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::WriteStackPointerToRegister(int register_index) {
1001cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
1011cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
1021cb0ef41Sopenharmony_ci  Emit(BC_SET_REGISTER_TO_SP, register_index);
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::ReadStackPointerFromRegister(int register_index) {
1061cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
1071cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
1081cb0ef41Sopenharmony_ci  Emit(BC_SET_SP_TO_REGISTER, register_index);
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::SetCurrentPositionFromEnd(int by) {
1121cb0ef41Sopenharmony_ci  DCHECK(is_uint24(by));
1131cb0ef41Sopenharmony_ci  Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
1141cb0ef41Sopenharmony_ci}
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::SetRegister(int register_index, int to) {
1171cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
1181cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
1191cb0ef41Sopenharmony_ci  Emit(BC_SET_REGISTER, register_index);
1201cb0ef41Sopenharmony_ci  Emit32(to);
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::AdvanceRegister(int register_index, int by) {
1241cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
1251cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
1261cb0ef41Sopenharmony_ci  Emit(BC_ADVANCE_REGISTER, register_index);
1271cb0ef41Sopenharmony_ci  Emit32(by);
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::PopCurrentPosition() { Emit(BC_POP_CP, 0); }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::PushCurrentPosition() { Emit(BC_PUSH_CP, 0); }
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::Backtrack() {
1351cb0ef41Sopenharmony_ci  int error_code =
1361cb0ef41Sopenharmony_ci      can_fallback() ? RegExp::RE_FALLBACK_TO_EXPERIMENTAL : RegExp::RE_FAILURE;
1371cb0ef41Sopenharmony_ci  Emit(BC_POP_BT, error_code);
1381cb0ef41Sopenharmony_ci}
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::GoTo(Label* l) {
1411cb0ef41Sopenharmony_ci  if (advance_current_end_ == pc_) {
1421cb0ef41Sopenharmony_ci    // Combine advance current and goto.
1431cb0ef41Sopenharmony_ci    pc_ = advance_current_start_;
1441cb0ef41Sopenharmony_ci    Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
1451cb0ef41Sopenharmony_ci    EmitOrLink(l);
1461cb0ef41Sopenharmony_ci    advance_current_end_ = kInvalidPC;
1471cb0ef41Sopenharmony_ci  } else {
1481cb0ef41Sopenharmony_ci    // Regular goto.
1491cb0ef41Sopenharmony_ci    Emit(BC_GOTO, 0);
1501cb0ef41Sopenharmony_ci    EmitOrLink(l);
1511cb0ef41Sopenharmony_ci  }
1521cb0ef41Sopenharmony_ci}
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::PushBacktrack(Label* l) {
1551cb0ef41Sopenharmony_ci  Emit(BC_PUSH_BT, 0);
1561cb0ef41Sopenharmony_ci  EmitOrLink(l);
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_cibool RegExpBytecodeGenerator::Succeed() {
1601cb0ef41Sopenharmony_ci  Emit(BC_SUCCEED, 0);
1611cb0ef41Sopenharmony_ci  return false;  // Restart matching for global regexp not supported.
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::Fail() { Emit(BC_FAIL, 0); }
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::AdvanceCurrentPosition(int by) {
1671cb0ef41Sopenharmony_ci  // TODO(chromium:1166138): Turn back into DCHECKs once the underlying issue
1681cb0ef41Sopenharmony_ci  // is fixed.
1691cb0ef41Sopenharmony_ci  CHECK_LE(kMinCPOffset, by);
1701cb0ef41Sopenharmony_ci  CHECK_GE(kMaxCPOffset, by);
1711cb0ef41Sopenharmony_ci  advance_current_start_ = pc_;
1721cb0ef41Sopenharmony_ci  advance_current_offset_ = by;
1731cb0ef41Sopenharmony_ci  Emit(BC_ADVANCE_CP, by);
1741cb0ef41Sopenharmony_ci  advance_current_end_ = pc_;
1751cb0ef41Sopenharmony_ci}
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckGreedyLoop(
1781cb0ef41Sopenharmony_ci    Label* on_tos_equals_current_position) {
1791cb0ef41Sopenharmony_ci  Emit(BC_CHECK_GREEDY, 0);
1801cb0ef41Sopenharmony_ci  EmitOrLink(on_tos_equals_current_position);
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::LoadCurrentCharacterImpl(int cp_offset,
1841cb0ef41Sopenharmony_ci                                                       Label* on_failure,
1851cb0ef41Sopenharmony_ci                                                       bool check_bounds,
1861cb0ef41Sopenharmony_ci                                                       int characters,
1871cb0ef41Sopenharmony_ci                                                       int eats_at_least) {
1881cb0ef41Sopenharmony_ci  DCHECK_GE(eats_at_least, characters);
1891cb0ef41Sopenharmony_ci  if (eats_at_least > characters && check_bounds) {
1901cb0ef41Sopenharmony_ci    DCHECK(is_int24(cp_offset + eats_at_least));
1911cb0ef41Sopenharmony_ci    Emit(BC_CHECK_CURRENT_POSITION, cp_offset + eats_at_least);
1921cb0ef41Sopenharmony_ci    EmitOrLink(on_failure);
1931cb0ef41Sopenharmony_ci    check_bounds = false;  // Load below doesn't need to check.
1941cb0ef41Sopenharmony_ci  }
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  DCHECK_LE(kMinCPOffset, cp_offset);
1971cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxCPOffset, cp_offset);
1981cb0ef41Sopenharmony_ci  int bytecode;
1991cb0ef41Sopenharmony_ci  if (check_bounds) {
2001cb0ef41Sopenharmony_ci    if (characters == 4) {
2011cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_4_CURRENT_CHARS;
2021cb0ef41Sopenharmony_ci    } else if (characters == 2) {
2031cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_2_CURRENT_CHARS;
2041cb0ef41Sopenharmony_ci    } else {
2051cb0ef41Sopenharmony_ci      DCHECK_EQ(1, characters);
2061cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_CURRENT_CHAR;
2071cb0ef41Sopenharmony_ci    }
2081cb0ef41Sopenharmony_ci  } else {
2091cb0ef41Sopenharmony_ci    if (characters == 4) {
2101cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
2111cb0ef41Sopenharmony_ci    } else if (characters == 2) {
2121cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
2131cb0ef41Sopenharmony_ci    } else {
2141cb0ef41Sopenharmony_ci      DCHECK_EQ(1, characters);
2151cb0ef41Sopenharmony_ci      bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
2161cb0ef41Sopenharmony_ci    }
2171cb0ef41Sopenharmony_ci  }
2181cb0ef41Sopenharmony_ci  Emit(bytecode, cp_offset);
2191cb0ef41Sopenharmony_ci  if (check_bounds) EmitOrLink(on_failure);
2201cb0ef41Sopenharmony_ci}
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacterLT(base::uc16 limit,
2231cb0ef41Sopenharmony_ci                                               Label* on_less) {
2241cb0ef41Sopenharmony_ci  Emit(BC_CHECK_LT, limit);
2251cb0ef41Sopenharmony_ci  EmitOrLink(on_less);
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacterGT(base::uc16 limit,
2291cb0ef41Sopenharmony_ci                                               Label* on_greater) {
2301cb0ef41Sopenharmony_ci  Emit(BC_CHECK_GT, limit);
2311cb0ef41Sopenharmony_ci  EmitOrLink(on_greater);
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacter(uint32_t c, Label* on_equal) {
2351cb0ef41Sopenharmony_ci  if (c > MAX_FIRST_ARG) {
2361cb0ef41Sopenharmony_ci    Emit(BC_CHECK_4_CHARS, 0);
2371cb0ef41Sopenharmony_ci    Emit32(c);
2381cb0ef41Sopenharmony_ci  } else {
2391cb0ef41Sopenharmony_ci    Emit(BC_CHECK_CHAR, c);
2401cb0ef41Sopenharmony_ci  }
2411cb0ef41Sopenharmony_ci  EmitOrLink(on_equal);
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckAtStart(int cp_offset, Label* on_at_start) {
2451cb0ef41Sopenharmony_ci  Emit(BC_CHECK_AT_START, cp_offset);
2461cb0ef41Sopenharmony_ci  EmitOrLink(on_at_start);
2471cb0ef41Sopenharmony_ci}
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotAtStart(int cp_offset,
2501cb0ef41Sopenharmony_ci                                              Label* on_not_at_start) {
2511cb0ef41Sopenharmony_ci  Emit(BC_CHECK_NOT_AT_START, cp_offset);
2521cb0ef41Sopenharmony_ci  EmitOrLink(on_not_at_start);
2531cb0ef41Sopenharmony_ci}
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotCharacter(uint32_t c,
2561cb0ef41Sopenharmony_ci                                                Label* on_not_equal) {
2571cb0ef41Sopenharmony_ci  if (c > MAX_FIRST_ARG) {
2581cb0ef41Sopenharmony_ci    Emit(BC_CHECK_NOT_4_CHARS, 0);
2591cb0ef41Sopenharmony_ci    Emit32(c);
2601cb0ef41Sopenharmony_ci  } else {
2611cb0ef41Sopenharmony_ci    Emit(BC_CHECK_NOT_CHAR, c);
2621cb0ef41Sopenharmony_ci  }
2631cb0ef41Sopenharmony_ci  EmitOrLink(on_not_equal);
2641cb0ef41Sopenharmony_ci}
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
2671cb0ef41Sopenharmony_ci                                                     Label* on_equal) {
2681cb0ef41Sopenharmony_ci  if (c > MAX_FIRST_ARG) {
2691cb0ef41Sopenharmony_ci    Emit(BC_AND_CHECK_4_CHARS, 0);
2701cb0ef41Sopenharmony_ci    Emit32(c);
2711cb0ef41Sopenharmony_ci  } else {
2721cb0ef41Sopenharmony_ci    Emit(BC_AND_CHECK_CHAR, c);
2731cb0ef41Sopenharmony_ci  }
2741cb0ef41Sopenharmony_ci  Emit32(mask);
2751cb0ef41Sopenharmony_ci  EmitOrLink(on_equal);
2761cb0ef41Sopenharmony_ci}
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotCharacterAfterAnd(uint32_t c,
2791cb0ef41Sopenharmony_ci                                                        uint32_t mask,
2801cb0ef41Sopenharmony_ci                                                        Label* on_not_equal) {
2811cb0ef41Sopenharmony_ci  if (c > MAX_FIRST_ARG) {
2821cb0ef41Sopenharmony_ci    Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
2831cb0ef41Sopenharmony_ci    Emit32(c);
2841cb0ef41Sopenharmony_ci  } else {
2851cb0ef41Sopenharmony_ci    Emit(BC_AND_CHECK_NOT_CHAR, c);
2861cb0ef41Sopenharmony_ci  }
2871cb0ef41Sopenharmony_ci  Emit32(mask);
2881cb0ef41Sopenharmony_ci  EmitOrLink(on_not_equal);
2891cb0ef41Sopenharmony_ci}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotCharacterAfterMinusAnd(
2921cb0ef41Sopenharmony_ci    base::uc16 c, base::uc16 minus, base::uc16 mask, Label* on_not_equal) {
2931cb0ef41Sopenharmony_ci  Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
2941cb0ef41Sopenharmony_ci  Emit16(minus);
2951cb0ef41Sopenharmony_ci  Emit16(mask);
2961cb0ef41Sopenharmony_ci  EmitOrLink(on_not_equal);
2971cb0ef41Sopenharmony_ci}
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacterInRange(base::uc16 from,
3001cb0ef41Sopenharmony_ci                                                    base::uc16 to,
3011cb0ef41Sopenharmony_ci                                                    Label* on_in_range) {
3021cb0ef41Sopenharmony_ci  Emit(BC_CHECK_CHAR_IN_RANGE, 0);
3031cb0ef41Sopenharmony_ci  Emit16(from);
3041cb0ef41Sopenharmony_ci  Emit16(to);
3051cb0ef41Sopenharmony_ci  EmitOrLink(on_in_range);
3061cb0ef41Sopenharmony_ci}
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckCharacterNotInRange(base::uc16 from,
3091cb0ef41Sopenharmony_ci                                                       base::uc16 to,
3101cb0ef41Sopenharmony_ci                                                       Label* on_not_in_range) {
3111cb0ef41Sopenharmony_ci  Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
3121cb0ef41Sopenharmony_ci  Emit16(from);
3131cb0ef41Sopenharmony_ci  Emit16(to);
3141cb0ef41Sopenharmony_ci  EmitOrLink(on_not_in_range);
3151cb0ef41Sopenharmony_ci}
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckBitInTable(Handle<ByteArray> table,
3181cb0ef41Sopenharmony_ci                                              Label* on_bit_set) {
3191cb0ef41Sopenharmony_ci  Emit(BC_CHECK_BIT_IN_TABLE, 0);
3201cb0ef41Sopenharmony_ci  EmitOrLink(on_bit_set);
3211cb0ef41Sopenharmony_ci  for (int i = 0; i < kTableSize; i += kBitsPerByte) {
3221cb0ef41Sopenharmony_ci    int byte = 0;
3231cb0ef41Sopenharmony_ci    for (int j = 0; j < kBitsPerByte; j++) {
3241cb0ef41Sopenharmony_ci      if (table->get(i + j) != 0) byte |= 1 << j;
3251cb0ef41Sopenharmony_ci    }
3261cb0ef41Sopenharmony_ci    Emit8(byte);
3271cb0ef41Sopenharmony_ci  }
3281cb0ef41Sopenharmony_ci}
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotBackReference(int start_reg,
3311cb0ef41Sopenharmony_ci                                                    bool read_backward,
3321cb0ef41Sopenharmony_ci                                                    Label* on_not_equal) {
3331cb0ef41Sopenharmony_ci  DCHECK_LE(0, start_reg);
3341cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, start_reg);
3351cb0ef41Sopenharmony_ci  Emit(read_backward ? BC_CHECK_NOT_BACK_REF_BACKWARD : BC_CHECK_NOT_BACK_REF,
3361cb0ef41Sopenharmony_ci       start_reg);
3371cb0ef41Sopenharmony_ci  EmitOrLink(on_not_equal);
3381cb0ef41Sopenharmony_ci}
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::CheckNotBackReferenceIgnoreCase(
3411cb0ef41Sopenharmony_ci    int start_reg, bool read_backward, bool unicode, Label* on_not_equal) {
3421cb0ef41Sopenharmony_ci  DCHECK_LE(0, start_reg);
3431cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, start_reg);
3441cb0ef41Sopenharmony_ci  Emit(read_backward ? (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE_BACKWARD
3451cb0ef41Sopenharmony_ci                                : BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD)
3461cb0ef41Sopenharmony_ci                     : (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE
3471cb0ef41Sopenharmony_ci                                : BC_CHECK_NOT_BACK_REF_NO_CASE),
3481cb0ef41Sopenharmony_ci       start_reg);
3491cb0ef41Sopenharmony_ci  EmitOrLink(on_not_equal);
3501cb0ef41Sopenharmony_ci}
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::IfRegisterLT(int register_index, int comparand,
3531cb0ef41Sopenharmony_ci                                           Label* on_less_than) {
3541cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
3551cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
3561cb0ef41Sopenharmony_ci  Emit(BC_CHECK_REGISTER_LT, register_index);
3571cb0ef41Sopenharmony_ci  Emit32(comparand);
3581cb0ef41Sopenharmony_ci  EmitOrLink(on_less_than);
3591cb0ef41Sopenharmony_ci}
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::IfRegisterGE(int register_index, int comparand,
3621cb0ef41Sopenharmony_ci                                           Label* on_greater_or_equal) {
3631cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
3641cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
3651cb0ef41Sopenharmony_ci  Emit(BC_CHECK_REGISTER_GE, register_index);
3661cb0ef41Sopenharmony_ci  Emit32(comparand);
3671cb0ef41Sopenharmony_ci  EmitOrLink(on_greater_or_equal);
3681cb0ef41Sopenharmony_ci}
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::IfRegisterEqPos(int register_index,
3711cb0ef41Sopenharmony_ci                                              Label* on_eq) {
3721cb0ef41Sopenharmony_ci  DCHECK_LE(0, register_index);
3731cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxRegister, register_index);
3741cb0ef41Sopenharmony_ci  Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
3751cb0ef41Sopenharmony_ci  EmitOrLink(on_eq);
3761cb0ef41Sopenharmony_ci}
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ciHandle<HeapObject> RegExpBytecodeGenerator::GetCode(Handle<String> source) {
3791cb0ef41Sopenharmony_ci  Bind(&backtrack_);
3801cb0ef41Sopenharmony_ci  Backtrack();
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  Handle<ByteArray> array;
3831cb0ef41Sopenharmony_ci  if (FLAG_regexp_peephole_optimization) {
3841cb0ef41Sopenharmony_ci    array = RegExpBytecodePeepholeOptimization::OptimizeBytecode(
3851cb0ef41Sopenharmony_ci        isolate_, zone(), source, buffer_.data(), length(), jump_edges_);
3861cb0ef41Sopenharmony_ci  } else {
3871cb0ef41Sopenharmony_ci    array = isolate_->factory()->NewByteArray(length());
3881cb0ef41Sopenharmony_ci    Copy(array->GetDataStartAddress());
3891cb0ef41Sopenharmony_ci  }
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  return array;
3921cb0ef41Sopenharmony_ci}
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ciint RegExpBytecodeGenerator::length() { return pc_; }
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::Copy(byte* a) {
3971cb0ef41Sopenharmony_ci  MemCopy(a, buffer_.data(), length());
3981cb0ef41Sopenharmony_ci}
3991cb0ef41Sopenharmony_ci
4001cb0ef41Sopenharmony_civoid RegExpBytecodeGenerator::ExpandBuffer() {
4011cb0ef41Sopenharmony_ci  // TODO(jgruber): The growth strategy could be smarter for large sizes.
4021cb0ef41Sopenharmony_ci  // TODO(jgruber): It's not necessary to default-initialize new elements.
4031cb0ef41Sopenharmony_ci  buffer_.resize(buffer_.size() * 2);
4041cb0ef41Sopenharmony_ci}
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ci}  // namespace internal
4071cb0ef41Sopenharmony_ci}  // namespace v8
408