| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 BranchOrBacktrack(not_equal, on_failure); | 282 BranchOrBacktrack(not_equal, on_failure); |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 287 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { |
| 288 Label fallthrough; | 288 Label fallthrough; |
| 289 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 289 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
| 290 __ j(not_equal, &fallthrough, Label::kNear); | 290 __ j(not_equal, &fallthrough); |
| 291 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 291 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
| 292 BranchOrBacktrack(no_condition, on_equal); | 292 BranchOrBacktrack(no_condition, on_equal); |
| 293 __ bind(&fallthrough); | 293 __ bind(&fallthrough); |
| 294 } | 294 } |
| 295 | 295 |
| 296 | 296 |
| 297 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 297 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( |
| 298 int start_reg, | 298 int start_reg, |
| 299 Label* on_no_match) { | 299 Label* on_no_match) { |
| 300 Label fallthrough; | 300 Label fallthrough; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 321 // After this, the eax, ecx, and edi registers are available. | 321 // After this, the eax, ecx, and edi registers are available. |
| 322 | 322 |
| 323 __ add(edx, esi); // Start of capture | 323 __ add(edx, esi); // Start of capture |
| 324 __ add(edi, esi); // Start of text to match against capture. | 324 __ add(edi, esi); // Start of text to match against capture. |
| 325 __ add(ebx, edi); // End of text to match against capture. | 325 __ add(ebx, edi); // End of text to match against capture. |
| 326 | 326 |
| 327 Label loop; | 327 Label loop; |
| 328 __ bind(&loop); | 328 __ bind(&loop); |
| 329 __ movzx_b(eax, Operand(edi, 0)); | 329 __ movzx_b(eax, Operand(edi, 0)); |
| 330 __ cmpb_al(Operand(edx, 0)); | 330 __ cmpb_al(Operand(edx, 0)); |
| 331 __ j(equal, &loop_increment, Label::kNear); | 331 __ j(equal, &loop_increment); |
| 332 | 332 |
| 333 // Mismatch, try case-insensitive match (converting letters to lower-case). | 333 // Mismatch, try case-insensitive match (converting letters to lower-case). |
| 334 __ or_(eax, 0x20); // Convert match character to lower-case. | 334 __ or_(eax, 0x20); // Convert match character to lower-case. |
| 335 __ lea(ecx, Operand(eax, -'a')); | 335 __ lea(ecx, Operand(eax, -'a')); |
| 336 __ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter? | 336 __ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter? |
| 337 __ j(above, &fail, Label::kNear); | 337 __ j(above, &fail); |
| 338 // Also convert capture character. | 338 // Also convert capture character. |
| 339 __ movzx_b(ecx, Operand(edx, 0)); | 339 __ movzx_b(ecx, Operand(edx, 0)); |
| 340 __ or_(ecx, 0x20); | 340 __ or_(ecx, 0x20); |
| 341 | 341 |
| 342 __ cmp(eax, ecx); | 342 __ cmp(eax, ecx); |
| 343 __ j(not_equal, &fail, Label::kNear); | 343 __ j(not_equal, &fail); |
| 344 | 344 |
| 345 __ bind(&loop_increment); | 345 __ bind(&loop_increment); |
| 346 // Increment pointers into match and capture strings. | 346 // Increment pointers into match and capture strings. |
| 347 __ add(edx, Immediate(1)); | 347 __ add(edx, Immediate(1)); |
| 348 __ add(edi, Immediate(1)); | 348 __ add(edi, Immediate(1)); |
| 349 // Compare to end of match, and loop if not done. | 349 // Compare to end of match, and loop if not done. |
| 350 __ cmp(edi, ebx); | 350 __ cmp(edi, ebx); |
| 351 __ j(below, &loop); | 351 __ j(below, &loop); |
| 352 __ jmp(&success, Label::kNear); | 352 __ jmp(&success); |
| 353 | 353 |
| 354 __ bind(&fail); | 354 __ bind(&fail); |
| 355 // Restore original values before failing. | 355 // Restore original values before failing. |
| 356 __ pop(backtrack_stackpointer()); | 356 __ pop(backtrack_stackpointer()); |
| 357 __ pop(edi); | 357 __ pop(edi); |
| 358 BranchOrBacktrack(no_condition, on_no_match); | 358 BranchOrBacktrack(no_condition, on_no_match); |
| 359 | 359 |
| 360 __ bind(&success); | 360 __ bind(&success); |
| 361 // Restore original value before continuing. | 361 // Restore original value before continuing. |
| 362 __ pop(backtrack_stackpointer()); | 362 __ pop(backtrack_stackpointer()); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 Label loop; | 450 Label loop; |
| 451 __ bind(&loop); | 451 __ bind(&loop); |
| 452 if (mode_ == ASCII) { | 452 if (mode_ == ASCII) { |
| 453 __ movzx_b(eax, Operand(edx, 0)); | 453 __ movzx_b(eax, Operand(edx, 0)); |
| 454 __ cmpb_al(Operand(ebx, 0)); | 454 __ cmpb_al(Operand(ebx, 0)); |
| 455 } else { | 455 } else { |
| 456 ASSERT(mode_ == UC16); | 456 ASSERT(mode_ == UC16); |
| 457 __ movzx_w(eax, Operand(edx, 0)); | 457 __ movzx_w(eax, Operand(edx, 0)); |
| 458 __ cmpw_ax(Operand(ebx, 0)); | 458 __ cmpw_ax(Operand(ebx, 0)); |
| 459 } | 459 } |
| 460 __ j(not_equal, &fail, Label::kNear); | 460 __ j(not_equal, &fail); |
| 461 // Increment pointers into capture and match string. | 461 // Increment pointers into capture and match string. |
| 462 __ add(edx, Immediate(char_size())); | 462 __ add(edx, Immediate(char_size())); |
| 463 __ add(ebx, Immediate(char_size())); | 463 __ add(ebx, Immediate(char_size())); |
| 464 // Check if we have reached end of match area. | 464 // Check if we have reached end of match area. |
| 465 __ cmp(ebx, ecx); | 465 __ cmp(ebx, ecx); |
| 466 __ j(below, &loop); | 466 __ j(below, &loop); |
| 467 __ jmp(&success, Label::kNear); | 467 __ jmp(&success); |
| 468 | 468 |
| 469 __ bind(&fail); | 469 __ bind(&fail); |
| 470 // Restore backtrack stackpointer. | 470 // Restore backtrack stackpointer. |
| 471 __ pop(backtrack_stackpointer()); | 471 __ pop(backtrack_stackpointer()); |
| 472 BranchOrBacktrack(no_condition, on_no_match); | 472 BranchOrBacktrack(no_condition, on_no_match); |
| 473 | 473 |
| 474 __ bind(&success); | 474 __ bind(&success); |
| 475 // Move current character position to position after match. | 475 // Move current character position to position after match. |
| 476 __ mov(edi, ecx); | 476 __ mov(edi, ecx); |
| 477 __ sub(edi, esi); | 477 __ sub(edi, esi); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 Label* on_no_match) { | 535 Label* on_no_match) { |
| 536 // Range checks (c in min..max) are generally implemented by an unsigned | 536 // Range checks (c in min..max) are generally implemented by an unsigned |
| 537 // (c - min) <= (max - min) check | 537 // (c - min) <= (max - min) check |
| 538 switch (type) { | 538 switch (type) { |
| 539 case 's': | 539 case 's': |
| 540 // Match space-characters | 540 // Match space-characters |
| 541 if (mode_ == ASCII) { | 541 if (mode_ == ASCII) { |
| 542 // ASCII space characters are '\t'..'\r' and ' '. | 542 // ASCII space characters are '\t'..'\r' and ' '. |
| 543 Label success; | 543 Label success; |
| 544 __ cmp(current_character(), ' '); | 544 __ cmp(current_character(), ' '); |
| 545 __ j(equal, &success, Label::kNear); | 545 __ j(equal, &success); |
| 546 // Check range 0x09..0x0d | 546 // Check range 0x09..0x0d |
| 547 __ lea(eax, Operand(current_character(), -'\t')); | 547 __ lea(eax, Operand(current_character(), -'\t')); |
| 548 __ cmp(eax, '\r' - '\t'); | 548 __ cmp(eax, '\r' - '\t'); |
| 549 BranchOrBacktrack(above, on_no_match); | 549 BranchOrBacktrack(above, on_no_match); |
| 550 __ bind(&success); | 550 __ bind(&success); |
| 551 return true; | 551 return true; |
| 552 } | 552 } |
| 553 return false; | 553 return false; |
| 554 case 'S': | 554 case 'S': |
| 555 // Match non-space characters. | 555 // Match non-space characters. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 __ test_b(current_character(), | 604 __ test_b(current_character(), |
| 605 Operand::StaticArray(current_character(), times_1, word_map)); | 605 Operand::StaticArray(current_character(), times_1, word_map)); |
| 606 BranchOrBacktrack(zero, on_no_match); | 606 BranchOrBacktrack(zero, on_no_match); |
| 607 return true; | 607 return true; |
| 608 } | 608 } |
| 609 case 'W': { | 609 case 'W': { |
| 610 Label done; | 610 Label done; |
| 611 if (mode_ != ASCII) { | 611 if (mode_ != ASCII) { |
| 612 // Table is 128 entries, so all ASCII characters can be tested. | 612 // Table is 128 entries, so all ASCII characters can be tested. |
| 613 __ cmp(current_character(), Immediate('z')); | 613 __ cmp(current_character(), Immediate('z')); |
| 614 __ j(above, &done, Label::kNear); | 614 __ j(above, &done); |
| 615 } | 615 } |
| 616 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 616 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
| 617 ExternalReference word_map = ExternalReference::re_word_character_map(); | 617 ExternalReference word_map = ExternalReference::re_word_character_map(); |
| 618 __ test_b(current_character(), | 618 __ test_b(current_character(), |
| 619 Operand::StaticArray(current_character(), times_1, word_map)); | 619 Operand::StaticArray(current_character(), times_1, word_map)); |
| 620 BranchOrBacktrack(not_zero, on_no_match); | 620 BranchOrBacktrack(not_zero, on_no_match); |
| 621 if (mode_ != ASCII) { | 621 if (mode_ != ASCII) { |
| 622 __ bind(&done); | 622 __ bind(&done); |
| 623 } | 623 } |
| 624 return true; | 624 return true; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 | 688 |
| 689 // Check if we have space on the stack for registers. | 689 // Check if we have space on the stack for registers. |
| 690 Label stack_limit_hit; | 690 Label stack_limit_hit; |
| 691 Label stack_ok; | 691 Label stack_ok; |
| 692 | 692 |
| 693 ExternalReference stack_limit = | 693 ExternalReference stack_limit = |
| 694 ExternalReference::address_of_stack_limit(masm_->isolate()); | 694 ExternalReference::address_of_stack_limit(masm_->isolate()); |
| 695 __ mov(ecx, esp); | 695 __ mov(ecx, esp); |
| 696 __ sub(ecx, Operand::StaticVariable(stack_limit)); | 696 __ sub(ecx, Operand::StaticVariable(stack_limit)); |
| 697 // Handle it if the stack pointer is already below the stack limit. | 697 // Handle it if the stack pointer is already below the stack limit. |
| 698 __ j(below_equal, &stack_limit_hit, Label::kNear); | 698 __ j(below_equal, &stack_limit_hit); |
| 699 // Check if there is room for the variable number of registers above | 699 // Check if there is room for the variable number of registers above |
| 700 // the stack limit. | 700 // the stack limit. |
| 701 __ cmp(ecx, num_registers_ * kPointerSize); | 701 __ cmp(ecx, num_registers_ * kPointerSize); |
| 702 __ j(above_equal, &stack_ok, Label::kNear); | 702 __ j(above_equal, &stack_ok); |
| 703 // Exit with OutOfMemory exception. There is not enough space on the stack | 703 // Exit with OutOfMemory exception. There is not enough space on the stack |
| 704 // for our working registers. | 704 // for our working registers. |
| 705 __ mov(eax, EXCEPTION); | 705 __ mov(eax, EXCEPTION); |
| 706 __ jmp(&exit_label_); | 706 __ jmp(&exit_label_); |
| 707 | 707 |
| 708 __ bind(&stack_limit_hit); | 708 __ bind(&stack_limit_hit); |
| 709 CallCheckStackGuardState(ebx); | 709 CallCheckStackGuardState(ebx); |
| 710 __ or_(eax, eax); | 710 __ or_(eax, eax); |
| 711 // If returned value is non-zero, we exit with the returned value as result. | 711 // If returned value is non-zero, we exit with the returned value as result. |
| 712 __ j(not_zero, &exit_label_); | 712 __ j(not_zero, &exit_label_); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 i += kRegistersPerPage) { | 757 i += kRegistersPerPage) { |
| 758 __ mov(register_location(i), eax); // One write every page. | 758 __ mov(register_location(i), eax); // One write every page. |
| 759 } | 759 } |
| 760 | 760 |
| 761 | 761 |
| 762 // Initialize backtrack stack pointer. | 762 // Initialize backtrack stack pointer. |
| 763 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); | 763 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); |
| 764 // Load previous char as initial value of current-character. | 764 // Load previous char as initial value of current-character. |
| 765 Label at_start; | 765 Label at_start; |
| 766 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 766 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
| 767 __ j(equal, &at_start, Label::kNear); | 767 __ j(equal, &at_start); |
| 768 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. | 768 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. |
| 769 __ jmp(&start_label_); | 769 __ jmp(&start_label_); |
| 770 __ bind(&at_start); | 770 __ bind(&at_start); |
| 771 __ mov(current_character(), '\n'); | 771 __ mov(current_character(), '\n'); |
| 772 __ jmp(&start_label_); | 772 __ jmp(&start_label_); |
| 773 | 773 |
| 774 | 774 |
| 775 // Exit code: | 775 // Exit code: |
| 776 if (success_label_.is_linked()) { | 776 if (success_label_.is_linked()) { |
| 777 // Save captures when successful. | 777 // Save captures when successful. |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); | 1228 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 | 1231 |
| 1232 void RegExpMacroAssemblerIA32::CheckPreemption() { | 1232 void RegExpMacroAssemblerIA32::CheckPreemption() { |
| 1233 // Check for preemption. | 1233 // Check for preemption. |
| 1234 Label no_preempt; | 1234 Label no_preempt; |
| 1235 ExternalReference stack_limit = | 1235 ExternalReference stack_limit = |
| 1236 ExternalReference::address_of_stack_limit(masm_->isolate()); | 1236 ExternalReference::address_of_stack_limit(masm_->isolate()); |
| 1237 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 1237 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
| 1238 __ j(above, &no_preempt, Label::kNear); | 1238 __ j(above, &no_preempt); |
| 1239 | 1239 |
| 1240 SafeCall(&check_preempt_label_); | 1240 SafeCall(&check_preempt_label_); |
| 1241 | 1241 |
| 1242 __ bind(&no_preempt); | 1242 __ bind(&no_preempt); |
| 1243 } | 1243 } |
| 1244 | 1244 |
| 1245 | 1245 |
| 1246 void RegExpMacroAssemblerIA32::CheckStackLimit() { | 1246 void RegExpMacroAssemblerIA32::CheckStackLimit() { |
| 1247 Label no_stack_overflow; | 1247 Label no_stack_overflow; |
| 1248 ExternalReference stack_limit = | 1248 ExternalReference stack_limit = |
| 1249 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); | 1249 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); |
| 1250 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); | 1250 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); |
| 1251 __ j(above, &no_stack_overflow, Label::kNear); | 1251 __ j(above, &no_stack_overflow); |
| 1252 | 1252 |
| 1253 SafeCall(&stack_overflow_label_); | 1253 SafeCall(&stack_overflow_label_); |
| 1254 | 1254 |
| 1255 __ bind(&no_stack_overflow); | 1255 __ bind(&no_stack_overflow); |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 | 1258 |
| 1259 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1259 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
| 1260 int characters) { | 1260 int characters) { |
| 1261 if (mode_ == ASCII) { | 1261 if (mode_ == ASCII) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 | 1283 |
| 1284 #undef __ | 1284 #undef __ |
| 1285 | 1285 |
| 1286 #endif // V8_INTERPRETED_REGEXP | 1286 #endif // V8_INTERPRETED_REGEXP |
| 1287 | 1287 |
| 1288 }} // namespace v8::internal | 1288 }} // namespace v8::internal |
| 1289 | 1289 |
| 1290 #endif // V8_TARGET_ARCH_IA32 | 1290 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |