Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 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 |
| (...skipping 4469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4480 | 4480 |
| 4481 // For arguments 4 and 3 get string length, calculate start of string data and | 4481 // For arguments 4 and 3 get string length, calculate start of string data and |
| 4482 // calculate the shift of the index (0 for ASCII and 1 for two byte). | 4482 // calculate the shift of the index (0 for ASCII and 1 for two byte). |
| 4483 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 4483 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
| 4484 __ add(r8, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 4484 __ add(r8, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
| 4485 __ eor(r3, r3, Operand(1)); | 4485 __ eor(r3, r3, Operand(1)); |
| 4486 // Load the length from the original subject string from the previous stack | 4486 // Load the length from the original subject string from the previous stack |
| 4487 // frame. Therefore we have to use fp, which points exactly to two pointer | 4487 // frame. Therefore we have to use fp, which points exactly to two pointer |
| 4488 // sizes below the previous sp. (Because creating a new stack frame pushes | 4488 // sizes below the previous sp. (Because creating a new stack frame pushes |
| 4489 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) | 4489 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) |
| 4490 __ ldr(r0, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); | 4490 __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); |
|
Yang
2011/09/02 13:15:22
the underlying subject string is no longer needed,
| |
| 4491 // If slice offset is not 0, load the length from the original sliced string. | 4491 // If slice offset is not 0, load the length from the original sliced string. |
| 4492 // Argument 4, r3: End of string data | 4492 // Argument 4, r3: End of string data |
| 4493 // Argument 3, r2: Start of string data | 4493 // Argument 3, r2: Start of string data |
| 4494 // Prepare start and end index of the input. | 4494 // Prepare start and end index of the input. |
| 4495 __ add(r9, r8, Operand(r9, LSL, r3)); | 4495 __ add(r9, r8, Operand(r9, LSL, r3)); |
| 4496 __ add(r2, r9, Operand(r1, LSL, r3)); | 4496 __ add(r2, r9, Operand(r1, LSL, r3)); |
| 4497 | 4497 |
| 4498 __ ldr(r8, FieldMemOperand(r0, String::kLengthOffset)); | 4498 __ ldr(r8, FieldMemOperand(subject, String::kLengthOffset)); |
| 4499 __ mov(r8, Operand(r8, ASR, kSmiTagSize)); | 4499 __ mov(r8, Operand(r8, ASR, kSmiTagSize)); |
| 4500 __ add(r3, r9, Operand(r8, LSL, r3)); | 4500 __ add(r3, r9, Operand(r8, LSL, r3)); |
| 4501 | 4501 |
| 4502 // Argument 2 (r1): Previous index. | 4502 // Argument 2 (r1): Previous index. |
| 4503 // Already there | 4503 // Already there |
| 4504 | 4504 |
| 4505 // Argument 1 (r0): Subject string. | 4505 // Argument 1 (r0): Subject string. |
| 4506 // Already there | 4506 __ mov(r0, subject); |
| 4507 | 4507 |
| 4508 // Locate the code entry and call it. | 4508 // Locate the code entry and call it. |
| 4509 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4509 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4510 DirectCEntryStub stub; | 4510 DirectCEntryStub stub; |
| 4511 stub.GenerateCall(masm, r7); | 4511 stub.GenerateCall(masm, r7); |
| 4512 | 4512 |
| 4513 __ LeaveExitFrame(false, no_reg); | 4513 __ LeaveExitFrame(false, no_reg); |
| 4514 | 4514 |
| 4515 // r0: result | 4515 // r0: result |
| 4516 // subject: subject string (callee saved) | 4516 // subject: subject string (callee saved) |
| 4517 // regexp_data: RegExp data (callee saved) | 4517 // regexp_data: RegExp data (callee saved) |
| 4518 // last_match_info_elements: Last match info elements (callee saved) | 4518 // last_match_info_elements: Last match info elements (callee saved) |
| 4519 | 4519 |
| 4520 // Check the result. | 4520 // Check the result. |
| 4521 Label success; | 4521 Label success; |
| 4522 | 4522 |
| 4523 __ cmp(subject, Operand(NativeRegExpMacroAssembler::SUCCESS)); | 4523 __ cmp(r0, Operand(NativeRegExpMacroAssembler::SUCCESS)); |
|
Yang
2011/09/02 13:15:22
not subject (r4) but r0 is the return value of the
| |
| 4524 __ b(eq, &success); | 4524 __ b(eq, &success); |
| 4525 Label failure; | 4525 Label failure; |
| 4526 __ cmp(subject, Operand(NativeRegExpMacroAssembler::FAILURE)); | 4526 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE)); |
| 4527 __ b(eq, &failure); | 4527 __ b(eq, &failure); |
| 4528 __ cmp(subject, Operand(NativeRegExpMacroAssembler::EXCEPTION)); | 4528 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); |
| 4529 // If not exception it can only be retry. Handle that in the runtime system. | 4529 // If not exception it can only be retry. Handle that in the runtime system. |
| 4530 __ b(ne, &runtime); | 4530 __ b(ne, &runtime); |
|
Yang
2011/09/02 13:15:22
even though subject is not the result of the regex
| |
| 4531 // Result must now be exception. If there is no pending exception already a | 4531 // Result must now be exception. If there is no pending exception already a |
| 4532 // stack overflow (on the backtrack stack) was detected in RegExp code but | 4532 // stack overflow (on the backtrack stack) was detected in RegExp code but |
| 4533 // haven't created the exception yet. Handle that in the runtime system. | 4533 // haven't created the exception yet. Handle that in the runtime system. |
| 4534 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 4534 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
| 4535 __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); | 4535 __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); |
| 4536 __ ldr(r1, MemOperand(r1, 0)); | 4536 __ ldr(r1, MemOperand(r1, 0)); |
| 4537 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, | 4537 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 4538 isolate))); | 4538 isolate))); |
| 4539 __ ldr(r0, MemOperand(r2, 0)); | 4539 __ ldr(r0, MemOperand(r2, 0)); |
| 4540 __ cmp(subject, r1); | 4540 __ cmp(r0, r1); |
| 4541 __ b(eq, &runtime); | 4541 __ b(eq, &runtime); |
| 4542 | 4542 |
| 4543 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. | 4543 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. |
| 4544 | 4544 |
| 4545 // Check if the exception is a termination. If so, throw as uncatchable. | 4545 // Check if the exception is a termination. If so, throw as uncatchable. |
| 4546 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex); | 4546 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex); |
|
Erik Corry
2011/09/02 13:25:19
We have CompareRoot for this.
| |
| 4547 __ cmp(subject, ip); | 4547 __ cmp(r0, ip); |
| 4548 Label termination_exception; | 4548 Label termination_exception; |
| 4549 __ b(eq, &termination_exception); | 4549 __ b(eq, &termination_exception); |
| 4550 | 4550 |
| 4551 __ Throw(subject); // Expects thrown value in r0. | 4551 __ Throw(r0); // Expects thrown value in r0. |
| 4552 | 4552 |
| 4553 __ bind(&termination_exception); | 4553 __ bind(&termination_exception); |
| 4554 __ ThrowUncatchable(TERMINATION, r0); // Expects thrown value in r0. | 4554 __ ThrowUncatchable(TERMINATION, r0); // Expects thrown value in r0. |
| 4555 | 4555 |
| 4556 __ bind(&failure); | 4556 __ bind(&failure); |
| 4557 // For failure and exception return null. | 4557 // For failure and exception return null. |
| 4558 __ mov(r0, Operand(masm->isolate()->factory()->null_value())); | 4558 __ mov(r0, Operand(masm->isolate()->factory()->null_value())); |
| 4559 __ add(sp, sp, Operand(4 * kPointerSize)); | 4559 __ add(sp, sp, Operand(4 * kPointerSize)); |
| 4560 __ Ret(); | 4560 __ Ret(); |
| 4561 | 4561 |
| (...skipping 2123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6685 __ mov(result, Operand::Zero()); | 6685 __ mov(result, Operand::Zero()); |
| 6686 __ Ret(); | 6686 __ Ret(); |
| 6687 } | 6687 } |
| 6688 | 6688 |
| 6689 | 6689 |
| 6690 #undef __ | 6690 #undef __ |
| 6691 | 6691 |
| 6692 } } // namespace v8::internal | 6692 } } // namespace v8::internal |
| 6693 | 6693 |
| 6694 #endif // V8_TARGET_ARCH_ARM | 6694 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |