OLD | NEW |
1 // Copyright 2008-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2008-2009 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 * - ecx : points to tip of backtrack stack | 52 * - ecx : points to tip of backtrack stack |
53 * | 53 * |
54 * The registers eax, ebx and ecx are free to use for computations. | 54 * The registers eax, ebx and ecx are free to use for computations. |
55 * | 55 * |
56 * Each call to a public method should retain this convention. | 56 * Each call to a public method should retain this convention. |
57 * The stack will have the following structure: | 57 * The stack will have the following structure: |
58 * - direct_call (if 1, direct call from JavaScript code, if 0 | 58 * - direct_call (if 1, direct call from JavaScript code, if 0 |
59 * call through the runtime system) | 59 * call through the runtime system) |
60 * - stack_area_base (High end of the memory area to use as | 60 * - stack_area_base (High end of the memory area to use as |
61 * backtracking stack) | 61 * backtracking stack) |
62 * - at_start (if 1, we are starting at the start of the | |
63 * string, otherwise 0) | |
64 * - int* capture_array (int[num_saved_registers_], for output). | 62 * - int* capture_array (int[num_saved_registers_], for output). |
65 * - end of input (Address of end of string) | 63 * - end of input (Address of end of string) |
66 * - start of input (Address of first character in string) | 64 * - start of input (Address of first character in string) |
67 * - start index (character index of start) | 65 * - start index (character index of start) |
68 * - String* input_string (location of a handle containing the string) | 66 * - String* input_string (location of a handle containing the string) |
69 * --- frame alignment (if applicable) --- | 67 * --- frame alignment (if applicable) --- |
70 * - return address | 68 * - return address |
71 * ebp-> - old ebp | 69 * ebp-> - old ebp |
72 * - backup of caller esi | 70 * - backup of caller esi |
73 * - backup of caller edi | 71 * - backup of caller edi |
74 * - backup of caller ebx | 72 * - backup of caller ebx |
75 * - Offset of location before start of input (effectively character | 73 * - Offset of location before start of input (effectively character |
76 * position -1). Used to initialize capture registers to a non-position. | 74 * position -1). Used to initialize capture registers to a non-position. |
| 75 * - Boolean at start (if 1, we are starting at the start of the string, |
| 76 * otherwise 0) |
77 * - register 0 ebp[-4] (Only positions must be stored in the first | 77 * - register 0 ebp[-4] (Only positions must be stored in the first |
78 * - register 1 ebp[-8] num_saved_registers_ registers) | 78 * - register 1 ebp[-8] num_saved_registers_ registers) |
79 * - ... | 79 * - ... |
80 * | 80 * |
81 * The first num_saved_registers_ registers are initialized to point to | 81 * The first num_saved_registers_ registers are initialized to point to |
82 * "character -1" in the string (i.e., char_size() bytes before the first | 82 * "character -1" in the string (i.e., char_size() bytes before the first |
83 * character of the string). The remaining registers starts out as garbage. | 83 * character of the string). The remaining registers starts out as garbage. |
84 * | 84 * |
85 * The data up to the return address must be placed there by the calling | 85 * The data up to the return address must be placed there by the calling |
86 * code, by calling the code entry as cast to a function with the signature: | 86 * code, by calling the code entry as cast to a function with the signature: |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 __ bind(&entry_label_); | 618 __ bind(&entry_label_); |
619 // Start new stack frame. | 619 // Start new stack frame. |
620 __ push(ebp); | 620 __ push(ebp); |
621 __ mov(ebp, esp); | 621 __ mov(ebp, esp); |
622 // Save callee-save registers. Order here should correspond to order of | 622 // Save callee-save registers. Order here should correspond to order of |
623 // kBackup_ebx etc. | 623 // kBackup_ebx etc. |
624 __ push(esi); | 624 __ push(esi); |
625 __ push(edi); | 625 __ push(edi); |
626 __ push(ebx); // Callee-save on MacOS. | 626 __ push(ebx); // Callee-save on MacOS. |
627 __ push(Immediate(0)); // Make room for "input start - 1" constant. | 627 __ push(Immediate(0)); // Make room for "input start - 1" constant. |
| 628 __ push(Immediate(0)); // Make room for "at start" constant. |
628 | 629 |
629 // Check if we have space on the stack for registers. | 630 // Check if we have space on the stack for registers. |
630 Label stack_limit_hit; | 631 Label stack_limit_hit; |
631 Label stack_ok; | 632 Label stack_ok; |
632 | 633 |
633 ExternalReference stack_limit = | 634 ExternalReference stack_limit = |
634 ExternalReference::address_of_stack_limit(); | 635 ExternalReference::address_of_stack_limit(); |
635 __ mov(ecx, esp); | 636 __ mov(ecx, esp); |
636 __ sub(ecx, Operand::StaticVariable(stack_limit)); | 637 __ sub(ecx, Operand::StaticVariable(stack_limit)); |
637 // Handle it if the stack pointer is already below the stack limit. | 638 // Handle it if the stack pointer is already below the stack limit. |
(...skipping 22 matching lines...) Expand all Loading... |
660 // Load input position. | 661 // Load input position. |
661 __ mov(edi, Operand(ebp, kInputStart)); | 662 __ mov(edi, Operand(ebp, kInputStart)); |
662 // Set up edi to be negative offset from string end. | 663 // Set up edi to be negative offset from string end. |
663 __ sub(edi, Operand(esi)); | 664 __ sub(edi, Operand(esi)); |
664 // Set eax to address of char before start of input | 665 // Set eax to address of char before start of input |
665 // (effectively string position -1). | 666 // (effectively string position -1). |
666 __ lea(eax, Operand(edi, -char_size())); | 667 __ lea(eax, Operand(edi, -char_size())); |
667 // Store this value in a local variable, for use when clearing | 668 // Store this value in a local variable, for use when clearing |
668 // position registers. | 669 // position registers. |
669 __ mov(Operand(ebp, kInputStartMinusOne), eax); | 670 __ mov(Operand(ebp, kInputStartMinusOne), eax); |
| 671 |
| 672 // Determine whether the start index is zero, that is at the start of the |
| 673 // string, and store that value in a local variable. |
| 674 __ mov(ebx, Operand(ebp, kStartIndex)); |
| 675 __ xor_(Operand(ecx), ecx); // setcc only operates on cl (lower byte of ecx). |
| 676 __ test(ebx, Operand(ebx)); |
| 677 __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive. |
| 678 __ mov(Operand(ebp, kAtStart), ecx); |
| 679 |
670 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. | 680 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. |
671 // Fill saved registers with initial value = start offset - 1 | 681 // Fill saved registers with initial value = start offset - 1 |
672 // Fill in stack push order, to avoid accessing across an unwritten | 682 // Fill in stack push order, to avoid accessing across an unwritten |
673 // page (a problem on Windows). | 683 // page (a problem on Windows). |
674 __ mov(ecx, kRegisterZero); | 684 __ mov(ecx, kRegisterZero); |
675 Label init_loop; | 685 Label init_loop; |
676 __ bind(&init_loop); | 686 __ bind(&init_loop); |
677 __ mov(Operand(ebp, ecx, times_1, +0), eax); | 687 __ mov(Operand(ebp, ecx, times_1, +0), eax); |
678 __ sub(Operand(ecx), Immediate(kPointerSize)); | 688 __ sub(Operand(ecx), Immediate(kPointerSize)); |
679 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize); | 689 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize); |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 } | 1207 } |
1198 } | 1208 } |
1199 } | 1209 } |
1200 | 1210 |
1201 | 1211 |
1202 #undef __ | 1212 #undef __ |
1203 | 1213 |
1204 #endif // V8_NATIVE_REGEXP | 1214 #endif // V8_NATIVE_REGEXP |
1205 | 1215 |
1206 }} // namespace v8::internal | 1216 }} // namespace v8::internal |
OLD | NEW |