| 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 |