5 #if V8_TARGET_ARCH_IA32 7 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" 9 #include "src/assembler-inl.h" 11 #include "src/macro-assembler.h" 12 #include "src/objects-inl.h" 13 #include "src/regexp/regexp-macro-assembler.h" 14 #include "src/regexp/regexp-stack.h" 20 #ifndef V8_INTERPRETED_REGEXP 80 #define __ ACCESS_MASM(masm_) 82 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(Isolate* isolate, Zone* zone,
84 int registers_to_save)
85 : NativeRegExpMacroAssembler(isolate, zone),
86 masm_(new MacroAssembler(isolate, nullptr, kRegExpCodeSize,
87 CodeObjectRequired::kYes)),
89 num_registers_(registers_to_save),
90 num_saved_registers_(registers_to_save),
97 masm_->set_root_array_available(
false);
99 DCHECK_EQ(0, registers_to_save % 2);
100 __ jmp(&entry_label_);
101 __ bind(&start_label_);
105 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() {
108 entry_label_.Unuse();
109 start_label_.Unuse();
110 success_label_.Unuse();
111 backtrack_label_.Unuse();
113 check_preempt_label_.Unuse();
114 stack_overflow_label_.Unuse();
118 int RegExpMacroAssemblerIA32::stack_limit_slack() {
119 return RegExpStack::kStackLimitSlack;
123 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(
int by) {
125 __ add(edi, Immediate(by * char_size()));
130 void RegExpMacroAssemblerIA32::AdvanceRegister(
int reg,
int by) {
132 DCHECK_GT(num_registers_, reg);
134 __ add(register_location(reg), Immediate(by));
139 void RegExpMacroAssemblerIA32::Backtrack() {
143 __ add(ebx, Immediate(masm_->CodeObject()));
148 void RegExpMacroAssemblerIA32::Bind(Label* label) {
153 void RegExpMacroAssemblerIA32::CheckCharacter(
uint32_t c, Label* on_equal) {
154 __ cmp(current_character(), c);
155 BranchOrBacktrack(equal, on_equal);
159 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) {
160 __ cmp(current_character(), limit);
161 BranchOrBacktrack(greater, on_greater);
165 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) {
166 __ lea(eax, Operand(edi, -char_size()));
167 __ cmp(eax, Operand(ebp, kStringStartMinusOne));
168 BranchOrBacktrack(equal, on_at_start);
172 void RegExpMacroAssemblerIA32::CheckNotAtStart(
int cp_offset,
173 Label* on_not_at_start) {
174 __ lea(eax, Operand(edi, -char_size() + cp_offset * char_size()));
175 __ cmp(eax, Operand(ebp, kStringStartMinusOne));
176 BranchOrBacktrack(not_equal, on_not_at_start);
180 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) {
181 __ cmp(current_character(), limit);
182 BranchOrBacktrack(less, on_less);
186 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) {
188 __ cmp(edi, Operand(backtrack_stackpointer(), 0));
189 __ j(not_equal, &fallthrough);
190 __ add(backtrack_stackpointer(), Immediate(kPointerSize));
191 BranchOrBacktrack(no_condition, on_equal);
192 __ bind(&fallthrough);
196 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
197 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
199 __ mov(edx, register_location(start_reg));
200 __ mov(ebx, register_location(start_reg + 1));
206 __ j(equal, &fallthrough);
210 __ mov(eax, Operand(ebp, kStringStartMinusOne));
213 BranchOrBacktrack(less_equal, on_no_match);
217 BranchOrBacktrack(greater, on_no_match);
220 if (mode_ == LATIN1) {
223 Label loop_increment;
226 __ push(backtrack_stackpointer());
238 __ movzx_b(eax, Operand(edi, 0));
239 __ cmpb_al(Operand(edx, 0));
240 __ j(equal, &loop_increment);
244 __ lea(ecx, Operand(eax, -
'a'));
245 __ cmp(ecx, static_cast<int32_t>(
'z' -
'a'));
246 Label convert_capture;
247 __ j(below_equal, &convert_capture);
249 __ sub(ecx, Immediate(224 -
'a'));
250 __ cmp(ecx, Immediate(254 - 224));
252 __ cmp(ecx, Immediate(247 - 224));
254 __ bind(&convert_capture);
256 __ movzx_b(ecx, Operand(edx, 0));
260 __ j(not_equal, &fail);
262 __ bind(&loop_increment);
264 __ add(edx, Immediate(1));
265 __ add(edi, Immediate(1));
273 __ pop(backtrack_stackpointer());
275 BranchOrBacktrack(no_condition, on_no_match);
279 __ pop(backtrack_stackpointer());
281 __ add(esp, Immediate(kPointerSize));
286 __ add(edi, register_location(start_reg));
287 __ sub(edi, register_location(start_reg + 1));
290 DCHECK(mode_ == UC16);
294 __ push(backtrack_stackpointer());
297 static const int argument_count = 4;
298 __ PrepareCallCFunction(argument_count, ecx);
307 #ifdef V8_INTL_SUPPORT 309 __ mov(Operand(esp, 3 * kPointerSize), Immediate(0));
311 #endif // V8_INTL_SUPPORT 313 __ mov(Operand(esp, 3 * kPointerSize),
314 Immediate(ExternalReference::isolate_address(isolate())));
317 __ mov(Operand(esp, 2 * kPointerSize), ebx);
325 __ mov(Operand(esp, 1 * kPointerSize), edi);
329 __ mov(Operand(esp, 0 * kPointerSize), edx);
332 AllowExternalCallThatCantCauseGC scope(masm_);
333 ExternalReference compare =
334 ExternalReference::re_case_insensitive_compare_uc16(isolate());
335 __ CallCFunction(compare, argument_count);
339 __ pop(backtrack_stackpointer());
345 BranchOrBacktrack(zero, on_no_match);
353 __ bind(&fallthrough);
357 void RegExpMacroAssemblerIA32::CheckNotBackReference(
int start_reg,
359 Label* on_no_match) {
365 __ mov(edx, register_location(start_reg));
366 __ mov(eax, register_location(start_reg + 1));
372 __ j(equal, &fallthrough);
376 __ mov(ebx, Operand(ebp, kStringStartMinusOne));
379 BranchOrBacktrack(less_equal, on_no_match);
383 BranchOrBacktrack(greater, on_no_match);
387 __ push(backtrack_stackpointer());
391 __ lea(ebx, Operand(esi, edi, times_1, 0));
395 __ lea(ecx, Operand(eax, ebx, times_1, 0));
399 if (mode_ == LATIN1) {
400 __ movzx_b(eax, Operand(edx, 0));
401 __ cmpb_al(Operand(ebx, 0));
403 DCHECK(mode_ == UC16);
404 __ movzx_w(eax, Operand(edx, 0));
405 __ cmpw_ax(Operand(ebx, 0));
407 __ j(not_equal, &fail);
409 __ add(edx, Immediate(char_size()));
410 __ add(ebx, Immediate(char_size()));
418 __ pop(backtrack_stackpointer());
419 BranchOrBacktrack(no_condition, on_no_match);
427 __ add(edi, register_location(start_reg));
428 __ sub(edi, register_location(start_reg + 1));
431 __ pop(backtrack_stackpointer());
433 __ bind(&fallthrough);
437 void RegExpMacroAssemblerIA32::CheckNotCharacter(
uint32_t c,
438 Label* on_not_equal) {
439 __ cmp(current_character(), c);
440 BranchOrBacktrack(not_equal, on_not_equal);
444 void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(
uint32_t c,
448 __ test(current_character(), Immediate(mask));
451 __ and_(eax, current_character());
454 BranchOrBacktrack(equal, on_equal);
458 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(
uint32_t c,
460 Label* on_not_equal) {
462 __ test(current_character(), Immediate(mask));
465 __ and_(eax, current_character());
468 BranchOrBacktrack(not_equal, on_not_equal);
472 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd(
476 Label* on_not_equal) {
477 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
478 __ lea(eax, Operand(current_character(), -minus));
480 __ test(eax, Immediate(mask));
485 BranchOrBacktrack(not_equal, on_not_equal);
489 void RegExpMacroAssemblerIA32::CheckCharacterInRange(
492 Label* on_in_range) {
493 __ lea(eax, Operand(current_character(), -from));
494 __ cmp(eax, to - from);
495 BranchOrBacktrack(below_equal, on_in_range);
499 void RegExpMacroAssemblerIA32::CheckCharacterNotInRange(
502 Label* on_not_in_range) {
503 __ lea(eax, Operand(current_character(), -from));
504 __ cmp(eax, to - from);
505 BranchOrBacktrack(above, on_not_in_range);
509 void RegExpMacroAssemblerIA32::CheckBitInTable(
510 Handle<ByteArray> table,
512 __ mov(eax, Immediate(table));
513 Register index = current_character();
514 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
515 __ mov(ebx, kTableSize - 1);
516 __ and_(ebx, current_character());
519 __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize),
521 BranchOrBacktrack(not_equal, on_bit_set);
525 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type,
526 Label* on_no_match) {
532 if (mode_ == LATIN1) {
535 __ cmp(current_character(),
' ');
536 __ j(equal, &success, Label::kNear);
538 __ lea(eax, Operand(current_character(), -
'\t'));
539 __ cmp(eax,
'\r' -
'\t');
540 __ j(below_equal, &success, Label::kNear);
542 __ cmp(eax, 0x00A0 -
'\t');
543 BranchOrBacktrack(not_equal, on_no_match);
553 __ lea(eax, Operand(current_character(), -
'0'));
554 __ cmp(eax,
'9' -
'0');
555 BranchOrBacktrack(above, on_no_match);
559 __ lea(eax, Operand(current_character(), -
'0'));
560 __ cmp(eax,
'9' -
'0');
561 BranchOrBacktrack(below_equal, on_no_match);
565 __ mov(eax, current_character());
566 __ xor_(eax, Immediate(0x01));
568 __ sub(eax, Immediate(0x0B));
569 __ cmp(eax, 0x0C - 0x0B);
570 BranchOrBacktrack(below_equal, on_no_match);
575 __ sub(eax, Immediate(0x2028 - 0x0B));
576 __ cmp(eax, 0x2029 - 0x2028);
577 BranchOrBacktrack(below_equal, on_no_match);
582 if (mode_ != LATIN1) {
584 __ cmp(current_character(), Immediate(
'z'));
585 BranchOrBacktrack(above, on_no_match);
587 DCHECK_EQ(0, word_character_map[0]);
588 ExternalReference word_map =
589 ExternalReference::re_word_character_map(isolate());
590 __ test_b(current_character(),
591 Operand(current_character(), times_1, word_map.address(),
592 RelocInfo::EXTERNAL_REFERENCE));
593 BranchOrBacktrack(zero, on_no_match);
598 if (mode_ != LATIN1) {
600 __ cmp(current_character(), Immediate(
'z'));
603 DCHECK_EQ(0, word_character_map[0]);
604 ExternalReference word_map =
605 ExternalReference::re_word_character_map(isolate());
606 __ test_b(current_character(),
607 Operand(current_character(), times_1, word_map.address(),
608 RelocInfo::EXTERNAL_REFERENCE));
609 BranchOrBacktrack(not_zero, on_no_match);
610 if (mode_ != LATIN1) {
622 __ mov(eax, current_character());
623 __ xor_(eax, Immediate(0x01));
625 __ sub(eax, Immediate(0x0B));
626 __ cmp(eax, 0x0C - 0x0B);
627 if (mode_ == LATIN1) {
628 BranchOrBacktrack(above, on_no_match);
631 BranchOrBacktrack(below_equal, &done);
632 DCHECK_EQ(UC16, mode_);
636 __ sub(eax, Immediate(0x2028 - 0x0B));
638 BranchOrBacktrack(above, on_no_match);
650 void RegExpMacroAssemblerIA32::Fail() {
651 STATIC_ASSERT(FAILURE == 0);
653 __ Move(eax, Immediate(FAILURE));
655 __ jmp(&exit_label_);
659 Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
665 __ bind(&entry_label_);
669 FrameScope scope(masm_, StackFrame::MANUAL);
679 __ push(Immediate(0));
680 __ push(Immediate(0));
683 Label stack_limit_hit;
686 ExternalReference stack_limit =
687 ExternalReference::address_of_stack_limit(isolate());
689 __ sub(ecx, StaticVariable(stack_limit));
691 __ j(below_equal, &stack_limit_hit);
694 __ cmp(ecx, num_registers_ * kPointerSize);
695 __ j(above_equal, &stack_ok);
698 __ mov(eax, EXCEPTION);
701 __ bind(&stack_limit_hit);
702 CallCheckStackGuardState(ebx);
705 __ j(not_zero, &return_eax);
709 __ mov(ebx, Operand(ebp, kStartIndex));
712 __ sub(esp, Immediate(num_registers_ * kPointerSize));
714 __ mov(esi, Operand(ebp, kInputEnd));
716 __ mov(edi, Operand(ebp, kInputStart));
724 __ lea(eax, Operand(edi, ebx, times_2, -char_size()));
726 __ lea(eax, Operand(edi, ebx, times_1, -char_size()));
730 __ mov(Operand(ebp, kStringStartMinusOne), eax);
735 const int kPageSize = 4096;
736 const int kRegistersPerPage = kPageSize / kPointerSize;
737 for (
int i = num_saved_registers_ + kRegistersPerPage - 1;
739 i += kRegistersPerPage) {
740 __ mov(register_location(
i), eax);
744 Label load_char_start_regexp, start_regexp;
746 __ cmp(Operand(ebp, kStartIndex), Immediate(0));
747 __ j(not_equal, &load_char_start_regexp, Label::kNear);
748 __ mov(current_character(),
'\n');
749 __ jmp(&start_regexp, Label::kNear);
752 __ bind(&load_char_start_regexp);
754 LoadCurrentCharacterUnchecked(-1, 1);
755 __ bind(&start_regexp);
758 if (num_saved_registers_ > 0) {
762 if (num_saved_registers_ > 8) {
763 __ mov(ecx, kRegisterZero);
766 __ mov(Operand(ebp, ecx, times_1, 0), eax);
767 __ sub(ecx, Immediate(kPointerSize));
768 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
769 __ j(greater, &init_loop);
771 for (
int i = 0;
i < num_saved_registers_;
i++) {
772 __ mov(register_location(
i), eax);
778 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
780 __ jmp(&start_label_);
783 if (success_label_.is_linked()) {
785 __ bind(&success_label_);
786 if (num_saved_registers_ > 0) {
788 __ mov(ebx, Operand(ebp, kRegisterOutput));
789 __ mov(ecx, Operand(ebp, kInputEnd));
790 __ mov(edx, Operand(ebp, kStartIndex));
791 __ sub(ecx, Operand(ebp, kInputStart));
793 __ lea(ecx, Operand(ecx, edx, times_2, 0));
797 for (
int i = 0;
i < num_saved_registers_;
i++) {
798 __ mov(eax, register_location(
i));
799 if (
i == 0 && global_with_zero_length_check()) {
808 __ mov(Operand(ebx,
i * kPointerSize), eax);
815 __ inc(Operand(ebp, kSuccessfulCaptures));
818 __ mov(ecx, Operand(ebp, kNumOutputRegisters));
819 __ sub(ecx, Immediate(num_saved_registers_));
821 __ cmp(ecx, Immediate(num_saved_registers_));
822 __ j(less, &exit_label_);
824 __ mov(Operand(ebp, kNumOutputRegisters), ecx);
826 __ add(Operand(ebp, kRegisterOutput),
827 Immediate(num_saved_registers_ * kPointerSize));
830 __ mov(eax, Operand(ebp, kStringStartMinusOne));
832 if (global_with_zero_length_check()) {
837 __ j(not_equal, &load_char_start_regexp);
840 __ j(zero, &exit_label_, Label::kNear);
845 __ add(edi, Immediate(2));
849 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
851 __ jmp(&load_char_start_regexp);
853 __ mov(eax, Immediate(SUCCESS));
857 __ bind(&exit_label_);
860 __ mov(eax, Operand(ebp, kSuccessfulCaptures));
863 __ bind(&return_eax);
865 __ lea(esp, Operand(ebp, kBackup_ebx));
875 if (backtrack_label_.is_linked()) {
876 __ bind(&backtrack_label_);
880 Label exit_with_exception;
883 if (check_preempt_label_.is_linked()) {
884 SafeCallTarget(&check_preempt_label_);
886 __ push(backtrack_stackpointer());
889 CallCheckStackGuardState(ebx);
893 __ j(not_zero, &return_eax);
896 __ pop(backtrack_stackpointer());
898 __ mov(esi, Operand(ebp, kInputEnd));
903 if (stack_overflow_label_.is_linked()) {
904 SafeCallTarget(&stack_overflow_label_);
913 static const int num_arguments = 3;
914 __ PrepareCallCFunction(num_arguments, ebx);
915 __ mov(Operand(esp, 2 * kPointerSize),
916 Immediate(ExternalReference::isolate_address(isolate())));
917 __ lea(eax, Operand(ebp, kStackHighEnd));
918 __ mov(Operand(esp, 1 * kPointerSize), eax);
919 __ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer());
920 ExternalReference grow_stack =
921 ExternalReference::re_grow_stack(isolate());
922 __ CallCFunction(grow_stack, num_arguments);
926 __ j(equal, &exit_with_exception);
928 __ mov(backtrack_stackpointer(), eax);
935 if (exit_with_exception.is_linked()) {
937 __ bind(&exit_with_exception);
939 __ mov(eax, EXCEPTION);
944 masm_->GetCode(masm_->isolate(), &code_desc);
945 Handle<Code> code = isolate()->factory()->NewCode(code_desc, Code::REGEXP,
946 masm_->CodeObject());
947 PROFILE(masm_->isolate(),
948 RegExpCodeCreateEvent(AbstractCode::cast(*code), *source));
949 return Handle<HeapObject>::cast(code);
953 void RegExpMacroAssemblerIA32::GoTo(Label* to) {
954 BranchOrBacktrack(no_condition, to);
958 void RegExpMacroAssemblerIA32::IfRegisterGE(
int reg,
961 __ cmp(register_location(reg), Immediate(comparand));
962 BranchOrBacktrack(greater_equal, if_ge);
966 void RegExpMacroAssemblerIA32::IfRegisterLT(
int reg,
969 __ cmp(register_location(reg), Immediate(comparand));
970 BranchOrBacktrack(less, if_lt);
974 void RegExpMacroAssemblerIA32::IfRegisterEqPos(
int reg,
976 __ cmp(edi, register_location(reg));
977 BranchOrBacktrack(equal, if_eq);
981 RegExpMacroAssembler::IrregexpImplementation
982 RegExpMacroAssemblerIA32::Implementation() {
983 return kIA32Implementation;
987 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(
int cp_offset,
988 Label* on_end_of_input,
991 DCHECK(cp_offset < (1<<30));
993 if (cp_offset >= 0) {
994 CheckPosition(cp_offset + characters - 1, on_end_of_input);
996 CheckPosition(cp_offset, on_end_of_input);
999 LoadCurrentCharacterUnchecked(cp_offset, characters);
1003 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
1008 void RegExpMacroAssemblerIA32::PopRegister(
int register_index) {
1010 __ mov(register_location(register_index), eax);
1014 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
1015 Push(Immediate::CodeRelativeOffset(label));
1020 void RegExpMacroAssemblerIA32::PushCurrentPosition() {
1025 void RegExpMacroAssemblerIA32::PushRegister(
int register_index,
1026 StackCheckFlag check_stack_limit) {
1027 __ mov(eax, register_location(register_index));
1029 if (check_stack_limit) CheckStackLimit();
1033 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(
int reg) {
1034 __ mov(edi, register_location(reg));
1038 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(
int reg) {
1039 __ mov(backtrack_stackpointer(), register_location(reg));
1040 __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
1043 void RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(
int by) {
1044 Label after_position;
1045 __ cmp(edi, -by * char_size());
1046 __ j(greater_equal, &after_position, Label::kNear);
1047 __ mov(edi, -by * char_size());
1051 LoadCurrentCharacterUnchecked(-1, 1);
1052 __ bind(&after_position);
1056 void RegExpMacroAssemblerIA32::SetRegister(
int register_index,
int to) {
1057 DCHECK(register_index >= num_saved_registers_);
1058 __ mov(register_location(register_index), Immediate(to));
1062 bool RegExpMacroAssemblerIA32::Succeed() {
1063 __ jmp(&success_label_);
1068 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(
int reg,
1070 if (cp_offset == 0) {
1071 __ mov(register_location(reg), edi);
1073 __ lea(eax, Operand(edi, cp_offset * char_size()));
1074 __ mov(register_location(reg), eax);
1079 void RegExpMacroAssemblerIA32::ClearRegisters(
int reg_from,
int reg_to) {
1080 DCHECK(reg_from <= reg_to);
1081 __ mov(eax, Operand(ebp, kStringStartMinusOne));
1082 for (
int reg = reg_from; reg <= reg_to; reg++) {
1083 __ mov(register_location(reg), eax);
1088 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(
int reg) {
1089 __ mov(eax, backtrack_stackpointer());
1090 __ sub(eax, Operand(ebp, kStackHighEnd));
1091 __ mov(register_location(reg), eax);
1097 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
1098 static const int num_arguments = 3;
1099 __ PrepareCallCFunction(num_arguments, scratch);
1101 __ mov(Operand(esp, 2 * kPointerSize), ebp);
1103 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
1105 __ lea(eax, Operand(esp, -kPointerSize));
1106 __ mov(Operand(esp, 0 * kPointerSize), eax);
1107 ExternalReference check_stack_guard =
1108 ExternalReference::re_check_stack_guard_state(isolate());
1109 __ CallCFunction(check_stack_guard, num_arguments);
1112 Operand RegExpMacroAssemblerIA32::StaticVariable(
const ExternalReference& ext) {
1113 return Operand(ext.address(), RelocInfo::EXTERNAL_REFERENCE);
1117 template <
typename T>
1118 static T& frame_entry(Address re_frame,
int frame_offset) {
1119 return reinterpret_cast<T&
>(Memory<int32_t>(re_frame + frame_offset));
1123 template <
typename T>
1124 static T* frame_entry_address(Address re_frame,
int frame_offset) {
1125 return reinterpret_cast<T*
>(re_frame + frame_offset);
1128 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
1131 Code re_code = Code::cast(ObjectPtr(raw_code));
1132 return NativeRegExpMacroAssembler::CheckStackGuardState(
1133 frame_entry<Isolate*>(re_frame, kIsolate),
1134 frame_entry<int>(re_frame, kStartIndex),
1135 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code,
1136 frame_entry_address<Address>(re_frame, kInputString),
1137 frame_entry_address<const byte*>(re_frame, kInputStart),
1138 frame_entry_address<const byte*>(re_frame, kInputEnd));
1142 Operand RegExpMacroAssemblerIA32::register_location(
int register_index) {
1143 DCHECK(register_index < (1<<30));
1144 if (num_registers_ <= register_index) {
1145 num_registers_ = register_index + 1;
1147 return Operand(ebp, kRegisterZero - register_index * kPointerSize);
1151 void RegExpMacroAssemblerIA32::CheckPosition(
int cp_offset,
1152 Label* on_outside_input) {
1153 if (cp_offset >= 0) {
1154 __ cmp(edi, -cp_offset * char_size());
1155 BranchOrBacktrack(greater_equal, on_outside_input);
1157 __ lea(eax, Operand(edi, cp_offset * char_size()));
1158 __ cmp(eax, Operand(ebp, kStringStartMinusOne));
1159 BranchOrBacktrack(less_equal, on_outside_input);
1164 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
1166 if (condition < 0) {
1167 if (to ==
nullptr) {
1174 if (to ==
nullptr) {
1175 __ j(condition, &backtrack_label_);
1178 __ j(condition, to);
1182 void RegExpMacroAssemblerIA32::SafeCall(Label* to) {
1184 __ push(Immediate::CodeRelativeOffset(&return_to));
1186 __ bind(&return_to);
1190 void RegExpMacroAssemblerIA32::SafeReturn() {
1192 __ add(ebx, Immediate(masm_->CodeObject()));
1197 void RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) {
1202 void RegExpMacroAssemblerIA32::Push(Register source) {
1203 DCHECK(source != backtrack_stackpointer());
1205 __ sub(backtrack_stackpointer(), Immediate(kPointerSize));
1206 __ mov(Operand(backtrack_stackpointer(), 0), source);
1210 void RegExpMacroAssemblerIA32::Push(Immediate value) {
1212 __ sub(backtrack_stackpointer(), Immediate(kPointerSize));
1213 __ mov(Operand(backtrack_stackpointer(), 0), value);
1217 void RegExpMacroAssemblerIA32::Pop(Register target) {
1218 DCHECK(target != backtrack_stackpointer());
1219 __ mov(target, Operand(backtrack_stackpointer(), 0));
1221 __ add(backtrack_stackpointer(), Immediate(kPointerSize));
1225 void RegExpMacroAssemblerIA32::CheckPreemption() {
1228 ExternalReference stack_limit =
1229 ExternalReference::address_of_stack_limit(isolate());
1230 __ cmp(esp, StaticVariable(stack_limit));
1231 __ j(above, &no_preempt);
1233 SafeCall(&check_preempt_label_);
1235 __ bind(&no_preempt);
1239 void RegExpMacroAssemblerIA32::CheckStackLimit() {
1240 Label no_stack_overflow;
1241 ExternalReference stack_limit =
1242 ExternalReference::address_of_regexp_stack_limit(isolate());
1243 __ cmp(backtrack_stackpointer(), StaticVariable(stack_limit));
1244 __ j(above, &no_stack_overflow);
1246 SafeCall(&stack_overflow_label_);
1248 __ bind(&no_stack_overflow);
1252 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(
int cp_offset,
1254 if (mode_ == LATIN1) {
1255 if (characters == 4) {
1256 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset));
1257 }
else if (characters == 2) {
1258 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset));
1260 DCHECK_EQ(1, characters);
1261 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset));
1264 DCHECK(mode_ == UC16);
1265 if (characters == 2) {
1266 __ mov(current_character(),
1267 Operand(esi, edi, times_1, cp_offset *
sizeof(uc16)));
1269 DCHECK_EQ(1, characters);
1270 __ movzx_w(current_character(),
1271 Operand(esi, edi, times_1, cp_offset *
sizeof(uc16)));
1279 #endif // V8_INTERPRETED_REGEXP 1284 #endif // V8_TARGET_ARCH_IA32