OLD | NEW |
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 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "cpu-profiler.h" | 9 #include "cpu-profiler.h" |
10 #include "unicode.h" | 10 #include "unicode.h" |
11 #include "log.h" | 11 #include "log.h" |
12 #include "regexp-stack.h" | 12 #include "regexp-stack.h" |
13 #include "macro-assembler.h" | 13 #include "macro-assembler.h" |
14 #include "regexp-macro-assembler.h" | 14 #include "regexp-macro-assembler.h" |
15 #include "ia32/regexp-macro-assembler-ia32.h" | 15 #include "x87/regexp-macro-assembler-x87.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 #ifndef V8_INTERPRETED_REGEXP | 20 #ifndef V8_INTERPRETED_REGEXP |
21 /* | 21 /* |
22 * This assembler uses the following register assignment convention | 22 * This assembler uses the following register assignment convention |
23 * - edx : Current character. Must be loaded using LoadCurrentCharacter | 23 * - edx : Current character. Must be loaded using LoadCurrentCharacter |
24 * before using any of the dispatch methods. Temporarily stores the | 24 * before using any of the dispatch methods. Temporarily stores the |
25 * index of capture start after a matching pass for a global regexp. | 25 * index of capture start after a matching pass for a global regexp. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 * Address start, | 70 * Address start, |
71 * Address end, | 71 * Address end, |
72 * int* capture_output_array, | 72 * int* capture_output_array, |
73 * bool at_start, | 73 * bool at_start, |
74 * byte* stack_area_base, | 74 * byte* stack_area_base, |
75 * bool direct_call) | 75 * bool direct_call) |
76 */ | 76 */ |
77 | 77 |
78 #define __ ACCESS_MASM(masm_) | 78 #define __ ACCESS_MASM(masm_) |
79 | 79 |
80 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( | 80 RegExpMacroAssemblerX87::RegExpMacroAssemblerX87( |
81 Mode mode, | 81 Mode mode, |
82 int registers_to_save, | 82 int registers_to_save, |
83 Zone* zone) | 83 Zone* zone) |
84 : NativeRegExpMacroAssembler(zone), | 84 : NativeRegExpMacroAssembler(zone), |
85 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), | 85 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), |
86 mode_(mode), | 86 mode_(mode), |
87 num_registers_(registers_to_save), | 87 num_registers_(registers_to_save), |
88 num_saved_registers_(registers_to_save), | 88 num_saved_registers_(registers_to_save), |
89 entry_label_(), | 89 entry_label_(), |
90 start_label_(), | 90 start_label_(), |
91 success_label_(), | 91 success_label_(), |
92 backtrack_label_(), | 92 backtrack_label_(), |
93 exit_label_() { | 93 exit_label_() { |
94 ASSERT_EQ(0, registers_to_save % 2); | 94 ASSERT_EQ(0, registers_to_save % 2); |
95 __ jmp(&entry_label_); // We'll write the entry code later. | 95 __ jmp(&entry_label_); // We'll write the entry code later. |
96 __ bind(&start_label_); // And then continue from here. | 96 __ bind(&start_label_); // And then continue from here. |
97 } | 97 } |
98 | 98 |
99 | 99 |
100 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { | 100 RegExpMacroAssemblerX87::~RegExpMacroAssemblerX87() { |
101 delete masm_; | 101 delete masm_; |
102 // Unuse labels in case we throw away the assembler without calling GetCode. | 102 // Unuse labels in case we throw away the assembler without calling GetCode. |
103 entry_label_.Unuse(); | 103 entry_label_.Unuse(); |
104 start_label_.Unuse(); | 104 start_label_.Unuse(); |
105 success_label_.Unuse(); | 105 success_label_.Unuse(); |
106 backtrack_label_.Unuse(); | 106 backtrack_label_.Unuse(); |
107 exit_label_.Unuse(); | 107 exit_label_.Unuse(); |
108 check_preempt_label_.Unuse(); | 108 check_preempt_label_.Unuse(); |
109 stack_overflow_label_.Unuse(); | 109 stack_overflow_label_.Unuse(); |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 int RegExpMacroAssemblerIA32::stack_limit_slack() { | 113 int RegExpMacroAssemblerX87::stack_limit_slack() { |
114 return RegExpStack::kStackLimitSlack; | 114 return RegExpStack::kStackLimitSlack; |
115 } | 115 } |
116 | 116 |
117 | 117 |
118 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { | 118 void RegExpMacroAssemblerX87::AdvanceCurrentPosition(int by) { |
119 if (by != 0) { | 119 if (by != 0) { |
120 __ add(edi, Immediate(by * char_size())); | 120 __ add(edi, Immediate(by * char_size())); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { | 125 void RegExpMacroAssemblerX87::AdvanceRegister(int reg, int by) { |
126 ASSERT(reg >= 0); | 126 ASSERT(reg >= 0); |
127 ASSERT(reg < num_registers_); | 127 ASSERT(reg < num_registers_); |
128 if (by != 0) { | 128 if (by != 0) { |
129 __ add(register_location(reg), Immediate(by)); | 129 __ add(register_location(reg), Immediate(by)); |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 void RegExpMacroAssemblerIA32::Backtrack() { | 134 void RegExpMacroAssemblerX87::Backtrack() { |
135 CheckPreemption(); | 135 CheckPreemption(); |
136 // Pop Code* offset from backtrack stack, add Code* and jump to location. | 136 // Pop Code* offset from backtrack stack, add Code* and jump to location. |
137 Pop(ebx); | 137 Pop(ebx); |
138 __ add(ebx, Immediate(masm_->CodeObject())); | 138 __ add(ebx, Immediate(masm_->CodeObject())); |
139 __ jmp(ebx); | 139 __ jmp(ebx); |
140 } | 140 } |
141 | 141 |
142 | 142 |
143 void RegExpMacroAssemblerIA32::Bind(Label* label) { | 143 void RegExpMacroAssemblerX87::Bind(Label* label) { |
144 __ bind(label); | 144 __ bind(label); |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { | 148 void RegExpMacroAssemblerX87::CheckCharacter(uint32_t c, Label* on_equal) { |
149 __ cmp(current_character(), c); | 149 __ cmp(current_character(), c); |
150 BranchOrBacktrack(equal, on_equal); | 150 BranchOrBacktrack(equal, on_equal); |
151 } | 151 } |
152 | 152 |
153 | 153 |
154 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { | 154 void RegExpMacroAssemblerX87::CheckCharacterGT(uc16 limit, Label* on_greater) { |
155 __ cmp(current_character(), limit); | 155 __ cmp(current_character(), limit); |
156 BranchOrBacktrack(greater, on_greater); | 156 BranchOrBacktrack(greater, on_greater); |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { | 160 void RegExpMacroAssemblerX87::CheckAtStart(Label* on_at_start) { |
161 Label not_at_start; | 161 Label not_at_start; |
162 // Did we start the match at the start of the string at all? | 162 // Did we start the match at the start of the string at all? |
163 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 163 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
164 BranchOrBacktrack(not_equal, ¬_at_start); | 164 BranchOrBacktrack(not_equal, ¬_at_start); |
165 // If we did, are we still at the start of the input? | 165 // If we did, are we still at the start of the input? |
166 __ lea(eax, Operand(esi, edi, times_1, 0)); | 166 __ lea(eax, Operand(esi, edi, times_1, 0)); |
167 __ cmp(eax, Operand(ebp, kInputStart)); | 167 __ cmp(eax, Operand(ebp, kInputStart)); |
168 BranchOrBacktrack(equal, on_at_start); | 168 BranchOrBacktrack(equal, on_at_start); |
169 __ bind(¬_at_start); | 169 __ bind(¬_at_start); |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) { | 173 void RegExpMacroAssemblerX87::CheckNotAtStart(Label* on_not_at_start) { |
174 // Did we start the match at the start of the string at all? | 174 // Did we start the match at the start of the string at all? |
175 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 175 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
176 BranchOrBacktrack(not_equal, on_not_at_start); | 176 BranchOrBacktrack(not_equal, on_not_at_start); |
177 // If we did, are we still at the start of the input? | 177 // If we did, are we still at the start of the input? |
178 __ lea(eax, Operand(esi, edi, times_1, 0)); | 178 __ lea(eax, Operand(esi, edi, times_1, 0)); |
179 __ cmp(eax, Operand(ebp, kInputStart)); | 179 __ cmp(eax, Operand(ebp, kInputStart)); |
180 BranchOrBacktrack(not_equal, on_not_at_start); | 180 BranchOrBacktrack(not_equal, on_not_at_start); |
181 } | 181 } |
182 | 182 |
183 | 183 |
184 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { | 184 void RegExpMacroAssemblerX87::CheckCharacterLT(uc16 limit, Label* on_less) { |
185 __ cmp(current_character(), limit); | 185 __ cmp(current_character(), limit); |
186 BranchOrBacktrack(less, on_less); | 186 BranchOrBacktrack(less, on_less); |
187 } | 187 } |
188 | 188 |
189 | 189 |
190 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 190 void RegExpMacroAssemblerX87::CheckGreedyLoop(Label* on_equal) { |
191 Label fallthrough; | 191 Label fallthrough; |
192 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 192 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
193 __ j(not_equal, &fallthrough); | 193 __ j(not_equal, &fallthrough); |
194 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 194 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
195 BranchOrBacktrack(no_condition, on_equal); | 195 BranchOrBacktrack(no_condition, on_equal); |
196 __ bind(&fallthrough); | 196 __ bind(&fallthrough); |
197 } | 197 } |
198 | 198 |
199 | 199 |
200 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 200 void RegExpMacroAssemblerX87::CheckNotBackReferenceIgnoreCase( |
201 int start_reg, | 201 int start_reg, |
202 Label* on_no_match) { | 202 Label* on_no_match) { |
203 Label fallthrough; | 203 Label fallthrough; |
204 __ mov(edx, register_location(start_reg)); // Index of start of capture | 204 __ mov(edx, register_location(start_reg)); // Index of start of capture |
205 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture | 205 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture |
206 __ sub(ebx, edx); // Length of capture. | 206 __ sub(ebx, edx); // Length of capture. |
207 | 207 |
208 // The length of a capture should not be negative. This can only happen | 208 // The length of a capture should not be negative. This can only happen |
209 // if the end of the capture is unrecorded, or at a point earlier than | 209 // if the end of the capture is unrecorded, or at a point earlier than |
210 // the start of the capture. | 210 // the start of the capture. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 // Check if function returned non-zero for success or zero for failure. | 327 // Check if function returned non-zero for success or zero for failure. |
328 __ or_(eax, eax); | 328 __ or_(eax, eax); |
329 BranchOrBacktrack(zero, on_no_match); | 329 BranchOrBacktrack(zero, on_no_match); |
330 // On success, increment position by length of capture. | 330 // On success, increment position by length of capture. |
331 __ add(edi, ebx); | 331 __ add(edi, ebx); |
332 } | 332 } |
333 __ bind(&fallthrough); | 333 __ bind(&fallthrough); |
334 } | 334 } |
335 | 335 |
336 | 336 |
337 void RegExpMacroAssemblerIA32::CheckNotBackReference( | 337 void RegExpMacroAssemblerX87::CheckNotBackReference( |
338 int start_reg, | 338 int start_reg, |
339 Label* on_no_match) { | 339 Label* on_no_match) { |
340 Label fallthrough; | 340 Label fallthrough; |
341 Label success; | 341 Label success; |
342 Label fail; | 342 Label fail; |
343 | 343 |
344 // Find length of back-referenced capture. | 344 // Find length of back-referenced capture. |
345 __ mov(edx, register_location(start_reg)); | 345 __ mov(edx, register_location(start_reg)); |
346 __ mov(eax, register_location(start_reg + 1)); | 346 __ mov(eax, register_location(start_reg + 1)); |
347 __ sub(eax, edx); // Length to check. | 347 __ sub(eax, edx); // Length to check. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 // Move current character position to position after match. | 391 // Move current character position to position after match. |
392 __ mov(edi, ecx); | 392 __ mov(edi, ecx); |
393 __ sub(edi, esi); | 393 __ sub(edi, esi); |
394 // Restore backtrack stackpointer. | 394 // Restore backtrack stackpointer. |
395 __ pop(backtrack_stackpointer()); | 395 __ pop(backtrack_stackpointer()); |
396 | 396 |
397 __ bind(&fallthrough); | 397 __ bind(&fallthrough); |
398 } | 398 } |
399 | 399 |
400 | 400 |
401 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, | 401 void RegExpMacroAssemblerX87::CheckNotCharacter(uint32_t c, |
402 Label* on_not_equal) { | 402 Label* on_not_equal) { |
403 __ cmp(current_character(), c); | 403 __ cmp(current_character(), c); |
404 BranchOrBacktrack(not_equal, on_not_equal); | 404 BranchOrBacktrack(not_equal, on_not_equal); |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, | 408 void RegExpMacroAssemblerX87::CheckCharacterAfterAnd(uint32_t c, |
409 uint32_t mask, | 409 uint32_t mask, |
410 Label* on_equal) { | 410 Label* on_equal) { |
411 if (c == 0) { | 411 if (c == 0) { |
412 __ test(current_character(), Immediate(mask)); | 412 __ test(current_character(), Immediate(mask)); |
413 } else { | 413 } else { |
414 __ mov(eax, mask); | 414 __ mov(eax, mask); |
415 __ and_(eax, current_character()); | 415 __ and_(eax, current_character()); |
416 __ cmp(eax, c); | 416 __ cmp(eax, c); |
417 } | 417 } |
418 BranchOrBacktrack(equal, on_equal); | 418 BranchOrBacktrack(equal, on_equal); |
419 } | 419 } |
420 | 420 |
421 | 421 |
422 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c, | 422 void RegExpMacroAssemblerX87::CheckNotCharacterAfterAnd(uint32_t c, |
423 uint32_t mask, | 423 uint32_t mask, |
424 Label* on_not_equal) { | 424 Label* on_not_equal) { |
425 if (c == 0) { | 425 if (c == 0) { |
426 __ test(current_character(), Immediate(mask)); | 426 __ test(current_character(), Immediate(mask)); |
427 } else { | 427 } else { |
428 __ mov(eax, mask); | 428 __ mov(eax, mask); |
429 __ and_(eax, current_character()); | 429 __ and_(eax, current_character()); |
430 __ cmp(eax, c); | 430 __ cmp(eax, c); |
431 } | 431 } |
432 BranchOrBacktrack(not_equal, on_not_equal); | 432 BranchOrBacktrack(not_equal, on_not_equal); |
433 } | 433 } |
434 | 434 |
435 | 435 |
436 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( | 436 void RegExpMacroAssemblerX87::CheckNotCharacterAfterMinusAnd( |
437 uc16 c, | 437 uc16 c, |
438 uc16 minus, | 438 uc16 minus, |
439 uc16 mask, | 439 uc16 mask, |
440 Label* on_not_equal) { | 440 Label* on_not_equal) { |
441 ASSERT(minus < String::kMaxUtf16CodeUnit); | 441 ASSERT(minus < String::kMaxUtf16CodeUnit); |
442 __ lea(eax, Operand(current_character(), -minus)); | 442 __ lea(eax, Operand(current_character(), -minus)); |
443 if (c == 0) { | 443 if (c == 0) { |
444 __ test(eax, Immediate(mask)); | 444 __ test(eax, Immediate(mask)); |
445 } else { | 445 } else { |
446 __ and_(eax, mask); | 446 __ and_(eax, mask); |
447 __ cmp(eax, c); | 447 __ cmp(eax, c); |
448 } | 448 } |
449 BranchOrBacktrack(not_equal, on_not_equal); | 449 BranchOrBacktrack(not_equal, on_not_equal); |
450 } | 450 } |
451 | 451 |
452 | 452 |
453 void RegExpMacroAssemblerIA32::CheckCharacterInRange( | 453 void RegExpMacroAssemblerX87::CheckCharacterInRange( |
454 uc16 from, | 454 uc16 from, |
455 uc16 to, | 455 uc16 to, |
456 Label* on_in_range) { | 456 Label* on_in_range) { |
457 __ lea(eax, Operand(current_character(), -from)); | 457 __ lea(eax, Operand(current_character(), -from)); |
458 __ cmp(eax, to - from); | 458 __ cmp(eax, to - from); |
459 BranchOrBacktrack(below_equal, on_in_range); | 459 BranchOrBacktrack(below_equal, on_in_range); |
460 } | 460 } |
461 | 461 |
462 | 462 |
463 void RegExpMacroAssemblerIA32::CheckCharacterNotInRange( | 463 void RegExpMacroAssemblerX87::CheckCharacterNotInRange( |
464 uc16 from, | 464 uc16 from, |
465 uc16 to, | 465 uc16 to, |
466 Label* on_not_in_range) { | 466 Label* on_not_in_range) { |
467 __ lea(eax, Operand(current_character(), -from)); | 467 __ lea(eax, Operand(current_character(), -from)); |
468 __ cmp(eax, to - from); | 468 __ cmp(eax, to - from); |
469 BranchOrBacktrack(above, on_not_in_range); | 469 BranchOrBacktrack(above, on_not_in_range); |
470 } | 470 } |
471 | 471 |
472 | 472 |
473 void RegExpMacroAssemblerIA32::CheckBitInTable( | 473 void RegExpMacroAssemblerX87::CheckBitInTable( |
474 Handle<ByteArray> table, | 474 Handle<ByteArray> table, |
475 Label* on_bit_set) { | 475 Label* on_bit_set) { |
476 __ mov(eax, Immediate(table)); | 476 __ mov(eax, Immediate(table)); |
477 Register index = current_character(); | 477 Register index = current_character(); |
478 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { | 478 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { |
479 __ mov(ebx, kTableSize - 1); | 479 __ mov(ebx, kTableSize - 1); |
480 __ and_(ebx, current_character()); | 480 __ and_(ebx, current_character()); |
481 index = ebx; | 481 index = ebx; |
482 } | 482 } |
483 __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); | 483 __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); |
484 BranchOrBacktrack(not_equal, on_bit_set); | 484 BranchOrBacktrack(not_equal, on_bit_set); |
485 } | 485 } |
486 | 486 |
487 | 487 |
488 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, | 488 bool RegExpMacroAssemblerX87::CheckSpecialCharacterClass(uc16 type, |
489 Label* on_no_match) { | 489 Label* on_no_match) { |
490 // Range checks (c in min..max) are generally implemented by an unsigned | 490 // Range checks (c in min..max) are generally implemented by an unsigned |
491 // (c - min) <= (max - min) check | 491 // (c - min) <= (max - min) check |
492 switch (type) { | 492 switch (type) { |
493 case 's': | 493 case 's': |
494 // Match space-characters | 494 // Match space-characters |
495 if (mode_ == ASCII) { | 495 if (mode_ == ASCII) { |
496 // One byte space characters are '\t'..'\r', ' ' and \u00a0. | 496 // One byte space characters are '\t'..'\r', ' ' and \u00a0. |
497 Label success; | 497 Label success; |
498 __ cmp(current_character(), ' '); | 498 __ cmp(current_character(), ' '); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 } | 599 } |
600 return true; | 600 return true; |
601 } | 601 } |
602 // No custom implementation (yet): s(UC16), S(UC16). | 602 // No custom implementation (yet): s(UC16), S(UC16). |
603 default: | 603 default: |
604 return false; | 604 return false; |
605 } | 605 } |
606 } | 606 } |
607 | 607 |
608 | 608 |
609 void RegExpMacroAssemblerIA32::Fail() { | 609 void RegExpMacroAssemblerX87::Fail() { |
610 STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. | 610 STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. |
611 if (!global()) { | 611 if (!global()) { |
612 __ Move(eax, Immediate(FAILURE)); | 612 __ Move(eax, Immediate(FAILURE)); |
613 } | 613 } |
614 __ jmp(&exit_label_); | 614 __ jmp(&exit_label_); |
615 } | 615 } |
616 | 616 |
617 | 617 |
618 Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { | 618 Handle<HeapObject> RegExpMacroAssemblerX87::GetCode(Handle<String> source) { |
619 Label return_eax; | 619 Label return_eax; |
620 // Finalize code - write the entry point code now we know how many | 620 // Finalize code - write the entry point code now we know how many |
621 // registers we need. | 621 // registers we need. |
622 | 622 |
623 // Entry code: | 623 // Entry code: |
624 __ bind(&entry_label_); | 624 __ bind(&entry_label_); |
625 | 625 |
626 // Tell the system that we have a stack frame. Because the type is MANUAL, no | 626 // Tell the system that we have a stack frame. Because the type is MANUAL, no |
627 // code is generated. | 627 // code is generated. |
628 FrameScope scope(masm_, StackFrame::MANUAL); | 628 FrameScope scope(masm_, StackFrame::MANUAL); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 masm_->GetCode(&code_desc); | 901 masm_->GetCode(&code_desc); |
902 Handle<Code> code = | 902 Handle<Code> code = |
903 isolate()->factory()->NewCode(code_desc, | 903 isolate()->factory()->NewCode(code_desc, |
904 Code::ComputeFlags(Code::REGEXP), | 904 Code::ComputeFlags(Code::REGEXP), |
905 masm_->CodeObject()); | 905 masm_->CodeObject()); |
906 PROFILE(isolate(), RegExpCodeCreateEvent(*code, *source)); | 906 PROFILE(isolate(), RegExpCodeCreateEvent(*code, *source)); |
907 return Handle<HeapObject>::cast(code); | 907 return Handle<HeapObject>::cast(code); |
908 } | 908 } |
909 | 909 |
910 | 910 |
911 void RegExpMacroAssemblerIA32::GoTo(Label* to) { | 911 void RegExpMacroAssemblerX87::GoTo(Label* to) { |
912 BranchOrBacktrack(no_condition, to); | 912 BranchOrBacktrack(no_condition, to); |
913 } | 913 } |
914 | 914 |
915 | 915 |
916 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg, | 916 void RegExpMacroAssemblerX87::IfRegisterGE(int reg, |
917 int comparand, | 917 int comparand, |
918 Label* if_ge) { | 918 Label* if_ge) { |
919 __ cmp(register_location(reg), Immediate(comparand)); | 919 __ cmp(register_location(reg), Immediate(comparand)); |
920 BranchOrBacktrack(greater_equal, if_ge); | 920 BranchOrBacktrack(greater_equal, if_ge); |
921 } | 921 } |
922 | 922 |
923 | 923 |
924 void RegExpMacroAssemblerIA32::IfRegisterLT(int reg, | 924 void RegExpMacroAssemblerX87::IfRegisterLT(int reg, |
925 int comparand, | 925 int comparand, |
926 Label* if_lt) { | 926 Label* if_lt) { |
927 __ cmp(register_location(reg), Immediate(comparand)); | 927 __ cmp(register_location(reg), Immediate(comparand)); |
928 BranchOrBacktrack(less, if_lt); | 928 BranchOrBacktrack(less, if_lt); |
929 } | 929 } |
930 | 930 |
931 | 931 |
932 void RegExpMacroAssemblerIA32::IfRegisterEqPos(int reg, | 932 void RegExpMacroAssemblerX87::IfRegisterEqPos(int reg, |
933 Label* if_eq) { | 933 Label* if_eq) { |
934 __ cmp(edi, register_location(reg)); | 934 __ cmp(edi, register_location(reg)); |
935 BranchOrBacktrack(equal, if_eq); | 935 BranchOrBacktrack(equal, if_eq); |
936 } | 936 } |
937 | 937 |
938 | 938 |
939 RegExpMacroAssembler::IrregexpImplementation | 939 RegExpMacroAssembler::IrregexpImplementation |
940 RegExpMacroAssemblerIA32::Implementation() { | 940 RegExpMacroAssemblerX87::Implementation() { |
941 return kIA32Implementation; | 941 return kX87Implementation; |
942 } | 942 } |
943 | 943 |
944 | 944 |
945 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 945 void RegExpMacroAssemblerX87::LoadCurrentCharacter(int cp_offset, |
946 Label* on_end_of_input, | 946 Label* on_end_of_input, |
947 bool check_bounds, | 947 bool check_bounds, |
948 int characters) { | 948 int characters) { |
949 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. | 949 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. |
950 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 950 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
951 if (check_bounds) { | 951 if (check_bounds) { |
952 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 952 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
953 } | 953 } |
954 LoadCurrentCharacterUnchecked(cp_offset, characters); | 954 LoadCurrentCharacterUnchecked(cp_offset, characters); |
955 } | 955 } |
956 | 956 |
957 | 957 |
958 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 958 void RegExpMacroAssemblerX87::PopCurrentPosition() { |
959 Pop(edi); | 959 Pop(edi); |
960 } | 960 } |
961 | 961 |
962 | 962 |
963 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { | 963 void RegExpMacroAssemblerX87::PopRegister(int register_index) { |
964 Pop(eax); | 964 Pop(eax); |
965 __ mov(register_location(register_index), eax); | 965 __ mov(register_location(register_index), eax); |
966 } | 966 } |
967 | 967 |
968 | 968 |
969 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) { | 969 void RegExpMacroAssemblerX87::PushBacktrack(Label* label) { |
970 Push(Immediate::CodeRelativeOffset(label)); | 970 Push(Immediate::CodeRelativeOffset(label)); |
971 CheckStackLimit(); | 971 CheckStackLimit(); |
972 } | 972 } |
973 | 973 |
974 | 974 |
975 void RegExpMacroAssemblerIA32::PushCurrentPosition() { | 975 void RegExpMacroAssemblerX87::PushCurrentPosition() { |
976 Push(edi); | 976 Push(edi); |
977 } | 977 } |
978 | 978 |
979 | 979 |
980 void RegExpMacroAssemblerIA32::PushRegister(int register_index, | 980 void RegExpMacroAssemblerX87::PushRegister(int register_index, |
981 StackCheckFlag check_stack_limit) { | 981 StackCheckFlag check_stack_limit) { |
982 __ mov(eax, register_location(register_index)); | 982 __ mov(eax, register_location(register_index)); |
983 Push(eax); | 983 Push(eax); |
984 if (check_stack_limit) CheckStackLimit(); | 984 if (check_stack_limit) CheckStackLimit(); |
985 } | 985 } |
986 | 986 |
987 | 987 |
988 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) { | 988 void RegExpMacroAssemblerX87::ReadCurrentPositionFromRegister(int reg) { |
989 __ mov(edi, register_location(reg)); | 989 __ mov(edi, register_location(reg)); |
990 } | 990 } |
991 | 991 |
992 | 992 |
993 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) { | 993 void RegExpMacroAssemblerX87::ReadStackPointerFromRegister(int reg) { |
994 __ mov(backtrack_stackpointer(), register_location(reg)); | 994 __ mov(backtrack_stackpointer(), register_location(reg)); |
995 __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); | 995 __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); |
996 } | 996 } |
997 | 997 |
998 void RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(int by) { | 998 void RegExpMacroAssemblerX87::SetCurrentPositionFromEnd(int by) { |
999 Label after_position; | 999 Label after_position; |
1000 __ cmp(edi, -by * char_size()); | 1000 __ cmp(edi, -by * char_size()); |
1001 __ j(greater_equal, &after_position, Label::kNear); | 1001 __ j(greater_equal, &after_position, Label::kNear); |
1002 __ mov(edi, -by * char_size()); | 1002 __ mov(edi, -by * char_size()); |
1003 // On RegExp code entry (where this operation is used), the character before | 1003 // On RegExp code entry (where this operation is used), the character before |
1004 // the current position is expected to be already loaded. | 1004 // the current position is expected to be already loaded. |
1005 // We have advanced the position, so it's safe to read backwards. | 1005 // We have advanced the position, so it's safe to read backwards. |
1006 LoadCurrentCharacterUnchecked(-1, 1); | 1006 LoadCurrentCharacterUnchecked(-1, 1); |
1007 __ bind(&after_position); | 1007 __ bind(&after_position); |
1008 } | 1008 } |
1009 | 1009 |
1010 | 1010 |
1011 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { | 1011 void RegExpMacroAssemblerX87::SetRegister(int register_index, int to) { |
1012 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 1012 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! |
1013 __ mov(register_location(register_index), Immediate(to)); | 1013 __ mov(register_location(register_index), Immediate(to)); |
1014 } | 1014 } |
1015 | 1015 |
1016 | 1016 |
1017 bool RegExpMacroAssemblerIA32::Succeed() { | 1017 bool RegExpMacroAssemblerX87::Succeed() { |
1018 __ jmp(&success_label_); | 1018 __ jmp(&success_label_); |
1019 return global(); | 1019 return global(); |
1020 } | 1020 } |
1021 | 1021 |
1022 | 1022 |
1023 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg, | 1023 void RegExpMacroAssemblerX87::WriteCurrentPositionToRegister(int reg, |
1024 int cp_offset) { | 1024 int cp_offset) { |
1025 if (cp_offset == 0) { | 1025 if (cp_offset == 0) { |
1026 __ mov(register_location(reg), edi); | 1026 __ mov(register_location(reg), edi); |
1027 } else { | 1027 } else { |
1028 __ lea(eax, Operand(edi, cp_offset * char_size())); | 1028 __ lea(eax, Operand(edi, cp_offset * char_size())); |
1029 __ mov(register_location(reg), eax); | 1029 __ mov(register_location(reg), eax); |
1030 } | 1030 } |
1031 } | 1031 } |
1032 | 1032 |
1033 | 1033 |
1034 void RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { | 1034 void RegExpMacroAssemblerX87::ClearRegisters(int reg_from, int reg_to) { |
1035 ASSERT(reg_from <= reg_to); | 1035 ASSERT(reg_from <= reg_to); |
1036 __ mov(eax, Operand(ebp, kInputStartMinusOne)); | 1036 __ mov(eax, Operand(ebp, kInputStartMinusOne)); |
1037 for (int reg = reg_from; reg <= reg_to; reg++) { | 1037 for (int reg = reg_from; reg <= reg_to; reg++) { |
1038 __ mov(register_location(reg), eax); | 1038 __ mov(register_location(reg), eax); |
1039 } | 1039 } |
1040 } | 1040 } |
1041 | 1041 |
1042 | 1042 |
1043 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { | 1043 void RegExpMacroAssemblerX87::WriteStackPointerToRegister(int reg) { |
1044 __ mov(eax, backtrack_stackpointer()); | 1044 __ mov(eax, backtrack_stackpointer()); |
1045 __ sub(eax, Operand(ebp, kStackHighEnd)); | 1045 __ sub(eax, Operand(ebp, kStackHighEnd)); |
1046 __ mov(register_location(reg), eax); | 1046 __ mov(register_location(reg), eax); |
1047 } | 1047 } |
1048 | 1048 |
1049 | 1049 |
1050 // Private methods: | 1050 // Private methods: |
1051 | 1051 |
1052 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { | 1052 void RegExpMacroAssemblerX87::CallCheckStackGuardState(Register scratch) { |
1053 static const int num_arguments = 3; | 1053 static const int num_arguments = 3; |
1054 __ PrepareCallCFunction(num_arguments, scratch); | 1054 __ PrepareCallCFunction(num_arguments, scratch); |
1055 // RegExp code frame pointer. | 1055 // RegExp code frame pointer. |
1056 __ mov(Operand(esp, 2 * kPointerSize), ebp); | 1056 __ mov(Operand(esp, 2 * kPointerSize), ebp); |
1057 // Code* of self. | 1057 // Code* of self. |
1058 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); | 1058 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); |
1059 // Next address on the stack (will be address of return address). | 1059 // Next address on the stack (will be address of return address). |
1060 __ lea(eax, Operand(esp, -kPointerSize)); | 1060 __ lea(eax, Operand(esp, -kPointerSize)); |
1061 __ mov(Operand(esp, 0 * kPointerSize), eax); | 1061 __ mov(Operand(esp, 0 * kPointerSize), eax); |
1062 ExternalReference check_stack_guard = | 1062 ExternalReference check_stack_guard = |
1063 ExternalReference::re_check_stack_guard_state(isolate()); | 1063 ExternalReference::re_check_stack_guard_state(isolate()); |
1064 __ CallCFunction(check_stack_guard, num_arguments); | 1064 __ CallCFunction(check_stack_guard, num_arguments); |
1065 } | 1065 } |
1066 | 1066 |
1067 | 1067 |
1068 // Helper function for reading a value out of a stack frame. | 1068 // Helper function for reading a value out of a stack frame. |
1069 template <typename T> | 1069 template <typename T> |
1070 static T& frame_entry(Address re_frame, int frame_offset) { | 1070 static T& frame_entry(Address re_frame, int frame_offset) { |
1071 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 1071 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
1072 } | 1072 } |
1073 | 1073 |
1074 | 1074 |
1075 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, | 1075 int RegExpMacroAssemblerX87::CheckStackGuardState(Address* return_address, |
1076 Code* re_code, | 1076 Code* re_code, |
1077 Address re_frame) { | 1077 Address re_frame) { |
1078 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); | 1078 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); |
1079 if (isolate->stack_guard()->IsStackOverflow()) { | 1079 if (isolate->stack_guard()->IsStackOverflow()) { |
1080 isolate->StackOverflow(); | 1080 isolate->StackOverflow(); |
1081 return EXCEPTION; | 1081 return EXCEPTION; |
1082 } | 1082 } |
1083 | 1083 |
1084 // If not real stack overflow the stack guard was used to interrupt | 1084 // If not real stack overflow the stack guard was used to interrupt |
1085 // execution for another purpose. | 1085 // execution for another purpose. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 // Subject string might have been a ConsString that underwent | 1163 // Subject string might have been a ConsString that underwent |
1164 // short-circuiting during GC. That will not change start_address but | 1164 // short-circuiting during GC. That will not change start_address but |
1165 // will change pointer inside the subject handle. | 1165 // will change pointer inside the subject handle. |
1166 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1166 frame_entry<const String*>(re_frame, kInputString) = *subject; |
1167 } | 1167 } |
1168 | 1168 |
1169 return 0; | 1169 return 0; |
1170 } | 1170 } |
1171 | 1171 |
1172 | 1172 |
1173 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { | 1173 Operand RegExpMacroAssemblerX87::register_location(int register_index) { |
1174 ASSERT(register_index < (1<<30)); | 1174 ASSERT(register_index < (1<<30)); |
1175 if (num_registers_ <= register_index) { | 1175 if (num_registers_ <= register_index) { |
1176 num_registers_ = register_index + 1; | 1176 num_registers_ = register_index + 1; |
1177 } | 1177 } |
1178 return Operand(ebp, kRegisterZero - register_index * kPointerSize); | 1178 return Operand(ebp, kRegisterZero - register_index * kPointerSize); |
1179 } | 1179 } |
1180 | 1180 |
1181 | 1181 |
1182 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, | 1182 void RegExpMacroAssemblerX87::CheckPosition(int cp_offset, |
1183 Label* on_outside_input) { | 1183 Label* on_outside_input) { |
1184 __ cmp(edi, -cp_offset * char_size()); | 1184 __ cmp(edi, -cp_offset * char_size()); |
1185 BranchOrBacktrack(greater_equal, on_outside_input); | 1185 BranchOrBacktrack(greater_equal, on_outside_input); |
1186 } | 1186 } |
1187 | 1187 |
1188 | 1188 |
1189 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, | 1189 void RegExpMacroAssemblerX87::BranchOrBacktrack(Condition condition, |
1190 Label* to) { | 1190 Label* to) { |
1191 if (condition < 0) { // No condition | 1191 if (condition < 0) { // No condition |
1192 if (to == NULL) { | 1192 if (to == NULL) { |
1193 Backtrack(); | 1193 Backtrack(); |
1194 return; | 1194 return; |
1195 } | 1195 } |
1196 __ jmp(to); | 1196 __ jmp(to); |
1197 return; | 1197 return; |
1198 } | 1198 } |
1199 if (to == NULL) { | 1199 if (to == NULL) { |
1200 __ j(condition, &backtrack_label_); | 1200 __ j(condition, &backtrack_label_); |
1201 return; | 1201 return; |
1202 } | 1202 } |
1203 __ j(condition, to); | 1203 __ j(condition, to); |
1204 } | 1204 } |
1205 | 1205 |
1206 | 1206 |
1207 void RegExpMacroAssemblerIA32::SafeCall(Label* to) { | 1207 void RegExpMacroAssemblerX87::SafeCall(Label* to) { |
1208 Label return_to; | 1208 Label return_to; |
1209 __ push(Immediate::CodeRelativeOffset(&return_to)); | 1209 __ push(Immediate::CodeRelativeOffset(&return_to)); |
1210 __ jmp(to); | 1210 __ jmp(to); |
1211 __ bind(&return_to); | 1211 __ bind(&return_to); |
1212 } | 1212 } |
1213 | 1213 |
1214 | 1214 |
1215 void RegExpMacroAssemblerIA32::SafeReturn() { | 1215 void RegExpMacroAssemblerX87::SafeReturn() { |
1216 __ pop(ebx); | 1216 __ pop(ebx); |
1217 __ add(ebx, Immediate(masm_->CodeObject())); | 1217 __ add(ebx, Immediate(masm_->CodeObject())); |
1218 __ jmp(ebx); | 1218 __ jmp(ebx); |
1219 } | 1219 } |
1220 | 1220 |
1221 | 1221 |
1222 void RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) { | 1222 void RegExpMacroAssemblerX87::SafeCallTarget(Label* name) { |
1223 __ bind(name); | 1223 __ bind(name); |
1224 } | 1224 } |
1225 | 1225 |
1226 | 1226 |
1227 void RegExpMacroAssemblerIA32::Push(Register source) { | 1227 void RegExpMacroAssemblerX87::Push(Register source) { |
1228 ASSERT(!source.is(backtrack_stackpointer())); | 1228 ASSERT(!source.is(backtrack_stackpointer())); |
1229 // Notice: This updates flags, unlike normal Push. | 1229 // Notice: This updates flags, unlike normal Push. |
1230 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1230 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
1231 __ mov(Operand(backtrack_stackpointer(), 0), source); | 1231 __ mov(Operand(backtrack_stackpointer(), 0), source); |
1232 } | 1232 } |
1233 | 1233 |
1234 | 1234 |
1235 void RegExpMacroAssemblerIA32::Push(Immediate value) { | 1235 void RegExpMacroAssemblerX87::Push(Immediate value) { |
1236 // Notice: This updates flags, unlike normal Push. | 1236 // Notice: This updates flags, unlike normal Push. |
1237 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1237 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
1238 __ mov(Operand(backtrack_stackpointer(), 0), value); | 1238 __ mov(Operand(backtrack_stackpointer(), 0), value); |
1239 } | 1239 } |
1240 | 1240 |
1241 | 1241 |
1242 void RegExpMacroAssemblerIA32::Pop(Register target) { | 1242 void RegExpMacroAssemblerX87::Pop(Register target) { |
1243 ASSERT(!target.is(backtrack_stackpointer())); | 1243 ASSERT(!target.is(backtrack_stackpointer())); |
1244 __ mov(target, Operand(backtrack_stackpointer(), 0)); | 1244 __ mov(target, Operand(backtrack_stackpointer(), 0)); |
1245 // Notice: This updates flags, unlike normal Pop. | 1245 // Notice: This updates flags, unlike normal Pop. |
1246 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); | 1246 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); |
1247 } | 1247 } |
1248 | 1248 |
1249 | 1249 |
1250 void RegExpMacroAssemblerIA32::CheckPreemption() { | 1250 void RegExpMacroAssemblerX87::CheckPreemption() { |
1251 // Check for preemption. | 1251 // Check for preemption. |
1252 Label no_preempt; | 1252 Label no_preempt; |
1253 ExternalReference stack_limit = | 1253 ExternalReference stack_limit = |
1254 ExternalReference::address_of_stack_limit(isolate()); | 1254 ExternalReference::address_of_stack_limit(isolate()); |
1255 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 1255 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
1256 __ j(above, &no_preempt); | 1256 __ j(above, &no_preempt); |
1257 | 1257 |
1258 SafeCall(&check_preempt_label_); | 1258 SafeCall(&check_preempt_label_); |
1259 | 1259 |
1260 __ bind(&no_preempt); | 1260 __ bind(&no_preempt); |
1261 } | 1261 } |
1262 | 1262 |
1263 | 1263 |
1264 void RegExpMacroAssemblerIA32::CheckStackLimit() { | 1264 void RegExpMacroAssemblerX87::CheckStackLimit() { |
1265 Label no_stack_overflow; | 1265 Label no_stack_overflow; |
1266 ExternalReference stack_limit = | 1266 ExternalReference stack_limit = |
1267 ExternalReference::address_of_regexp_stack_limit(isolate()); | 1267 ExternalReference::address_of_regexp_stack_limit(isolate()); |
1268 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); | 1268 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); |
1269 __ j(above, &no_stack_overflow); | 1269 __ j(above, &no_stack_overflow); |
1270 | 1270 |
1271 SafeCall(&stack_overflow_label_); | 1271 SafeCall(&stack_overflow_label_); |
1272 | 1272 |
1273 __ bind(&no_stack_overflow); | 1273 __ bind(&no_stack_overflow); |
1274 } | 1274 } |
1275 | 1275 |
1276 | 1276 |
1277 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1277 void RegExpMacroAssemblerX87::LoadCurrentCharacterUnchecked(int cp_offset, |
1278 int characters) { | 1278 int characters) { |
1279 if (mode_ == ASCII) { | 1279 if (mode_ == ASCII) { |
1280 if (characters == 4) { | 1280 if (characters == 4) { |
1281 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1281 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1282 } else if (characters == 2) { | 1282 } else if (characters == 2) { |
1283 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1283 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1284 } else { | 1284 } else { |
1285 ASSERT(characters == 1); | 1285 ASSERT(characters == 1); |
1286 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1286 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1287 } | 1287 } |
(...skipping 10 matching lines...) Expand all Loading... |
1298 } | 1298 } |
1299 } | 1299 } |
1300 | 1300 |
1301 | 1301 |
1302 #undef __ | 1302 #undef __ |
1303 | 1303 |
1304 #endif // V8_INTERPRETED_REGEXP | 1304 #endif // V8_INTERPRETED_REGEXP |
1305 | 1305 |
1306 }} // namespace v8::internal | 1306 }} // namespace v8::internal |
1307 | 1307 |
1308 #endif // V8_TARGET_ARCH_IA32 | 1308 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |