OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 8089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8100 return; | 8100 return; |
8101 } | 8101 } |
8102 | 8102 |
8103 // Stack frame on entry. | 8103 // Stack frame on entry. |
8104 // esp[0]: return address | 8104 // esp[0]: return address |
8105 // esp[4]: last_match_info (expected JSArray) | 8105 // esp[4]: last_match_info (expected JSArray) |
8106 // esp[8]: previous index | 8106 // esp[8]: previous index |
8107 // esp[12]: subject string | 8107 // esp[12]: subject string |
8108 // esp[16]: JSRegExp object | 8108 // esp[16]: JSRegExp object |
8109 | 8109 |
8110 Label runtime; | 8110 static const int kLastMatchInfoOffset = 1 * kPointerSize; |
| 8111 static const int kPreviousIndexOffset = 2 * kPointerSize; |
| 8112 static const int kSubjectOffset = 3 * kPointerSize; |
| 8113 static const int kJSRegExpOffset = 4 * kPointerSize; |
| 8114 |
| 8115 Label runtime, invoke_regexp; |
| 8116 |
| 8117 // Ensure that a RegExp stack is allocated. |
| 8118 ExternalReference address_of_regexp_stack_memory_address = |
| 8119 ExternalReference::address_of_regexp_stack_memory_address(); |
| 8120 ExternalReference address_of_regexp_stack_memory_size = |
| 8121 ExternalReference::address_of_regexp_stack_memory_size(); |
| 8122 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); |
| 8123 __ test(ebx, Operand(ebx)); |
| 8124 __ j(zero, &runtime, not_taken); |
8111 | 8125 |
8112 // Check that the first argument is a JSRegExp object. | 8126 // Check that the first argument is a JSRegExp object. |
8113 __ mov(eax, Operand(esp, 4 * kPointerSize)); | 8127 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
8114 ASSERT_EQ(0, kSmiTag); | 8128 ASSERT_EQ(0, kSmiTag); |
8115 __ test(eax, Immediate(kSmiTagMask)); | 8129 __ test(eax, Immediate(kSmiTagMask)); |
8116 __ j(zero, &runtime); | 8130 __ j(zero, &runtime); |
8117 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); | 8131 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); |
8118 __ j(not_equal, &runtime); | 8132 __ j(not_equal, &runtime); |
8119 // Check that the RegExp has been compiled (data contains a fixed array). | 8133 // Check that the RegExp has been compiled (data contains a fixed array). |
8120 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 8134 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
8121 #ifdef DEBUG | 8135 #ifdef DEBUG |
8122 __ test(ecx, Immediate(kSmiTagMask)); | 8136 __ test(ecx, Immediate(kSmiTagMask)); |
8123 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); | 8137 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); |
(...skipping 15 matching lines...) Expand all Loading... |
8139 ASSERT_EQ(0, kSmiTag); | 8153 ASSERT_EQ(0, kSmiTag); |
8140 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 8154 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
8141 __ add(Operand(edx), Immediate(2)); // edx was a smi. | 8155 __ add(Operand(edx), Immediate(2)); // edx was a smi. |
8142 // Check that the static offsets vector buffer is large enough. | 8156 // Check that the static offsets vector buffer is large enough. |
8143 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize); | 8157 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize); |
8144 __ j(above, &runtime); | 8158 __ j(above, &runtime); |
8145 | 8159 |
8146 // ecx: RegExp data (FixedArray) | 8160 // ecx: RegExp data (FixedArray) |
8147 // edx: Number of capture registers | 8161 // edx: Number of capture registers |
8148 // Check that the second argument is a string. | 8162 // Check that the second argument is a string. |
8149 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 8163 __ mov(eax, Operand(esp, kSubjectOffset)); |
8150 __ test(eax, Immediate(kSmiTagMask)); | 8164 __ test(eax, Immediate(kSmiTagMask)); |
8151 __ j(zero, &runtime); | 8165 __ j(zero, &runtime); |
8152 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); | 8166 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); |
8153 __ j(NegateCondition(is_string), &runtime); | 8167 __ j(NegateCondition(is_string), &runtime); |
8154 // Get the length of the string to ebx. | 8168 // Get the length of the string to ebx. |
8155 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); | 8169 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); |
8156 | 8170 |
8157 // ebx: Length of subject string | 8171 // ebx: Length of subject string |
8158 // ecx: RegExp data (FixedArray) | 8172 // ecx: RegExp data (FixedArray) |
8159 // edx: Number of capture registers | 8173 // edx: Number of capture registers |
8160 // Check that the third argument is a positive smi. | 8174 // Check that the third argument is a positive smi. |
8161 __ mov(eax, Operand(esp, 2 * kPointerSize)); | 8175 __ mov(eax, Operand(esp, kPreviousIndexOffset)); |
8162 __ test(eax, Immediate(kSmiTagMask | 0x80000000)); | 8176 __ test(eax, Immediate(kSmiTagMask | 0x80000000)); |
8163 __ j(not_zero, &runtime); | 8177 __ j(not_zero, &runtime); |
8164 // Check that it is not greater than the subject string length. | 8178 // Check that it is not greater than the subject string length. |
8165 __ SmiUntag(eax); | 8179 __ SmiUntag(eax); |
8166 __ cmp(eax, Operand(ebx)); | 8180 __ cmp(eax, Operand(ebx)); |
8167 __ j(greater, &runtime); | 8181 __ j(greater, &runtime); |
8168 | 8182 |
8169 // ecx: RegExp data (FixedArray) | 8183 // ecx: RegExp data (FixedArray) |
8170 // edx: Number of capture registers | 8184 // edx: Number of capture registers |
8171 // Check that the fourth object is a JSArray object. | 8185 // Check that the fourth object is a JSArray object. |
8172 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 8186 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
8173 __ test(eax, Immediate(kSmiTagMask)); | 8187 __ test(eax, Immediate(kSmiTagMask)); |
8174 __ j(zero, &runtime); | 8188 __ j(zero, &runtime); |
8175 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); | 8189 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); |
8176 __ j(not_equal, &runtime); | 8190 __ j(not_equal, &runtime); |
8177 // Check that the JSArray is in fast case. | 8191 // Check that the JSArray is in fast case. |
8178 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); | 8192 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); |
8179 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset)); | 8193 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset)); |
8180 __ cmp(eax, Factory::fixed_array_map()); | 8194 __ cmp(eax, Factory::fixed_array_map()); |
8181 __ j(not_equal, &runtime); | 8195 __ j(not_equal, &runtime); |
8182 // Check that the last match info has space for the capture registers and the | 8196 // Check that the last match info has space for the capture registers and the |
8183 // additional information. | 8197 // additional information. |
8184 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset)); | 8198 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset)); |
8185 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead)); | 8199 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead)); |
8186 __ cmp(edx, Operand(eax)); | 8200 __ cmp(edx, Operand(eax)); |
8187 __ j(greater, &runtime); | 8201 __ j(greater, &runtime); |
8188 | 8202 |
8189 // ecx: RegExp data (FixedArray) | 8203 // ecx: RegExp data (FixedArray) |
8190 // Check the representation and encoding of the subject string (only support | 8204 // Check the representation and encoding of the subject string. |
8191 // flat ascii strings). | 8205 Label seq_string, seq_two_byte_string, check_code; |
8192 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 8206 const int kStringRepresentationEncodingMask = |
| 8207 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; |
| 8208 __ mov(eax, Operand(esp, kSubjectOffset)); |
8193 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 8209 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
8194 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 8210 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
8195 __ and_(ebx, kStringRepresentationMask | kStringEncodingMask); | 8211 __ and_(ebx, kStringRepresentationEncodingMask); |
8196 __ cmp(ebx, kSeqStringTag | kAsciiStringTag); | 8212 // First check for sequential string. |
| 8213 ASSERT_EQ(0, kStringTag); |
| 8214 ASSERT_EQ(0, kSeqStringTag); |
| 8215 __ test(Operand(ebx), |
| 8216 Immediate(kIsNotStringMask | kStringRepresentationMask)); |
| 8217 __ j(zero, &seq_string); |
| 8218 |
| 8219 // Check for flat cons string. |
| 8220 // A flat cons string is a cons string where the second part is the empty |
| 8221 // string. In that case the subject string is just the first part of the cons |
| 8222 // string. Also in this case the first part of the cons string is known to be |
| 8223 // a sequential string. |
| 8224 __ mov(edx, ebx); |
| 8225 __ and_(edx, kStringRepresentationMask); |
| 8226 __ cmp(edx, kConsStringTag); |
8197 __ j(not_equal, &runtime); | 8227 __ j(not_equal, &runtime); |
| 8228 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); |
| 8229 __ cmp(Operand(edx), Immediate(Handle<String>(Heap::empty_string()))); |
| 8230 __ j(not_equal, &runtime); |
| 8231 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
| 8232 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 8233 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 8234 __ and_(ebx, kStringRepresentationEncodingMask); |
8198 | 8235 |
8199 // ecx: RegExp data (FixedArray) | 8236 __ bind(&seq_string); |
8200 // Ensure that a RegExp stack is allocated. | 8237 // eax: subject string (sequential either ascii to two byte) |
8201 ExternalReference address_of_regexp_stack_memory_address = | 8238 // ebx: suject string type & kStringRepresentationEncodingMask |
8202 ExternalReference::address_of_regexp_stack_memory_address(); | |
8203 ExternalReference address_of_regexp_stack_memory_size = | |
8204 ExternalReference::address_of_regexp_stack_memory_size(); | |
8205 __ mov(eax, Operand::StaticVariable(address_of_regexp_stack_memory_size)); | |
8206 __ test(eax, Operand(eax)); | |
8207 __ j(zero, &runtime, not_taken); | |
8208 | |
8209 // ecx: RegExp data (FixedArray) | 8239 // ecx: RegExp data (FixedArray) |
8210 // Check that the irregexp code has been generated for an ascii string. If | 8240 // Check that the irregexp code has been generated for an ascii string. If |
8211 // it has the field contains a code object otherwise it contains the hole. | 8241 // it has, the field contains a code object otherwise it contains the hole. |
| 8242 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag); |
| 8243 __ j(equal, &seq_two_byte_string); |
| 8244 #ifdef DEBUG |
| 8245 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag); |
| 8246 __ Check(equal, "Expected sequential ascii string"); |
| 8247 #endif |
8212 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); | 8248 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); |
| 8249 __ Set(edi, Immediate(1)); // Type is ascii. |
| 8250 __ jmp(&check_code); |
| 8251 |
| 8252 __ bind(&seq_two_byte_string); |
| 8253 // eax: subject string |
| 8254 // ecx: RegExp data (FixedArray) |
| 8255 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); |
| 8256 __ Set(edi, Immediate(0)); // Type is two byte. |
| 8257 |
| 8258 __ bind(&check_code); |
| 8259 // Check that the irregexp code has been generated for If it has, the field |
| 8260 // contains a code object otherwise it contains the hole. |
8213 __ CmpObjectType(edx, CODE_TYPE, ebx); | 8261 __ CmpObjectType(edx, CODE_TYPE, ebx); |
8214 __ j(not_equal, &runtime); | 8262 __ j(not_equal, &runtime); |
8215 | 8263 |
| 8264 // eax: subject string |
| 8265 // edx: code |
| 8266 // edi: encoding of subject string (1 if ascii 0 if two_byte); |
8216 // Load used arguments before starting to push arguments for call to native | 8267 // Load used arguments before starting to push arguments for call to native |
8217 // RegExp code to avoid handling changing stack height. | 8268 // RegExp code to avoid handling changing stack height. |
8218 __ mov(eax, Operand(esp, 3 * kPointerSize)); // Subject string. | 8269 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); |
8219 __ mov(ebx, Operand(esp, 2 * kPointerSize)); // Previous index. | 8270 __ mov(ecx, Operand(esp, kJSRegExpOffset)); |
8220 __ mov(ecx, Operand(esp, 4 * kPointerSize)); // JSRegExp object. | 8271 __ SmiUntag(ebx); // Previous index from smi. |
8221 __ SmiUntag(ebx); // Previous index from sim. | |
8222 | 8272 |
8223 // eax: subject string | 8273 // eax: subject string |
8224 // ebx: previous index | 8274 // ebx: previous index |
8225 // edx: code | 8275 // edx: code |
8226 // All checks done. Now push arguments for native regexp code. | 8276 // All checks done. Now push arguments for native regexp code. |
8227 __ IncrementCounter(&Counters::regexp_entry_native, 1); | 8277 __ IncrementCounter(&Counters::regexp_entry_native, 1); |
8228 | 8278 |
8229 // Argument 8: Indicate that this is a direct call from JavaScript. | 8279 // Argument 8: Indicate that this is a direct call from JavaScript. |
8230 __ push(Immediate(1)); | 8280 __ push(Immediate(1)); |
8231 | 8281 |
8232 // Argument 7: Start (high end) of backtracking stack memory area. | 8282 // Argument 7: Start (high end) of backtracking stack memory area. |
8233 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); | 8283 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); |
8234 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); | 8284 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); |
8235 __ push(ecx); | 8285 __ push(ecx); |
8236 | 8286 |
8237 // Argument 6: At start of string? | 8287 // Argument 6: At start of string? |
8238 __ xor_(Operand(ecx), ecx); // setcc only operated on cl (lower byte of ecx). | 8288 __ xor_(Operand(ecx), ecx); // setcc only operated on cl (lower byte of ecx). |
8239 __ test(ebx, Operand(ebx)); | 8289 __ test(ebx, Operand(ebx)); |
8240 __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive. | 8290 __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive. |
8241 __ push(ecx); | 8291 __ push(ecx); |
8242 | 8292 |
8243 // Argument 5: static offsets vector buffer. | 8293 // Argument 5: static offsets vector buffer. |
8244 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); | 8294 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); |
8245 | 8295 |
8246 // Argument 4: End of string data. | 8296 // Argument 4: End of string data |
8247 __ mov(ecx, FieldOperand(eax, String::kLengthOffset)); | 8297 // Argument 3: Start of string data |
8248 __ add(ecx, Operand(eax)); | 8298 Label push_two_byte, push_rest; |
8249 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 8299 __ test(edi, Operand(edi)); |
8250 __ push(ecx); | 8300 __ mov(edi, FieldOperand(eax, String::kLengthOffset)); |
| 8301 __ j(zero, &push_two_byte); |
| 8302 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize)); |
| 8303 __ push(ecx); // Argument 4. |
| 8304 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); |
| 8305 __ push(ecx); // Argument 3. |
| 8306 __ jmp(&push_rest); |
8251 | 8307 |
8252 // Argument 3: Start of string data. | 8308 __ bind(&push_two_byte); |
8253 __ mov(ecx, ebx); | 8309 ASSERT(kShortSize == 2); |
8254 __ add(ebx, Operand(eax)); // String is ASCII. | 8310 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize)); |
8255 __ add(Operand(ebx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 8311 __ push(ecx); // Argument 4. |
8256 __ push(ebx); | 8312 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); |
| 8313 __ push(ecx); // Argument 3. |
| 8314 |
| 8315 __ bind(&push_rest); |
8257 | 8316 |
8258 // Argument 2: Previous index. | 8317 // Argument 2: Previous index. |
8259 __ push(ecx); | 8318 __ push(ebx); |
8260 | 8319 |
8261 // Argument 1: Subject string. | 8320 // Argument 1: Subject string. |
8262 __ push(eax); | 8321 __ push(eax); |
8263 | 8322 |
8264 // Locate the code entry and call it. | 8323 // Locate the code entry and call it. |
8265 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 8324 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
8266 __ call(Operand(edx)); | 8325 __ call(Operand(edx)); |
8267 // Remove arguments. | 8326 // Remove arguments. |
8268 __ add(Operand(esp), Immediate(8 * kPointerSize)); | 8327 __ add(Operand(esp), Immediate(8 * kPointerSize)); |
8269 | 8328 |
(...skipping 15 matching lines...) Expand all Loading... |
8285 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 8344 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
8286 __ cmp(eax, Operand::StaticVariable(pending_exception)); | 8345 __ cmp(eax, Operand::StaticVariable(pending_exception)); |
8287 __ j(equal, &runtime); | 8346 __ j(equal, &runtime); |
8288 __ bind(&failure); | 8347 __ bind(&failure); |
8289 // For failure and exception return null. | 8348 // For failure and exception return null. |
8290 __ mov(Operand(eax), Factory::null_value()); | 8349 __ mov(Operand(eax), Factory::null_value()); |
8291 __ ret(4 * kPointerSize); | 8350 __ ret(4 * kPointerSize); |
8292 | 8351 |
8293 // Load RegExp data. | 8352 // Load RegExp data. |
8294 __ bind(&success); | 8353 __ bind(&success); |
8295 __ mov(eax, Operand(esp, 4 * kPointerSize)); | 8354 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
8296 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 8355 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
8297 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); | 8356 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); |
8298 // Calculate number of capture registers (number_of_captures + 1) * 2. | 8357 // Calculate number of capture registers (number_of_captures + 1) * 2. |
8299 __ add(Operand(edx), Immediate(2)); // edx was a smi. | 8358 __ add(Operand(edx), Immediate(2)); // edx was a smi. |
8300 | 8359 |
8301 // edx: Number of capture registers | 8360 // edx: Number of capture registers |
8302 // Load last_match_info which is still known to be a fast case JSArray. | 8361 // Load last_match_info which is still known to be a fast case JSArray. |
8303 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 8362 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
8304 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); | 8363 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); |
8305 | 8364 |
8306 // ebx: last_match_info backing store (FixedArray) | 8365 // ebx: last_match_info backing store (FixedArray) |
8307 // edx: number of capture registers | 8366 // edx: number of capture registers |
8308 // Store the capture count. | 8367 // Store the capture count. |
8309 __ SmiTag(edx); // Number of capture registers to smi. | 8368 __ SmiTag(edx); // Number of capture registers to smi. |
8310 __ mov(FieldOperand(ebx, RegExpImpl::kLastCaptureCountOffset), edx); | 8369 __ mov(FieldOperand(ebx, RegExpImpl::kLastCaptureCountOffset), edx); |
8311 __ SmiUntag(edx); // Number of capture registers back from smi. | 8370 __ SmiUntag(edx); // Number of capture registers back from smi. |
8312 // Store last subject and last input. | 8371 // Store last subject and last input. |
8313 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 8372 __ mov(eax, Operand(esp, kSubjectOffset)); |
8314 __ mov(FieldOperand(ebx, RegExpImpl::kLastSubjectOffset), eax); | 8373 __ mov(FieldOperand(ebx, RegExpImpl::kLastSubjectOffset), eax); |
8315 __ mov(ecx, ebx); | 8374 __ mov(ecx, ebx); |
8316 __ RecordWrite(ecx, RegExpImpl::kLastSubjectOffset, eax, edi); | 8375 __ RecordWrite(ecx, RegExpImpl::kLastSubjectOffset, eax, edi); |
8317 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 8376 __ mov(eax, Operand(esp, kSubjectOffset)); |
8318 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax); | 8377 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax); |
8319 __ mov(ecx, ebx); | 8378 __ mov(ecx, ebx); |
8320 __ RecordWrite(ecx, RegExpImpl::kLastInputOffset, eax, edi); | 8379 __ RecordWrite(ecx, RegExpImpl::kLastInputOffset, eax, edi); |
8321 | 8380 |
8322 // Get the static offsets vector filled by the native regexp code. | 8381 // Get the static offsets vector filled by the native regexp code. |
8323 ExternalReference address_of_static_offsets_vector = | 8382 ExternalReference address_of_static_offsets_vector = |
8324 ExternalReference::address_of_static_offsets_vector(); | 8383 ExternalReference::address_of_static_offsets_vector(); |
8325 __ mov(ecx, Immediate(address_of_static_offsets_vector)); | 8384 __ mov(ecx, Immediate(address_of_static_offsets_vector)); |
8326 | 8385 |
8327 // ebx: last_match_info backing store (FixedArray) | 8386 // ebx: last_match_info backing store (FixedArray) |
8328 // ecx: offsets vector | 8387 // ecx: offsets vector |
8329 // edx: number of capture registers | 8388 // edx: number of capture registers |
8330 Label next_capture, done; | 8389 Label next_capture, done; |
8331 __ mov(eax, Operand(esp, 2 * kPointerSize)); // Read previous index. | 8390 __ mov(eax, Operand(esp, kPreviousIndexOffset)); |
8332 // Capture register counter starts from number of capture registers and | 8391 // Capture register counter starts from number of capture registers and |
8333 // counts down until wraping after zero. | 8392 // counts down until wraping after zero. |
8334 __ bind(&next_capture); | 8393 __ bind(&next_capture); |
8335 __ sub(Operand(edx), Immediate(1)); | 8394 __ sub(Operand(edx), Immediate(1)); |
8336 __ j(negative, &done); | 8395 __ j(negative, &done); |
8337 // Read the value from the static offsets vector buffer. | 8396 // Read the value from the static offsets vector buffer. |
8338 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0)); | 8397 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0)); |
8339 // Perform explicit shift | 8398 // Perform explicit shift |
8340 ASSERT_EQ(0, kSmiTag); | 8399 ASSERT_EQ(0, kSmiTag); |
8341 __ shl(edi, kSmiTagSize); | 8400 __ shl(edi, kSmiTagSize); |
8342 // Add previous index (from its stack slot) if value is not negative. | 8401 // Add previous index (from its stack slot) if value is not negative. |
8343 Label capture_negative; | 8402 Label capture_negative; |
8344 // Carry flag set by shift above. | 8403 // Carry flag set by shift above. |
8345 __ j(negative, &capture_negative, not_taken); | 8404 __ j(negative, &capture_negative, not_taken); |
8346 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). | 8405 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). |
8347 __ bind(&capture_negative); | 8406 __ bind(&capture_negative); |
8348 // Store the smi value in the last match info. | 8407 // Store the smi value in the last match info. |
8349 __ mov(FieldOperand(ebx, | 8408 __ mov(FieldOperand(ebx, |
8350 edx, | 8409 edx, |
8351 times_pointer_size, | 8410 times_pointer_size, |
8352 RegExpImpl::kFirstCaptureOffset), | 8411 RegExpImpl::kFirstCaptureOffset), |
8353 edi); | 8412 edi); |
8354 __ jmp(&next_capture); | 8413 __ jmp(&next_capture); |
8355 __ bind(&done); | 8414 __ bind(&done); |
8356 | 8415 |
8357 // Return last match info. | 8416 // Return last match info. |
8358 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 8417 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
8359 __ ret(4 * kPointerSize); | 8418 __ ret(4 * kPointerSize); |
8360 | 8419 |
8361 // Do the runtime call to execute the regexp. | 8420 // Do the runtime call to execute the regexp. |
8362 __ bind(&runtime); | 8421 __ bind(&runtime); |
8363 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); | 8422 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); |
8364 } | 8423 } |
8365 | 8424 |
8366 | 8425 |
8367 void CompareStub::Generate(MacroAssembler* masm) { | 8426 void CompareStub::Generate(MacroAssembler* masm) { |
8368 Label call_builtin, done; | 8427 Label call_builtin, done; |
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9734 | 9793 |
9735 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 9794 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
9736 // tagged as a small integer. | 9795 // tagged as a small integer. |
9737 __ bind(&runtime); | 9796 __ bind(&runtime); |
9738 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 9797 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
9739 } | 9798 } |
9740 | 9799 |
9741 #undef __ | 9800 #undef __ |
9742 | 9801 |
9743 } } // namespace v8::internal | 9802 } } // namespace v8::internal |
OLD | NEW |