Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: src/regexp/ia32/regexp-macro-assembler-ia32.cc

Issue 1418963009: Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: mips64 port Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" 7 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h"
8 8
9 #include "src/log.h" 9 #include "src/log.h"
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } 149 }
150 150
151 151
152 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { 152 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) {
153 __ cmp(current_character(), limit); 153 __ cmp(current_character(), limit);
154 BranchOrBacktrack(greater, on_greater); 154 BranchOrBacktrack(greater, on_greater);
155 } 155 }
156 156
157 157
158 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { 158 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) {
159 Label not_at_start;
160 // Did we start the match at the start of the string at all?
161 __ cmp(Operand(ebp, kStartIndex), Immediate(0));
162 BranchOrBacktrack(not_equal, &not_at_start);
163 // If we did, are we still at the start of the input?
164 __ lea(eax, Operand(esi, edi, times_1, 0)); 159 __ lea(eax, Operand(esi, edi, times_1, 0));
160 for (int i = 0; i < char_size(); i++) {
161 __ add(eax, Operand(ebp, kStartIndex));
162 }
165 __ cmp(eax, Operand(ebp, kInputStart)); 163 __ cmp(eax, Operand(ebp, kInputStart));
166 BranchOrBacktrack(equal, on_at_start); 164 BranchOrBacktrack(equal, on_at_start);
167 __ bind(&not_at_start);
168 } 165 }
169 166
170 167
171 void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) { 168 void RegExpMacroAssemblerIA32::CheckNotAtStart(int cp_offset,
172 // Did we start the match at the start of the string at all? 169 Label* on_not_at_start) {
173 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); 170 __ lea(eax, Operand(esi, edi, times_1, cp_offset * char_size()));
174 BranchOrBacktrack(not_equal, on_not_at_start); 171 for (int i = 0; i < char_size(); i++) {
175 // If we did, are we still at the start of the input? 172 __ add(eax, Operand(ebp, kStartIndex));
176 __ lea(eax, Operand(esi, edi, times_1, 0)); 173 }
177 __ cmp(eax, Operand(ebp, kInputStart)); 174 __ cmp(eax, Operand(ebp, kInputStart));
178 BranchOrBacktrack(not_equal, on_not_at_start); 175 BranchOrBacktrack(not_equal, on_not_at_start);
179 } 176 }
180 177
181 178
182 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { 179 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) {
183 __ cmp(current_character(), limit); 180 __ cmp(current_character(), limit);
184 BranchOrBacktrack(less, on_less); 181 BranchOrBacktrack(less, on_less);
185 } 182 }
186 183
187 184
188 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { 185 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) {
189 Label fallthrough; 186 Label fallthrough;
190 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); 187 __ cmp(edi, Operand(backtrack_stackpointer(), 0));
191 __ j(not_equal, &fallthrough); 188 __ j(not_equal, &fallthrough);
192 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. 189 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop.
193 BranchOrBacktrack(no_condition, on_equal); 190 BranchOrBacktrack(no_condition, on_equal);
194 __ bind(&fallthrough); 191 __ bind(&fallthrough);
195 } 192 }
196 193
197 194
198 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( 195 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
199 int start_reg, 196 int start_reg,
197 bool read_backward,
200 Label* on_no_match) { 198 Label* on_no_match) {
201 Label fallthrough; 199 Label fallthrough;
202 __ mov(edx, register_location(start_reg)); // Index of start of capture 200 __ mov(edx, register_location(start_reg)); // Index of start of capture
203 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture 201 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture
204 __ sub(ebx, edx); // Length of capture. 202 __ sub(ebx, edx); // Length of capture.
205 203
206 // The length of a capture should not be negative. This can only happen 204 // The length of the capture can only be negative if the end of the
207 // if the end of the capture is unrecorded, or at a point earlier than 205 // capture is not yet recorded. If the length is zero, the capture is
208 // the start of the capture. 206 // either empty or uncaptured. In either of those cases, succeed.
209 BranchOrBacktrack(less, on_no_match); 207 __ j(less_equal, &fallthrough);
210
211 // If length is zero, either the capture is empty or it is completely
212 // uncaptured. In either case succeed immediately.
213 __ j(equal, &fallthrough);
214 208
215 // Check that there are sufficient characters left in the input. 209 // Check that there are sufficient characters left in the input.
216 __ mov(eax, edi); 210 if (read_backward) {
217 __ add(eax, ebx); 211 __ lea(eax, Operand(esi, edi, times_1, 0));
218 BranchOrBacktrack(greater, on_no_match); 212 __ sub(eax, ebx);
213 for (int i = 0; i < char_size(); i++) {
214 __ add(eax, Operand(ebp, kStartIndex));
215 }
216 __ cmp(eax, Operand(ebp, kInputStart));
217 BranchOrBacktrack(less, on_no_match);
218 } else {
219 __ mov(eax, edi);
220 __ add(eax, ebx);
221 BranchOrBacktrack(greater, on_no_match);
222 }
219 223
220 if (mode_ == LATIN1) { 224 if (mode_ == LATIN1) {
221 Label success; 225 Label success;
222 Label fail; 226 Label fail;
223 Label loop_increment; 227 Label loop_increment;
224 // Save register contents to make the registers available below. 228 // Save register contents to make the registers available below.
225 __ push(edi); 229 __ push(edi);
226 __ push(backtrack_stackpointer()); 230 __ push(backtrack_stackpointer());
227 // After this, the eax, ecx, and edi registers are available. 231 // After this, the eax, ecx, and edi registers are available.
228 232
229 __ add(edx, esi); // Start of capture 233 __ add(edx, esi); // Start of capture
230 __ add(edi, esi); // Start of text to match against capture. 234 __ add(edi, esi); // Start of text to match against capture.
235 if (read_backward) {
236 __ sub(edi, ebx); // Offset by length when matching backwards.
237 }
231 __ add(ebx, edi); // End of text to match against capture. 238 __ add(ebx, edi); // End of text to match against capture.
232 239
233 Label loop; 240 Label loop;
234 __ bind(&loop); 241 __ bind(&loop);
235 __ movzx_b(eax, Operand(edi, 0)); 242 __ movzx_b(eax, Operand(edi, 0));
236 __ cmpb_al(Operand(edx, 0)); 243 __ cmpb_al(Operand(edx, 0));
237 __ j(equal, &loop_increment); 244 __ j(equal, &loop_increment);
238 245
239 // Mismatch, try case-insensitive match (converting letters to lower-case). 246 // Mismatch, try case-insensitive match (converting letters to lower-case).
240 __ or_(eax, 0x20); // Convert match character to lower-case. 247 __ or_(eax, 0x20); // Convert match character to lower-case.
(...skipping 30 matching lines...) Expand all
271 __ pop(edi); 278 __ pop(edi);
272 BranchOrBacktrack(no_condition, on_no_match); 279 BranchOrBacktrack(no_condition, on_no_match);
273 280
274 __ bind(&success); 281 __ bind(&success);
275 // Restore original value before continuing. 282 // Restore original value before continuing.
276 __ pop(backtrack_stackpointer()); 283 __ pop(backtrack_stackpointer());
277 // Drop original value of character position. 284 // Drop original value of character position.
278 __ add(esp, Immediate(kPointerSize)); 285 __ add(esp, Immediate(kPointerSize));
279 // Compute new value of character position after the matched part. 286 // Compute new value of character position after the matched part.
280 __ sub(edi, esi); 287 __ sub(edi, esi);
288 if (read_backward) {
289 // Subtract match length if we matched backward.
290 __ add(edi, register_location(start_reg));
291 __ sub(edi, register_location(start_reg + 1));
292 }
281 } else { 293 } else {
282 DCHECK(mode_ == UC16); 294 DCHECK(mode_ == UC16);
283 // Save registers before calling C function. 295 // Save registers before calling C function.
284 __ push(esi); 296 __ push(esi);
285 __ push(edi); 297 __ push(edi);
286 __ push(backtrack_stackpointer()); 298 __ push(backtrack_stackpointer());
287 __ push(ebx); 299 __ push(ebx);
288 300
289 static const int argument_count = 4; 301 static const int argument_count = 4;
290 __ PrepareCallCFunction(argument_count, ecx); 302 __ PrepareCallCFunction(argument_count, ecx);
291 // Put arguments into allocated stack area, last argument highest on stack. 303 // Put arguments into allocated stack area, last argument highest on stack.
292 // Parameters are 304 // Parameters are
293 // Address byte_offset1 - Address captured substring's start. 305 // Address byte_offset1 - Address captured substring's start.
294 // Address byte_offset2 - Address of current character position. 306 // Address byte_offset2 - Address of current character position.
295 // size_t byte_length - length of capture in bytes(!) 307 // size_t byte_length - length of capture in bytes(!)
296 // Isolate* isolate 308 // Isolate* isolate
297 309
298 // Set isolate. 310 // Set isolate.
299 __ mov(Operand(esp, 3 * kPointerSize), 311 __ mov(Operand(esp, 3 * kPointerSize),
300 Immediate(ExternalReference::isolate_address(isolate()))); 312 Immediate(ExternalReference::isolate_address(isolate())));
301 // Set byte_length. 313 // Set byte_length.
302 __ mov(Operand(esp, 2 * kPointerSize), ebx); 314 __ mov(Operand(esp, 2 * kPointerSize), ebx);
303 // Set byte_offset2. 315 // Set byte_offset2.
304 // Found by adding negative string-end offset of current position (edi) 316 // Found by adding negative string-end offset of current position (edi)
305 // to end of string. 317 // to end of string.
306 __ add(edi, esi); 318 __ add(edi, esi);
319 if (read_backward) {
320 __ sub(edi, ebx); // Offset by length when matching backwards.
321 }
307 __ mov(Operand(esp, 1 * kPointerSize), edi); 322 __ mov(Operand(esp, 1 * kPointerSize), edi);
308 // Set byte_offset1. 323 // Set byte_offset1.
309 // Start of capture, where edx already holds string-end negative offset. 324 // Start of capture, where edx already holds string-end negative offset.
310 __ add(edx, esi); 325 __ add(edx, esi);
311 __ mov(Operand(esp, 0 * kPointerSize), edx); 326 __ mov(Operand(esp, 0 * kPointerSize), edx);
312 327
313 { 328 {
314 AllowExternalCallThatCantCauseGC scope(masm_); 329 AllowExternalCallThatCantCauseGC scope(masm_);
315 ExternalReference compare = 330 ExternalReference compare =
316 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 331 ExternalReference::re_case_insensitive_compare_uc16(isolate());
317 __ CallCFunction(compare, argument_count); 332 __ CallCFunction(compare, argument_count);
318 } 333 }
319 // Pop original values before reacting on result value. 334 // Pop original values before reacting on result value.
320 __ pop(ebx); 335 __ pop(ebx);
321 __ pop(backtrack_stackpointer()); 336 __ pop(backtrack_stackpointer());
322 __ pop(edi); 337 __ pop(edi);
323 __ pop(esi); 338 __ pop(esi);
324 339
325 // Check if function returned non-zero for success or zero for failure. 340 // Check if function returned non-zero for success or zero for failure.
326 __ or_(eax, eax); 341 __ or_(eax, eax);
327 BranchOrBacktrack(zero, on_no_match); 342 BranchOrBacktrack(zero, on_no_match);
328 // On success, increment position by length of capture. 343 // On success, advance position by length of capture.
329 __ add(edi, ebx); 344 if (read_backward) {
345 __ sub(edi, ebx);
346 } else {
347 __ add(edi, ebx);
348 }
330 } 349 }
331 __ bind(&fallthrough); 350 __ bind(&fallthrough);
332 } 351 }
333 352
334 353
335 void RegExpMacroAssemblerIA32::CheckNotBackReference( 354 void RegExpMacroAssemblerIA32::CheckNotBackReference(
336 int start_reg, 355 int start_reg,
356 bool read_backward,
337 Label* on_no_match) { 357 Label* on_no_match) {
338 Label fallthrough; 358 Label fallthrough;
339 Label success; 359 Label success;
340 Label fail; 360 Label fail;
341 361
342 // Find length of back-referenced capture. 362 // Find length of back-referenced capture.
343 __ mov(edx, register_location(start_reg)); 363 __ mov(edx, register_location(start_reg));
344 __ mov(eax, register_location(start_reg + 1)); 364 __ mov(eax, register_location(start_reg + 1));
345 __ sub(eax, edx); // Length to check. 365 __ sub(eax, edx); // Length to check.
346 // Fail on partial or illegal capture (start of capture after end of capture). 366 // The length of the capture can only be negative if the end of the
347 BranchOrBacktrack(less, on_no_match); 367 // capture is not yet recorded. If the length is zero, the capture is
348 // Succeed on empty capture (including no capture) 368 // either empty or uncaptured. In either of those cases, succeed.
349 __ j(equal, &fallthrough); 369 __ j(less_equal, &fallthrough);
350 370
351 // Check that there are sufficient characters left in the input. 371 // Check that there are sufficient characters left in the input.
352 __ mov(ebx, edi); 372 if (read_backward) {
353 __ add(ebx, eax); 373 __ lea(ebx, Operand(esi, edi, times_1, 0));
354 BranchOrBacktrack(greater, on_no_match); 374 __ sub(ebx, eax);
375 for (int i = 0; i < char_size(); i++) {
376 __ add(ebx, Operand(ebp, kStartIndex));
377 }
378 __ cmp(ebx, Operand(ebp, kInputStart));
379 BranchOrBacktrack(less, on_no_match);
380 } else {
381 __ mov(ebx, edi);
382 __ add(ebx, eax);
383 BranchOrBacktrack(greater, on_no_match);
384 }
355 385
356 // Save register to make it available below. 386 // Save register to make it available below.
357 __ push(backtrack_stackpointer()); 387 __ push(backtrack_stackpointer());
358 388
359 // Compute pointers to match string and capture string 389 // Compute pointers to match string and capture string
390 __ add(edx, esi); // Start of capture.
360 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. 391 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match.
361 __ add(edx, esi); // Start of capture. 392 if (read_backward) {
393 __ sub(ebx, eax); // Offset by length when matching backwards.
394 }
362 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match 395 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match
363 396
364 Label loop; 397 Label loop;
365 __ bind(&loop); 398 __ bind(&loop);
366 if (mode_ == LATIN1) { 399 if (mode_ == LATIN1) {
367 __ movzx_b(eax, Operand(edx, 0)); 400 __ movzx_b(eax, Operand(edx, 0));
368 __ cmpb_al(Operand(ebx, 0)); 401 __ cmpb_al(Operand(ebx, 0));
369 } else { 402 } else {
370 DCHECK(mode_ == UC16); 403 DCHECK(mode_ == UC16);
371 __ movzx_w(eax, Operand(edx, 0)); 404 __ movzx_w(eax, Operand(edx, 0));
(...skipping 10 matching lines...) Expand all
382 415
383 __ bind(&fail); 416 __ bind(&fail);
384 // Restore backtrack stackpointer. 417 // Restore backtrack stackpointer.
385 __ pop(backtrack_stackpointer()); 418 __ pop(backtrack_stackpointer());
386 BranchOrBacktrack(no_condition, on_no_match); 419 BranchOrBacktrack(no_condition, on_no_match);
387 420
388 __ bind(&success); 421 __ bind(&success);
389 // Move current character position to position after match. 422 // Move current character position to position after match.
390 __ mov(edi, ecx); 423 __ mov(edi, ecx);
391 __ sub(edi, esi); 424 __ sub(edi, esi);
425 if (read_backward) {
426 // Subtract match length if we matched backward.
427 __ add(edi, register_location(start_reg));
428 __ sub(edi, register_location(start_reg + 1));
429 }
392 // Restore backtrack stackpointer. 430 // Restore backtrack stackpointer.
393 __ pop(backtrack_stackpointer()); 431 __ pop(backtrack_stackpointer());
394 432
395 __ bind(&fallthrough); 433 __ bind(&fallthrough);
396 } 434 }
397 435
398 436
399 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, 437 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c,
400 Label* on_not_equal) { 438 Label* on_not_equal) {
401 __ cmp(current_character(), c); 439 __ cmp(current_character(), c);
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 // Convert to index from start of string, not end. 798 // Convert to index from start of string, not end.
761 __ add(eax, ecx); 799 __ add(eax, ecx);
762 if (mode_ == UC16) { 800 if (mode_ == UC16) {
763 __ sar(eax, 1); // Convert byte index to character index. 801 __ sar(eax, 1); // Convert byte index to character index.
764 } 802 }
765 __ mov(Operand(ebx, i * kPointerSize), eax); 803 __ mov(Operand(ebx, i * kPointerSize), eax);
766 } 804 }
767 } 805 }
768 806
769 if (global()) { 807 if (global()) {
770 // Restart matching if the regular expression is flagged as global. 808 // Restart matching if the regular expression is flagged as global.
771 // Increment success counter. 809 // Increment success counter.
772 __ inc(Operand(ebp, kSuccessfulCaptures)); 810 __ inc(Operand(ebp, kSuccessfulCaptures));
773 // Capture results have been stored, so the number of remaining global 811 // Capture results have been stored, so the number of remaining global
774 // output registers is reduced by the number of stored captures. 812 // output registers is reduced by the number of stored captures.
775 __ mov(ecx, Operand(ebp, kNumOutputRegisters)); 813 __ mov(ecx, Operand(ebp, kNumOutputRegisters));
776 __ sub(ecx, Immediate(num_saved_registers_)); 814 __ sub(ecx, Immediate(num_saved_registers_));
777 // Check whether we have enough room for another set of capture results. 815 // Check whether we have enough room for another set of capture results.
778 __ cmp(ecx, Immediate(num_saved_registers_)); 816 __ cmp(ecx, Immediate(num_saved_registers_));
779 __ j(less, &exit_label_); 817 __ j(less, &exit_label_);
780 818
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 RegExpMacroAssembler::IrregexpImplementation 975 RegExpMacroAssembler::IrregexpImplementation
938 RegExpMacroAssemblerIA32::Implementation() { 976 RegExpMacroAssemblerIA32::Implementation() {
939 return kIA32Implementation; 977 return kIA32Implementation;
940 } 978 }
941 979
942 980
943 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, 981 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
944 Label* on_end_of_input, 982 Label* on_end_of_input,
945 bool check_bounds, 983 bool check_bounds,
946 int characters) { 984 int characters) {
947 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
948 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 985 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
949 if (check_bounds) { 986 if (check_bounds) {
950 CheckPosition(cp_offset + characters - 1, on_end_of_input); 987 if (cp_offset >= 0) {
988 CheckPosition(cp_offset + characters - 1, on_end_of_input);
989 } else {
990 CheckPosition(cp_offset, on_end_of_input);
991 }
951 } 992 }
952 LoadCurrentCharacterUnchecked(cp_offset, characters); 993 LoadCurrentCharacterUnchecked(cp_offset, characters);
953 } 994 }
954 995
955 996
956 void RegExpMacroAssemblerIA32::PopCurrentPosition() { 997 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
957 Pop(edi); 998 Pop(edi);
958 } 999 }
959 1000
960 1001
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 DCHECK(register_index < (1<<30)); 1134 DCHECK(register_index < (1<<30));
1094 if (num_registers_ <= register_index) { 1135 if (num_registers_ <= register_index) {
1095 num_registers_ = register_index + 1; 1136 num_registers_ = register_index + 1;
1096 } 1137 }
1097 return Operand(ebp, kRegisterZero - register_index * kPointerSize); 1138 return Operand(ebp, kRegisterZero - register_index * kPointerSize);
1098 } 1139 }
1099 1140
1100 1141
1101 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, 1142 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset,
1102 Label* on_outside_input) { 1143 Label* on_outside_input) {
1103 __ cmp(edi, -cp_offset * char_size()); 1144 if (cp_offset >= 0) {
1104 BranchOrBacktrack(greater_equal, on_outside_input); 1145 __ cmp(edi, -cp_offset * char_size());
1146 BranchOrBacktrack(greater_equal, on_outside_input);
1147 } else {
1148 __ lea(eax, Operand(esi, edi, times_1, cp_offset * char_size()));
1149 for (int i = 0; i < char_size(); i++) {
1150 __ add(eax, Operand(ebp, kStartIndex));
1151 }
1152 __ cmp(eax, Operand(ebp, kInputStart));
1153 BranchOrBacktrack(less, on_outside_input);
1154 }
1105 } 1155 }
1106 1156
1107 1157
1108 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, 1158 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
1109 Label* to) { 1159 Label* to) {
1110 if (condition < 0) { // No condition 1160 if (condition < 0) { // No condition
1111 if (to == NULL) { 1161 if (to == NULL) {
1112 Backtrack(); 1162 Backtrack();
1113 return; 1163 return;
1114 } 1164 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 1269
1220 1270
1221 #undef __ 1271 #undef __
1222 1272
1223 #endif // V8_INTERPRETED_REGEXP 1273 #endif // V8_INTERPRETED_REGEXP
1224 1274
1225 } // namespace internal 1275 } // namespace internal
1226 } // namespace v8 1276 } // namespace v8
1227 1277
1228 #endif // V8_TARGET_ARCH_IA32 1278 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698