OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
(...skipping 5116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5127 __ bind(¬_a_flat_string); | 5127 __ bind(¬_a_flat_string); |
5128 __ and_(temp.reg(), kStringRepresentationMask); | 5128 __ and_(temp.reg(), kStringRepresentationMask); |
5129 __ cmp(temp.reg(), kConsStringTag); | 5129 __ cmp(temp.reg(), kConsStringTag); |
5130 __ j(not_equal, &slow_case); | 5130 __ j(not_equal, &slow_case); |
5131 | 5131 |
5132 // ConsString. | 5132 // ConsString. |
5133 // Check that the right hand side is the empty string (ie if this is really a | 5133 // Check that the right hand side is the empty string (ie if this is really a |
5134 // flat string in a cons string). If that is not the case we would rather go | 5134 // flat string in a cons string). If that is not the case we would rather go |
5135 // to the runtime system now, to flatten the string. | 5135 // to the runtime system now, to flatten the string. |
5136 __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset)); | 5136 __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset)); |
5137 __ cmp(Operand(temp.reg()), Immediate(Handle<String>(Heap::empty_string()))); | 5137 __ cmp(Operand(temp.reg()), Factory::empty_string()); |
5138 __ j(not_equal, &slow_case); | 5138 __ j(not_equal, &slow_case); |
5139 // Get the first of the two strings. | 5139 // Get the first of the two strings. |
5140 __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset)); | 5140 __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset)); |
5141 __ jmp(&try_again_with_new_string); | 5141 __ jmp(&try_again_with_new_string); |
5142 | 5142 |
5143 __ bind(&slow_case); | 5143 __ bind(&slow_case); |
5144 // Move the undefined value into the result register, which will | 5144 // Move the undefined value into the result register, which will |
5145 // trigger the slow case. | 5145 // trigger the slow case. |
5146 __ Set(temp.reg(), Immediate(Factory::undefined_value())); | 5146 __ Set(temp.reg(), Immediate(Factory::undefined_value())); |
5147 | 5147 |
(...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8390 __ bind(&done); | 8390 __ bind(&done); |
8391 __ ret(3 * kPointerSize); | 8391 __ ret(3 * kPointerSize); |
8392 | 8392 |
8393 // Do the runtime call to allocate the arguments object. | 8393 // Do the runtime call to allocate the arguments object. |
8394 __ bind(&runtime); | 8394 __ bind(&runtime); |
8395 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); | 8395 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); |
8396 } | 8396 } |
8397 | 8397 |
8398 | 8398 |
8399 void RegExpExecStub::Generate(MacroAssembler* masm) { | 8399 void RegExpExecStub::Generate(MacroAssembler* masm) { |
8400 // Just jump directly to runtime if regexp entry in generated code is turned | 8400 // Just jump directly to runtime if native RegExp is not selected at compile |
8401 // off. | 8401 // time or if regexp entry in generated code is turned off runtime switch or |
8402 // at compilation. | |
8403 #ifndef V8_NATIVE_REGEXP | |
8404 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); | |
8405 #endif | |
Lasse Reichstein
2010/01/29 08:09:08
Perhaps use #else to make all the following code g
Søren Thygesen Gjesse
2010/01/29 13:06:53
Done.
| |
8402 if (!FLAG_regexp_entry_native) { | 8406 if (!FLAG_regexp_entry_native) { |
8403 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); | 8407 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); |
8404 return; | 8408 return; |
8405 } | 8409 } |
8406 | 8410 |
8407 // Stack frame on entry. | 8411 // Stack frame on entry. |
8408 // esp[0]: return address | 8412 // esp[0]: return address |
8409 // esp[4]: last_match_info (expected JSArray) | 8413 // esp[4]: last_match_info (expected JSArray) |
8410 // esp[8]: previous index | 8414 // esp[8]: previous index |
8411 // esp[12]: subject string | 8415 // esp[12]: subject string |
(...skipping 17 matching lines...) Expand all Loading... | |
8429 | 8433 |
8430 // Check that the first argument is a JSRegExp object. | 8434 // Check that the first argument is a JSRegExp object. |
8431 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 8435 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
8432 ASSERT_EQ(0, kSmiTag); | 8436 ASSERT_EQ(0, kSmiTag); |
8433 __ test(eax, Immediate(kSmiTagMask)); | 8437 __ test(eax, Immediate(kSmiTagMask)); |
8434 __ j(zero, &runtime); | 8438 __ j(zero, &runtime); |
8435 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); | 8439 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); |
8436 __ j(not_equal, &runtime); | 8440 __ j(not_equal, &runtime); |
8437 // Check that the RegExp has been compiled (data contains a fixed array). | 8441 // Check that the RegExp has been compiled (data contains a fixed array). |
8438 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 8442 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
8439 #ifdef DEBUG | 8443 if (FLAG_debug_code) { |
8440 __ test(ecx, Immediate(kSmiTagMask)); | 8444 __ test(ecx, Immediate(kSmiTagMask)); |
8441 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); | 8445 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); |
8442 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx); | 8446 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx); |
8443 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected"); | 8447 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected"); |
8444 #endif | 8448 } |
8445 | 8449 |
8446 // ecx: RegExp data (FixedArray) | 8450 // ecx: RegExp data (FixedArray) |
8447 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. | 8451 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. |
8448 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset)); | 8452 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset)); |
8449 __ cmp(Operand(ebx), Immediate(Smi::FromInt(JSRegExp::IRREGEXP))); | 8453 __ cmp(Operand(ebx), Immediate(Smi::FromInt(JSRegExp::IRREGEXP))); |
8450 __ j(not_equal, &runtime); | 8454 __ j(not_equal, &runtime); |
8451 | 8455 |
8452 // ecx: RegExp data (FixedArray) | 8456 // ecx: RegExp data (FixedArray) |
8453 // Check that the number of captures fit in the static offsets vector buffer. | 8457 // Check that the number of captures fit in the static offsets vector buffer. |
8454 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); | 8458 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); |
(...skipping 14 matching lines...) Expand all Loading... | |
8469 __ j(zero, &runtime); | 8473 __ j(zero, &runtime); |
8470 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); | 8474 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); |
8471 __ j(NegateCondition(is_string), &runtime); | 8475 __ j(NegateCondition(is_string), &runtime); |
8472 // Get the length of the string to ebx. | 8476 // Get the length of the string to ebx. |
8473 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); | 8477 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); |
8474 | 8478 |
8475 // ebx: Length of subject string | 8479 // ebx: Length of subject string |
8476 // ecx: RegExp data (FixedArray) | 8480 // ecx: RegExp data (FixedArray) |
8477 // edx: Number of capture registers | 8481 // edx: Number of capture registers |
8478 // Check that the third argument is a positive smi. | 8482 // Check that the third argument is a positive smi. |
8483 // Check that the third argument is a positive smi less than the subject | |
8484 // string length. A negative value will be greater (usigned comparison). | |
8479 __ mov(eax, Operand(esp, kPreviousIndexOffset)); | 8485 __ mov(eax, Operand(esp, kPreviousIndexOffset)); |
8480 __ test(eax, Immediate(kSmiTagMask | 0x80000000)); | |
8481 __ j(not_zero, &runtime); | |
8482 // Check that it is not greater than the subject string length. | |
8483 __ SmiUntag(eax); | 8486 __ SmiUntag(eax); |
8484 __ cmp(eax, Operand(ebx)); | 8487 __ cmp(eax, Operand(ebx)); |
8485 __ j(greater, &runtime); | 8488 __ j(greater, &runtime); |
8486 | 8489 |
8487 // ecx: RegExp data (FixedArray) | 8490 // ecx: RegExp data (FixedArray) |
8488 // edx: Number of capture registers | 8491 // edx: Number of capture registers |
8489 // Check that the fourth object is a JSArray object. | 8492 // Check that the fourth object is a JSArray object. |
8490 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 8493 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
8491 __ test(eax, Immediate(kSmiTagMask)); | 8494 __ test(eax, Immediate(kSmiTagMask)); |
8492 __ j(zero, &runtime); | 8495 __ j(zero, &runtime); |
(...skipping 24 matching lines...) Expand all Loading... | |
8517 ASSERT_EQ(0, kStringTag); | 8520 ASSERT_EQ(0, kStringTag); |
8518 ASSERT_EQ(0, kSeqStringTag); | 8521 ASSERT_EQ(0, kSeqStringTag); |
8519 __ test(Operand(ebx), | 8522 __ test(Operand(ebx), |
8520 Immediate(kIsNotStringMask | kStringRepresentationMask)); | 8523 Immediate(kIsNotStringMask | kStringRepresentationMask)); |
8521 __ j(zero, &seq_string); | 8524 __ j(zero, &seq_string); |
8522 | 8525 |
8523 // Check for flat cons string. | 8526 // Check for flat cons string. |
8524 // A flat cons string is a cons string where the second part is the empty | 8527 // A flat cons string is a cons string where the second part is the empty |
8525 // string. In that case the subject string is just the first part of the cons | 8528 // string. In that case the subject string is just the first part of the cons |
8526 // string. Also in this case the first part of the cons string is known to be | 8529 // string. Also in this case the first part of the cons string is known to be |
8527 // a sequential string. | 8530 // a sequential string or an external string. |
8528 __ mov(edx, ebx); | 8531 __ mov(edx, ebx); |
8529 __ and_(edx, kStringRepresentationMask); | 8532 __ and_(edx, kStringRepresentationMask); |
8530 __ cmp(edx, kConsStringTag); | 8533 __ cmp(edx, kConsStringTag); |
8531 __ j(not_equal, &runtime); | 8534 __ j(not_equal, &runtime); |
8532 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); | 8535 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); |
8533 __ cmp(Operand(edx), Immediate(Handle<String>(Heap::empty_string()))); | 8536 __ cmp(Operand(edx), Factory::empty_string()); |
8534 __ j(not_equal, &runtime); | 8537 __ j(not_equal, &runtime); |
8535 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); | 8538 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
8536 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 8539 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
8537 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 8540 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
8541 ASSERT_EQ(0, kSequentialStringTag); | |
8542 __ test(ebx, Immediate(kStringRepresentationMask)); | |
8543 __ j(not_zero, &runtime); | |
8538 __ and_(ebx, kStringRepresentationEncodingMask); | 8544 __ and_(ebx, kStringRepresentationEncodingMask); |
8539 | 8545 |
8540 __ bind(&seq_string); | 8546 __ bind(&seq_string); |
8541 // eax: subject string (sequential either ascii to two byte) | 8547 // eax: subject string (sequential either ascii to two byte) |
8542 // ebx: suject string type & kStringRepresentationEncodingMask | 8548 // ebx: suject string type & kStringRepresentationEncodingMask |
8543 // ecx: RegExp data (FixedArray) | 8549 // ecx: RegExp data (FixedArray) |
8544 // Check that the irregexp code has been generated for an ascii string. If | 8550 // Check that the irregexp code has been generated for an ascii string. If |
8545 // it has, the field contains a code object otherwise it contains the hole. | 8551 // it has, the field contains a code object otherwise it contains the hole. |
8546 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag); | 8552 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag); |
8547 __ j(equal, &seq_two_byte_string); | 8553 __ j(equal, &seq_two_byte_string); |
8548 #ifdef DEBUG | 8554 if (FLAG_debug_code) { |
8549 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag); | 8555 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag); |
8550 __ Check(equal, "Expected sequential ascii string"); | 8556 __ Check(equal, "Expected sequential ascii string"); |
8551 #endif | 8557 } |
8552 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); | 8558 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); |
8553 __ Set(edi, Immediate(1)); // Type is ascii. | 8559 __ Set(edi, Immediate(1)); // Type is ascii. |
8554 __ jmp(&check_code); | 8560 __ jmp(&check_code); |
8555 | 8561 |
8556 __ bind(&seq_two_byte_string); | 8562 __ bind(&seq_two_byte_string); |
8557 // eax: subject string | 8563 // eax: subject string |
8558 // ecx: RegExp data (FixedArray) | 8564 // ecx: RegExp data (FixedArray) |
8559 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); | 8565 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); |
8560 __ Set(edi, Immediate(0)); // Type is two byte. | 8566 __ Set(edi, Immediate(0)); // Type is two byte. |
8561 | 8567 |
8562 __ bind(&check_code); | 8568 __ bind(&check_code); |
8563 // Check that the irregexp code has been generated for If it has, the field | 8569 // Check that the irregexp code has been generated for the actual string |
8564 // contains a code object otherwise it contains the hole. | 8570 // encoding. If it has, the field contains a code object otherwise it contains |
8571 // the hole. | |
8565 __ CmpObjectType(edx, CODE_TYPE, ebx); | 8572 __ CmpObjectType(edx, CODE_TYPE, ebx); |
8566 __ j(not_equal, &runtime); | 8573 __ j(not_equal, &runtime); |
8567 | 8574 |
8568 // eax: subject string | 8575 // eax: subject string |
8569 // edx: code | 8576 // edx: code |
8570 // edi: encoding of subject string (1 if ascii 0 if two_byte); | 8577 // edi: encoding of subject string (1 if ascii, 0 if two_byte); |
8571 // Load used arguments before starting to push arguments for call to native | 8578 // Load used arguments before starting to push arguments for call to native |
8572 // RegExp code to avoid handling changing stack height. | 8579 // RegExp code to avoid handling changing stack height. |
8573 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); | 8580 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); |
8574 __ mov(ecx, Operand(esp, kJSRegExpOffset)); | |
8575 __ SmiUntag(ebx); // Previous index from smi. | 8581 __ SmiUntag(ebx); // Previous index from smi. |
8576 | 8582 |
8577 // eax: subject string | 8583 // eax: subject string |
8578 // ebx: previous index | 8584 // ebx: previous index |
8579 // edx: code | 8585 // edx: code |
8586 // edi: encoding of subject string (1 if ascii 0 if two_byte); | |
8580 // All checks done. Now push arguments for native regexp code. | 8587 // All checks done. Now push arguments for native regexp code. |
8581 __ IncrementCounter(&Counters::regexp_entry_native, 1); | 8588 __ IncrementCounter(&Counters::regexp_entry_native, 1); |
8582 | 8589 |
8583 // Argument 7: Indicate that this is a direct call from JavaScript. | 8590 // Argument 7: Indicate that this is a direct call from JavaScript. |
8584 __ push(Immediate(1)); | 8591 __ push(Immediate(1)); |
8585 | 8592 |
8586 // Argument 6: Start (high end) of backtracking stack memory area. | 8593 // Argument 6: Start (high end) of backtracking stack memory area. |
8587 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); | 8594 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); |
8588 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); | 8595 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); |
8589 __ push(ecx); | 8596 __ push(ecx); |
8590 | 8597 |
8591 // Argument 5: static offsets vector buffer. | 8598 // Argument 5: static offsets vector buffer. |
8592 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); | 8599 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); |
8593 | 8600 |
8594 // Argument 4: End of string data | 8601 // Argument 4: End of string data |
8595 // Argument 3: Start of string data | 8602 // Argument 3: Start of string data |
8596 Label push_two_byte, push_rest; | 8603 Label push_two_byte, push_rest; |
8597 __ test(edi, Operand(edi)); | 8604 __ test(edi, Operand(edi)); |
8598 __ mov(edi, FieldOperand(eax, String::kLengthOffset)); | 8605 __ mov(edi, FieldOperand(eax, String::kLengthOffset)); |
8599 __ j(zero, &push_two_byte); | 8606 __ j(zero, &push_two_byte); |
8600 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize)); | 8607 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize)); |
8601 __ push(ecx); // Argument 4. | 8608 __ push(ecx); // Argument 4. |
8602 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); | 8609 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); |
8603 __ push(ecx); // Argument 3. | 8610 __ push(ecx); // Argument 3. |
8604 __ jmp(&push_rest); | 8611 __ jmp(&push_rest); |
8605 | 8612 |
8606 __ bind(&push_two_byte); | 8613 __ bind(&push_two_byte); |
8607 ASSERT(kShortSize == 2); | |
8608 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize)); | 8614 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize)); |
8609 __ push(ecx); // Argument 4. | 8615 __ push(ecx); // Argument 4. |
8610 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); | 8616 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); |
8611 __ push(ecx); // Argument 3. | 8617 __ push(ecx); // Argument 3. |
8612 | 8618 |
8613 __ bind(&push_rest); | 8619 __ bind(&push_rest); |
8614 | 8620 |
8615 // Argument 2: Previous index. | 8621 // Argument 2: Previous index. |
8616 __ push(ebx); | 8622 __ push(ebx); |
8617 | 8623 |
(...skipping 12 matching lines...) Expand all Loading... | |
8630 __ j(equal, &success, taken); | 8636 __ j(equal, &success, taken); |
8631 Label failure; | 8637 Label failure; |
8632 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); | 8638 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); |
8633 __ j(equal, &failure, taken); | 8639 __ j(equal, &failure, taken); |
8634 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); | 8640 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); |
8635 // If not exception it can only be retry. Handle that in the runtime system. | 8641 // If not exception it can only be retry. Handle that in the runtime system. |
8636 __ j(not_equal, &runtime); | 8642 __ j(not_equal, &runtime); |
8637 // Result must now be exception. If there is no pending exception already a | 8643 // Result must now be exception. If there is no pending exception already a |
8638 // stack overflow (on the backtrack stack) was detected in RegExp code but | 8644 // stack overflow (on the backtrack stack) was detected in RegExp code but |
8639 // haven't created the exception yet. Handle that in the runtime system. | 8645 // haven't created the exception yet. Handle that in the runtime system. |
8646 // TODO(592) Rerunning the RegExp to get the stack overflow exception. | |
8640 ExternalReference pending_exception(Top::k_pending_exception_address); | 8647 ExternalReference pending_exception(Top::k_pending_exception_address); |
8641 __ mov(eax, | 8648 __ mov(eax, |
8642 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 8649 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
8643 __ cmp(eax, Operand::StaticVariable(pending_exception)); | 8650 __ cmp(eax, Operand::StaticVariable(pending_exception)); |
8644 __ j(equal, &runtime); | 8651 __ j(equal, &runtime); |
8645 __ bind(&failure); | 8652 __ bind(&failure); |
8646 // For failure and exception return null. | 8653 // For failure and exception return null. |
8647 __ mov(Operand(eax), Factory::null_value()); | 8654 __ mov(Operand(eax), Factory::null_value()); |
8648 __ ret(4 * kPointerSize); | 8655 __ ret(4 * kPointerSize); |
8649 | 8656 |
8650 // Load RegExp data. | 8657 // Load RegExp data. |
8651 __ bind(&success); | 8658 __ bind(&success); |
8652 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 8659 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
8653 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 8660 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
8654 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); | 8661 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); |
8655 // Calculate number of capture registers (number_of_captures + 1) * 2. | 8662 // Calculate number of capture registers (number_of_captures + 1) * 2. |
8663 ASSERT_EQ(0, kSmiTag); | |
8664 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | |
8656 __ add(Operand(edx), Immediate(2)); // edx was a smi. | 8665 __ add(Operand(edx), Immediate(2)); // edx was a smi. |
8657 | 8666 |
8658 // edx: Number of capture registers | 8667 // edx: Number of capture registers |
8659 // Load last_match_info which is still known to be a fast case JSArray. | 8668 // Load last_match_info which is still known to be a fast case JSArray. |
8660 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 8669 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
8661 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); | 8670 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); |
8662 | 8671 |
8663 // ebx: last_match_info backing store (FixedArray) | 8672 // ebx: last_match_info backing store (FixedArray) |
8664 // edx: number of capture registers | 8673 // edx: number of capture registers |
8665 // Store the capture count. | 8674 // Store the capture count. |
(...skipping 19 matching lines...) Expand all Loading... | |
8685 // ecx: offsets vector | 8694 // ecx: offsets vector |
8686 // edx: number of capture registers | 8695 // edx: number of capture registers |
8687 Label next_capture, done; | 8696 Label next_capture, done; |
8688 __ mov(eax, Operand(esp, kPreviousIndexOffset)); | 8697 __ mov(eax, Operand(esp, kPreviousIndexOffset)); |
8689 // Capture register counter starts from number of capture registers and | 8698 // Capture register counter starts from number of capture registers and |
8690 // counts down until wraping after zero. | 8699 // counts down until wraping after zero. |
8691 __ bind(&next_capture); | 8700 __ bind(&next_capture); |
8692 __ sub(Operand(edx), Immediate(1)); | 8701 __ sub(Operand(edx), Immediate(1)); |
8693 __ j(negative, &done); | 8702 __ j(negative, &done); |
8694 // Read the value from the static offsets vector buffer. | 8703 // Read the value from the static offsets vector buffer. |
8695 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0)); | 8704 __ mov(edi, Operand(ecx, edx, times_int_size, 0)); |
8696 // Perform explicit shift | 8705 // Perform explicit shift |
8697 ASSERT_EQ(0, kSmiTag); | 8706 ASSERT_EQ(0, kSmiTag); |
8698 __ shl(edi, kSmiTagSize); | 8707 __ shl(edi, kSmiTagSize); |
8699 // Add previous index (from its stack slot) if value is not negative. | 8708 // Add previous index (from its stack slot) if value is not negative. |
8700 Label capture_negative; | 8709 Label capture_negative; |
8701 // Carry flag set by shift above. | 8710 // Carry flag set by shift above. |
8702 __ j(negative, &capture_negative, not_taken); | 8711 __ j(negative, &capture_negative, not_taken); |
8703 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). | 8712 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). |
8704 __ bind(&capture_negative); | 8713 __ bind(&capture_negative); |
8705 // Store the smi value in the last match info. | 8714 // Store the smi value in the last match info. |
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10091 | 10100 |
10092 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10101 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
10093 // tagged as a small integer. | 10102 // tagged as a small integer. |
10094 __ bind(&runtime); | 10103 __ bind(&runtime); |
10095 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10104 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
10096 } | 10105 } |
10097 | 10106 |
10098 #undef __ | 10107 #undef __ |
10099 | 10108 |
10100 } } // namespace v8::internal | 10109 } } // namespace v8::internal |
OLD | NEW |