25 advance_current_end_(kInvalidPC) {}
37 advance_current_end_ = kInvalidPC;
43 pos = *
reinterpret_cast<int32_t*
>(buffer_->
data() + fixup);
44 *
reinterpret_cast<uint32_t*
>(buffer_->
data() + fixup) = pc_;
50void BytecodeRegExpMacroAssembler::EmitOrLink(
BlockLabel* l) {
51 if (l ==
nullptr) l = &backtrack_;
65 ASSERT(register_index >= 0);
67 Emit(BC_POP_REGISTER, register_index);
71 ASSERT(register_index >= 0);
73 Emit(BC_PUSH_REGISTER, register_index);
77 intptr_t register_index,
79 ASSERT(register_index >= 0);
81 Emit(BC_SET_REGISTER_TO_CP, register_index);
87 ASSERT(reg_from <= reg_to);
88 for (
int reg = reg_from; reg <= reg_to; reg++) {
94 intptr_t register_index) {
95 ASSERT(register_index >= 0);
97 Emit(BC_SET_CP_TO_REGISTER, register_index);
101 intptr_t register_index) {
102 ASSERT(register_index >= 0);
104 Emit(BC_SET_REGISTER_TO_SP, register_index);
108 intptr_t register_index) {
109 ASSERT(register_index >= 0);
111 Emit(BC_SET_SP_TO_REGISTER, register_index);
116 Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
121 ASSERT(register_index >= 0);
123 Emit(BC_SET_REGISTER, register_index);
129 ASSERT(register_index >= 0);
131 Emit(BC_ADVANCE_REGISTER, register_index);
148 if (advance_current_end_ == pc_) {
150 pc_ = advance_current_start_;
151 Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
153 advance_current_end_ = kInvalidPC;
178 advance_current_start_ = pc_;
179 advance_current_offset_ = by;
180 Emit(BC_ADVANCE_CP, by);
181 advance_current_end_ = pc_;
186 Emit(BC_CHECK_GREEDY, 0);
187 EmitOrLink(on_tos_equals_current_position);
193 intptr_t characters) {
198 if (characters == 4) {
199 bytecode = BC_LOAD_4_CURRENT_CHARS;
200 }
else if (characters == 2) {
201 bytecode = BC_LOAD_2_CURRENT_CHARS;
204 bytecode = BC_LOAD_CURRENT_CHAR;
207 if (characters == 4) {
208 bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
209 }
else if (characters == 2) {
210 bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
213 bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
216 Emit(bytecode, cp_offset);
222 Emit(BC_CHECK_LT, limit);
228 Emit(BC_CHECK_GT, limit);
229 EmitOrLink(on_greater);
235 Emit(BC_CHECK_4_CHARS, 0);
238 Emit(BC_CHECK_CHAR, c);
240 EmitOrLink(on_equal);
244 Emit(BC_CHECK_AT_START, 0);
245 EmitOrLink(on_at_start);
251 Emit(BC_CHECK_NOT_AT_START, cp_offset);
252 EmitOrLink(on_not_at_start);
258 Emit(BC_CHECK_NOT_4_CHARS, 0);
261 Emit(BC_CHECK_NOT_CHAR, c);
263 EmitOrLink(on_not_equal);
271 Emit(BC_AND_CHECK_4_CHARS, 0);
274 Emit(BC_AND_CHECK_CHAR, c);
277 EmitOrLink(on_equal);
285 Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
288 Emit(BC_AND_CHECK_NOT_CHAR, c);
291 EmitOrLink(on_not_equal);
299 Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
302 EmitOrLink(on_not_equal);
309 Emit(BC_CHECK_CHAR_IN_RANGE, 0);
312 EmitOrLink(on_in_range);
319 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
322 EmitOrLink(on_not_in_range);
327 Emit(BC_CHECK_BIT_IN_TABLE, 0);
328 EmitOrLink(on_bit_set);
332 if (
table.GetUint8(i + j) != 0)
byte |= 1 << j;
344 Emit(read_backward ? BC_CHECK_NOT_BACK_REF_BACKWARD : BC_CHECK_NOT_BACK_REF,
346 EmitOrLink(on_not_equal);
356 Emit(read_backward ? (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE_BACKWARD
357 : BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD)
358 : (unicode ? BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE
359 : BC_CHECK_NOT_BACK_REF_NO_CASE),
361 EmitOrLink(on_not_equal);
367 ASSERT(register_index >= 0);
369 Emit(BC_CHECK_REGISTER_LT, register_index);
371 EmitOrLink(on_less_than);
375 intptr_t register_index,
378 ASSERT(register_index >= 0);
380 Emit(BC_CHECK_REGISTER_GE, register_index);
382 EmitOrLink(on_greater_or_equal);
387 ASSERT(register_index >= 0);
389 Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
397 intptr_t len = length();
404 return bytecode.
ptr();
407intptr_t BytecodeRegExpMacroAssembler::length() {
411void BytecodeRegExpMacroAssembler::Expand() {
417 intptr_t
x = buffer_->
length();
418 for (intptr_t i = 0; i <
x; i++)
430#if defined(SUPPORT_TIMELINE)
431 TimelineBeginEndScope tbes(
Thread::Current(), Timeline::GetCompilerStream(),
432 "CompileIrregexpBytecode");
433 if (tbes.enabled()) {
434 tbes.SetNumArguments(1);
435 tbes.CopyArgument(0,
"pattern", pattern.
ToCString());
446 if (compile_data->
simple) {
453 compile_data, regexp, is_one_byte, sticky, zone);
454 if (
result.error_message !=
nullptr) {
475 intptr_t output_size,
482 int32_t* raw_output = &output[number_of_capture_registers];
487 for (
int i = number_of_capture_registers - 1; i >= 0; i--) {
499 memmove(output, raw_output, number_of_capture_registers *
sizeof(int32_t));
511 const Smi& start_index,
514 intptr_t required_registers =
Prepare(regexp, subject, sticky,
zone);
515 if (required_registers < 0) {
521 int32_t* output_registers =
zone->
Alloc<int32_t>(required_registers);
525 output_registers, required_registers,
zone));
528 intptr_t capture_register_count = (capture_count + 1) * 2;
529 ASSERT(required_registers >= capture_register_count);
537 for (intptr_t i = 0; i < capture_register_count; i++) {
538 int32_t val = output_registers[i];
539 ASSERT(val == -1 || (val >= 0 && val <= subject.
Length()));
544 memmove(
result.DataAddr(0), output_registers,
545 capture_register_count *
sizeof(int32_t));
void check_bounds(skiatest::Reporter *reporter, const SkPath &path)
Convenience wrapper around a BlockEntryInstr pointer.
void BindTo(intptr_t pos)
void LinkTo(intptr_t pos)
static const Bool & False()
static const Bool & True()
virtual void SetCurrentPositionFromEnd(intptr_t by)
virtual void CheckAtStart(BlockLabel *on_at_start)
virtual void GoTo(BlockLabel *label)
virtual void CheckCharacterInRange(uint16_t from, uint16_t to, BlockLabel *on_in_range)
virtual void CheckBitInTable(const TypedData &table, BlockLabel *on_bit_set)
virtual IrregexpImplementation Implementation()
virtual void CheckCharacterAfterAnd(unsigned c, unsigned mask, BlockLabel *on_equal)
BytecodeRegExpMacroAssembler(ZoneGrowableArray< uint8_t > *buffer, Zone *zone)
virtual void CheckCharacterLT(uint16_t limit, BlockLabel *on_less)
virtual void AdvanceRegister(intptr_t reg, intptr_t by)
virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned mask, BlockLabel *on_not_equal)
virtual ~BytecodeRegExpMacroAssembler()
virtual void ReadCurrentPositionFromRegister(intptr_t reg)
virtual void IfRegisterGE(intptr_t register_index, intptr_t comparand, BlockLabel *if_ge)
virtual void PopRegister(intptr_t register_index)
virtual void CheckNotCharacter(unsigned c, BlockLabel *on_not_equal)
virtual void PopCurrentPosition()
virtual void WriteStackPointerToRegister(intptr_t reg)
virtual void ReadStackPointerFromRegister(intptr_t reg)
virtual void CheckCharacter(unsigned c, BlockLabel *on_equal)
virtual void IfRegisterEqPos(intptr_t register_index, BlockLabel *if_eq)
virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to)
virtual void CheckCharacterNotInRange(uint16_t from, uint16_t to, BlockLabel *on_not_in_range)
virtual void PushBacktrack(BlockLabel *label)
virtual void AdvanceCurrentPosition(intptr_t by)
virtual void LoadCurrentCharacter(intptr_t cp_offset, BlockLabel *on_end_of_input, bool check_bounds=true, intptr_t characters=1)
virtual void WriteCurrentPositionToRegister(intptr_t reg, intptr_t cp_offset)
TypedDataPtr GetBytecode()
virtual void PushRegister(intptr_t register_index)
virtual void BindBlock(BlockLabel *label)
virtual void CheckNotCharacterAfterMinusAnd(uint16_t c, uint16_t minus, uint16_t mask, BlockLabel *on_not_equal)
virtual void PushCurrentPosition()
virtual void IfRegisterLT(intptr_t register_index, intptr_t comparand, BlockLabel *if_lt)
virtual void SetRegister(intptr_t register_index, intptr_t to)
static ObjectPtr Interpret(const RegExp ®exp, const String &str, const Smi &start_index, bool is_sticky, Zone *zone)
virtual void CheckNotAtStart(intptr_t cp_offset, BlockLabel *on_not_at_start)
virtual void CheckGreedyLoop(BlockLabel *on_tos_equals_current_position)
virtual void CheckCharacterGT(uint16_t limit, BlockLabel *on_greater)
virtual void CheckNotBackReference(intptr_t start_reg, bool read_backward, BlockLabel *on_no_match)
virtual void CheckNotBackReferenceIgnoreCase(intptr_t start_reg, bool read_backward, bool unicode, BlockLabel *on_no_match)
static DART_NORETURN void ThrowStackOverflow()
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
static DART_NORETURN void PropagateError(const Error &error)
static ObjectPtr Match(const TypedData &bytecode, const String &subject, int32_t *captures, int32_t start_position)
static CompilationResult CompileBytecode(RegExpCompileData *data, const RegExp ®exp, bool is_one_byte, bool sticky, Zone *zone)
static constexpr intptr_t kMaxRegister
static constexpr intptr_t kMinCPOffset
static constexpr intptr_t kTableSize
@ kBytecodeImplementation
static constexpr intptr_t kMaxCPOffset
static void ParseRegExp(const String &input, RegExpFlags regexp_flags, RegExpCompileData *result)
TypedDataPtr bytecode(bool is_one_byte, bool sticky) const
void set_is_simple() const
StringPtr pattern() const
void set_is_complex() const
void set_num_bracket_expressions(SmiPtr value) const
void set_capture_name_map(const Array &array) const
intptr_t num_bracket_expressions() const
void set_bytecode(bool is_one_byte, bool sticky, const TypedData &bytecode) const
RegExpFlags flags() const
intptr_t num_registers(bool is_one_byte) const
void set_num_registers(bool is_one_byte, intptr_t value) const
bool IsOneByteString() const
static const char * ToCString(Thread *thread, StringPtr ptr)
static Thread * Current()
void * DataAddr(intptr_t byte_offset) const
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
static bool IsUint(intptr_t N, T value)
ElementType * Alloc(intptr_t length)
static const uint8_t buffer[]
constexpr intptr_t kBitsPerByte
static ObjectPtr ExecRaw(const RegExp ®exp, const String &subject, int32_t index, bool sticky, int32_t *output, intptr_t output_size, Zone *zone)
static intptr_t Prepare(const RegExp ®exp, const String &subject, bool sticky, Zone *zone)
const unsigned int MAX_FIRST_ARG