Chromium Code Reviews| 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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/regexp/arm/regexp-macro-assembler-arm.h" | 7 #include "src/regexp/arm/regexp-macro-assembler-arm.h" |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/log.h" | 10 #include "src/log.h" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { | 172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { |
| 173 __ cmp(current_character(), Operand(limit)); | 173 __ cmp(current_character(), Operand(limit)); |
| 174 BranchOrBacktrack(gt, on_greater); | 174 BranchOrBacktrack(gt, on_greater); |
| 175 } | 175 } |
| 176 | 176 |
| 177 | 177 |
| 178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { | 178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { |
| 179 Label not_at_start; | 179 __ add(r0, end_of_input_address(), current_input_offset()); |
| 180 // Did we start the match at the start of the string at all? | 180 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
| 181 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 181 for (int i = 0; i < char_size(); i++) { |
| 182 __ cmp(r0, Operand::Zero()); | 182 __ add(r0, r0, r1); |
| 183 BranchOrBacktrack(ne, ¬_at_start); | 183 } |
| 184 | |
| 185 // If we did, are we still at the start of the input? | |
| 186 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 184 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
| 187 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | |
| 188 __ cmp(r0, r1); | 185 __ cmp(r0, r1); |
| 189 BranchOrBacktrack(eq, on_at_start); | 186 BranchOrBacktrack(eq, on_at_start); |
| 190 __ bind(¬_at_start); | |
| 191 } | 187 } |
| 192 | 188 |
| 193 | 189 |
| 194 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { | 190 void RegExpMacroAssemblerARM::CheckNotAtStart(int cp_offset, |
| 195 // Did we start the match at the start of the string at all? | 191 Label* on_not_at_start) { |
| 196 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 192 __ add(r0, end_of_input_address(), current_input_offset()); |
| 197 __ cmp(r0, Operand::Zero()); | 193 __ add(r0, r0, Operand(cp_offset * char_size())); |
| 198 BranchOrBacktrack(ne, on_not_at_start); | 194 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
| 199 // If we did, are we still at the start of the input? | 195 for (int i = 0; i < char_size(); i++) { |
| 196 __ add(r0, r0, r1); | |
| 197 } | |
| 200 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 198 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
| 201 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | |
| 202 __ cmp(r0, r1); | 199 __ cmp(r0, r1); |
| 203 BranchOrBacktrack(ne, on_not_at_start); | 200 BranchOrBacktrack(ne, on_not_at_start); |
| 204 } | 201 } |
| 205 | 202 |
| 206 | 203 |
| 207 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { | 204 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { |
| 208 __ cmp(current_character(), Operand(limit)); | 205 __ cmp(current_character(), Operand(limit)); |
| 209 BranchOrBacktrack(lt, on_less); | 206 BranchOrBacktrack(lt, on_less); |
| 210 } | 207 } |
| 211 | 208 |
| 212 | 209 |
| 213 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { | 210 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { |
| 214 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); | 211 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); |
| 215 __ cmp(current_input_offset(), r0); | 212 __ cmp(current_input_offset(), r0); |
| 216 __ add(backtrack_stackpointer(), | 213 __ add(backtrack_stackpointer(), |
| 217 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); | 214 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); |
| 218 BranchOrBacktrack(eq, on_equal); | 215 BranchOrBacktrack(eq, on_equal); |
| 219 } | 216 } |
| 220 | 217 |
| 221 | 218 |
| 222 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( | 219 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( |
| 223 int start_reg, | 220 int start_reg, bool read_backward, Label* on_no_match) { |
| 224 Label* on_no_match) { | |
| 225 Label fallthrough; | 221 Label fallthrough; |
| 226 __ ldr(r0, register_location(start_reg)); // Index of start of capture | 222 __ ldr(r0, register_location(start_reg)); // Index of start of capture |
| 227 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | 223 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture |
| 228 __ sub(r1, r1, r0, SetCC); // Length of capture. | 224 __ sub(r1, r1, r0, SetCC); // Length of capture. |
| 229 | 225 |
| 230 // If length is zero, either the capture is empty or it is not participating. | 226 // The length of the capture can only be negative if the end of the |
| 231 // In either case succeed immediately. | 227 // capture is not yet recorded. If the length is zero, the capture is |
| 232 __ b(eq, &fallthrough); | 228 // either empty or uncaptured. In either of those cases, succeed. |
| 229 __ b(le, &fallthrough); | |
| 233 | 230 |
| 234 // Check that there are enough characters left in the input. | 231 // Check that there are enough characters left in the input. |
| 235 __ cmn(r1, Operand(current_input_offset())); | 232 if (read_backward) { |
| 236 BranchOrBacktrack(gt, on_no_match); | 233 __ add(r2, end_of_input_address(), current_input_offset()); |
| 234 __ ldr(r3, MemOperand(frame_pointer(), kStartIndex)); | |
| 235 for (int i = 0; i < char_size(); i++) { | |
| 236 __ add(r2, r2, r3); | |
| 237 } | |
| 238 __ ldr(r3, MemOperand(frame_pointer(), kInputStart)); | |
| 239 __ cmp(r2, r3); | |
| 240 BranchOrBacktrack(lt, on_no_match); | |
| 241 } else { | |
| 242 __ cmn(r1, Operand(current_input_offset())); | |
| 243 BranchOrBacktrack(gt, on_no_match); | |
| 244 } | |
| 237 | 245 |
| 238 if (mode_ == LATIN1) { | 246 if (mode_ == LATIN1) { |
| 239 Label success; | 247 Label success; |
| 240 Label fail; | 248 Label fail; |
| 241 Label loop_check; | 249 Label loop_check; |
| 242 | 250 |
| 243 // r0 - offset of start of capture | 251 // r0 - offset of start of capture |
| 244 // r1 - length of capture | 252 // r1 - length of capture |
| 245 __ add(r0, r0, Operand(end_of_input_address())); | 253 __ add(r0, r0, end_of_input_address()); |
| 246 __ add(r2, end_of_input_address(), Operand(current_input_offset())); | 254 __ add(r2, end_of_input_address(), current_input_offset()); |
| 247 __ add(r1, r0, Operand(r1)); | 255 if (read_backward) { |
| 256 __ sub(r2, r2, r1); // Offset by length when matching backwards. | |
| 257 } | |
| 258 __ add(r1, r0, r1); | |
| 248 | 259 |
| 249 // r0 - Address of start of capture. | 260 // r0 - Address of start of capture. |
| 250 // r1 - Address of end of capture | 261 // r1 - Address of end of capture |
| 251 // r2 - Address of current input position. | 262 // r2 - Address of current input position. |
| 252 | 263 |
| 253 Label loop; | 264 Label loop; |
| 254 __ bind(&loop); | 265 __ bind(&loop); |
| 255 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); | 266 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); |
| 256 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); | 267 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); |
| 257 __ cmp(r4, r3); | 268 __ cmp(r4, r3); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 276 __ cmp(r0, r1); | 287 __ cmp(r0, r1); |
| 277 __ b(lt, &loop); | 288 __ b(lt, &loop); |
| 278 __ jmp(&success); | 289 __ jmp(&success); |
| 279 | 290 |
| 280 __ bind(&fail); | 291 __ bind(&fail); |
| 281 BranchOrBacktrack(al, on_no_match); | 292 BranchOrBacktrack(al, on_no_match); |
| 282 | 293 |
| 283 __ bind(&success); | 294 __ bind(&success); |
| 284 // Compute new value of character position after the matched part. | 295 // Compute new value of character position after the matched part. |
| 285 __ sub(current_input_offset(), r2, end_of_input_address()); | 296 __ sub(current_input_offset(), r2, end_of_input_address()); |
| 297 if (read_backward) { | |
| 298 __ ldr(r0, register_location(start_reg)); // Index of start of capture | |
| 299 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | |
| 300 __ add(current_input_offset(), current_input_offset(), r0); | |
| 301 __ sub(current_input_offset(), current_input_offset(), r1); | |
| 302 } | |
| 286 } else { | 303 } else { |
| 287 DCHECK(mode_ == UC16); | 304 DCHECK(mode_ == UC16); |
| 288 int argument_count = 4; | 305 int argument_count = 4; |
| 289 __ PrepareCallCFunction(argument_count, r2); | 306 __ PrepareCallCFunction(argument_count, r2); |
| 290 | 307 |
| 291 // r0 - offset of start of capture | 308 // r0 - offset of start of capture |
| 292 // r1 - length of capture | 309 // r1 - length of capture |
| 293 | 310 |
| 294 // Put arguments into arguments registers. | 311 // Put arguments into arguments registers. |
| 295 // Parameters are | 312 // Parameters are |
| 296 // r0: Address byte_offset1 - Address captured substring's start. | 313 // r0: Address byte_offset1 - Address captured substring's start. |
| 297 // r1: Address byte_offset2 - Address of current character position. | 314 // r1: Address byte_offset2 - Address of current character position. |
| 298 // r2: size_t byte_length - length of capture in bytes(!) | 315 // r2: size_t byte_length - length of capture in bytes(!) |
| 299 // r3: Isolate* isolate | 316 // r3: Isolate* isolate |
| 300 | 317 |
| 301 // Address of start of capture. | 318 // Address of start of capture. |
| 302 __ add(r0, r0, Operand(end_of_input_address())); | 319 __ add(r0, r0, Operand(end_of_input_address())); |
| 303 // Length of capture. | 320 // Length of capture. |
| 304 __ mov(r2, Operand(r1)); | 321 __ mov(r2, Operand(r1)); |
| 305 // Save length in callee-save register for use on return. | 322 // Save length in callee-save register for use on return. |
| 306 __ mov(r4, Operand(r1)); | 323 __ mov(r4, Operand(r1)); |
| 307 // Address of current input position. | 324 // Address of current input position. |
| 308 __ add(r1, current_input_offset(), Operand(end_of_input_address())); | 325 __ add(r1, current_input_offset(), end_of_input_address()); |
| 326 if (read_backward) { | |
| 327 __ sub(r1, r1, r4); | |
| 328 } | |
| 309 // Isolate. | 329 // Isolate. |
| 310 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); | 330 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); |
| 311 | 331 |
| 312 { | 332 { |
| 313 AllowExternalCallThatCantCauseGC scope(masm_); | 333 AllowExternalCallThatCantCauseGC scope(masm_); |
| 314 ExternalReference function = | 334 ExternalReference function = |
| 315 ExternalReference::re_case_insensitive_compare_uc16(isolate()); | 335 ExternalReference::re_case_insensitive_compare_uc16(isolate()); |
| 316 __ CallCFunction(function, argument_count); | 336 __ CallCFunction(function, argument_count); |
| 317 } | 337 } |
| 318 | 338 |
| 319 // Check if function returned non-zero for success or zero for failure. | 339 // Check if function returned non-zero for success or zero for failure. |
| 320 __ cmp(r0, Operand::Zero()); | 340 __ cmp(r0, Operand::Zero()); |
| 321 BranchOrBacktrack(eq, on_no_match); | 341 BranchOrBacktrack(eq, on_no_match); |
| 322 // On success, increment position by length of capture. | 342 |
| 323 __ add(current_input_offset(), current_input_offset(), Operand(r4)); | 343 // On success, advance position by length of capture. |
| 344 if (read_backward) { | |
| 345 __ sub(current_input_offset(), current_input_offset(), r4); | |
| 346 } else { | |
| 347 __ add(current_input_offset(), current_input_offset(), r4); | |
| 348 } | |
| 324 } | 349 } |
| 325 | 350 |
| 326 __ bind(&fallthrough); | 351 __ bind(&fallthrough); |
| 327 } | 352 } |
| 328 | 353 |
| 329 | 354 |
| 330 void RegExpMacroAssemblerARM::CheckNotBackReference( | 355 void RegExpMacroAssemblerARM::CheckNotBackReference(int start_reg, |
| 331 int start_reg, | 356 bool read_backward, |
| 332 Label* on_no_match) { | 357 Label* on_no_match) { |
| 333 Label fallthrough; | 358 Label fallthrough; |
| 334 Label success; | 359 Label success; |
| 335 | 360 |
| 336 // Find length of back-referenced capture. | 361 // Find length of back-referenced capture. |
| 337 __ ldr(r0, register_location(start_reg)); | 362 __ ldr(r0, register_location(start_reg)); |
| 338 __ ldr(r1, register_location(start_reg + 1)); | 363 __ ldr(r1, register_location(start_reg + 1)); |
| 339 __ sub(r1, r1, r0, SetCC); // Length to check. | 364 __ sub(r1, r1, r0, SetCC); // Length to check. |
| 340 // Succeed on empty capture (including no capture). | 365 |
| 341 __ b(eq, &fallthrough); | 366 // The length of the capture can only be negative if the end of the |
| 367 // capture is not yet recorded. If the length is zero, the capture is | |
| 368 // either empty or uncaptured. In either of those cases, succeed. | |
| 369 __ b(le, &fallthrough); | |
| 342 | 370 |
| 343 // Check that there are enough characters left in the input. | 371 // Check that there are enough characters left in the input. |
| 344 __ cmn(r1, Operand(current_input_offset())); | 372 if (read_backward) { |
| 345 BranchOrBacktrack(gt, on_no_match); | 373 __ add(r2, end_of_input_address(), current_input_offset()); |
| 374 __ ldr(r3, MemOperand(frame_pointer(), kStartIndex)); | |
| 375 for (int i = 0; i < char_size(); i++) { | |
| 376 __ add(r2, r2, r3); | |
| 377 } | |
| 378 __ ldr(r3, MemOperand(frame_pointer(), kInputStart)); | |
| 379 __ cmp(r2, r3); | |
| 380 BranchOrBacktrack(lt, on_no_match); | |
| 381 } else { | |
| 382 __ cmn(r1, Operand(current_input_offset())); | |
| 383 BranchOrBacktrack(gt, on_no_match); | |
| 384 } | |
| 346 | 385 |
| 347 // Compute pointers to match string and capture string | 386 // r0 - offset of start of capture |
| 348 __ add(r0, r0, Operand(end_of_input_address())); | 387 // r1 - length of capture |
| 349 __ add(r2, end_of_input_address(), Operand(current_input_offset())); | 388 __ add(r0, r0, end_of_input_address()); |
| 350 __ add(r1, r1, Operand(r0)); | 389 __ add(r2, end_of_input_address(), current_input_offset()); |
| 390 if (read_backward) { | |
| 391 __ sub(r2, r2, r1); // Offset by length when matching backwards. | |
| 392 } | |
| 393 __ add(r1, r0, r1); | |
| 351 | 394 |
| 352 Label loop; | 395 Label loop; |
| 353 __ bind(&loop); | 396 __ bind(&loop); |
| 354 if (mode_ == LATIN1) { | 397 if (mode_ == LATIN1) { |
| 355 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); | 398 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); |
| 356 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); | 399 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); |
| 357 } else { | 400 } else { |
| 358 DCHECK(mode_ == UC16); | 401 DCHECK(mode_ == UC16); |
| 359 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); | 402 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); |
| 360 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); | 403 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); |
| 361 } | 404 } |
| 362 __ cmp(r3, r4); | 405 __ cmp(r3, r4); |
| 363 BranchOrBacktrack(ne, on_no_match); | 406 BranchOrBacktrack(ne, on_no_match); |
| 364 __ cmp(r0, r1); | 407 __ cmp(r0, r1); |
| 365 __ b(lt, &loop); | 408 __ b(lt, &loop); |
| 366 | 409 |
| 367 // Move current character position to position after match. | 410 // Move current character position to position after match. |
| 368 __ sub(current_input_offset(), r2, end_of_input_address()); | 411 __ sub(current_input_offset(), r2, end_of_input_address()); |
| 412 if (read_backward) { | |
| 413 __ ldr(r0, register_location(start_reg)); // Index of start of capture | |
| 414 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | |
| 415 __ add(current_input_offset(), current_input_offset(), r0); | |
| 416 __ sub(current_input_offset(), current_input_offset(), r1); | |
| 417 } | |
| 418 | |
| 369 __ bind(&fallthrough); | 419 __ bind(&fallthrough); |
| 370 } | 420 } |
| 371 | 421 |
| 372 | 422 |
| 373 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, | 423 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, |
| 374 Label* on_not_equal) { | 424 Label* on_not_equal) { |
| 375 __ cmp(current_character(), Operand(c)); | 425 __ cmp(current_character(), Operand(c)); |
| 376 BranchOrBacktrack(ne, on_not_equal); | 426 BranchOrBacktrack(ne, on_not_equal); |
| 377 } | 427 } |
| 378 | 428 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 // Load string end. | 687 // Load string end. |
| 638 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 688 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
| 639 // Load input start. | 689 // Load input start. |
| 640 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); | 690 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); |
| 641 // Find negative length (offset of start relative to end). | 691 // Find negative length (offset of start relative to end). |
| 642 __ sub(current_input_offset(), r0, end_of_input_address()); | 692 __ sub(current_input_offset(), r0, end_of_input_address()); |
| 643 // Set r0 to address of char before start of the input string | 693 // Set r0 to address of char before start of the input string |
| 644 // (effectively string position -1). | 694 // (effectively string position -1). |
| 645 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | 695 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
| 646 __ sub(r0, current_input_offset(), Operand(char_size())); | 696 __ sub(r0, current_input_offset(), Operand(char_size())); |
| 647 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); | 697 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); |
|
erikcorry
2015/11/13 14:30:13
This instruction is better than the short for loop
| |
| 648 // Store this value in a local variable, for use when clearing | 698 // Store this value in a local variable, for use when clearing |
| 649 // position registers. | 699 // position registers. |
| 650 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 700 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
|
erikcorry
2015/11/13 14:30:13
This looks useful. It's the actual position 1 les
| |
| 651 | 701 |
| 652 // Initialize code pointer register | 702 // Initialize code pointer register |
| 653 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 703 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
| 654 | 704 |
| 655 Label load_char_start_regexp, start_regexp; | 705 Label load_char_start_regexp, start_regexp; |
| 656 // Load newline if index is at start, previous character otherwise. | 706 // Load newline if index is at start, previous character otherwise. |
| 657 __ cmp(r1, Operand::Zero()); | 707 __ cmp(r1, Operand::Zero()); |
| 658 __ b(ne, &load_char_start_regexp); | 708 __ b(ne, &load_char_start_regexp); |
| 659 __ mov(current_character(), Operand('\n'), LeaveCC, eq); | 709 __ mov(current_character(), Operand('\n'), LeaveCC, eq); |
| 660 __ jmp(&start_regexp); | 710 __ jmp(&start_regexp); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 885 RegExpMacroAssembler::IrregexpImplementation | 935 RegExpMacroAssembler::IrregexpImplementation |
| 886 RegExpMacroAssemblerARM::Implementation() { | 936 RegExpMacroAssemblerARM::Implementation() { |
| 887 return kARMImplementation; | 937 return kARMImplementation; |
| 888 } | 938 } |
| 889 | 939 |
| 890 | 940 |
| 891 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, | 941 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, |
| 892 Label* on_end_of_input, | 942 Label* on_end_of_input, |
| 893 bool check_bounds, | 943 bool check_bounds, |
| 894 int characters) { | 944 int characters) { |
| 895 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. | |
| 896 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 945 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
| 897 if (check_bounds) { | 946 if (check_bounds) { |
| 898 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 947 if (cp_offset >= 0) { |
| 948 CheckPosition(cp_offset + characters - 1, on_end_of_input); | |
| 949 } else { | |
| 950 CheckPosition(cp_offset, on_end_of_input); | |
| 951 } | |
| 899 } | 952 } |
| 900 LoadCurrentCharacterUnchecked(cp_offset, characters); | 953 LoadCurrentCharacterUnchecked(cp_offset, characters); |
| 901 } | 954 } |
| 902 | 955 |
| 903 | 956 |
| 904 void RegExpMacroAssemblerARM::PopCurrentPosition() { | 957 void RegExpMacroAssemblerARM::PopCurrentPosition() { |
| 905 Pop(current_input_offset()); | 958 Pop(current_input_offset()); |
| 906 } | 959 } |
| 907 | 960 |
| 908 | 961 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 if (num_registers_ <= register_index) { | 1115 if (num_registers_ <= register_index) { |
| 1063 num_registers_ = register_index + 1; | 1116 num_registers_ = register_index + 1; |
| 1064 } | 1117 } |
| 1065 return MemOperand(frame_pointer(), | 1118 return MemOperand(frame_pointer(), |
| 1066 kRegisterZero - register_index * kPointerSize); | 1119 kRegisterZero - register_index * kPointerSize); |
| 1067 } | 1120 } |
| 1068 | 1121 |
| 1069 | 1122 |
| 1070 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, | 1123 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, |
| 1071 Label* on_outside_input) { | 1124 Label* on_outside_input) { |
| 1072 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); | 1125 if (cp_offset >= 0) { |
| 1073 BranchOrBacktrack(ge, on_outside_input); | 1126 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); |
| 1127 BranchOrBacktrack(ge, on_outside_input); | |
| 1128 } else { | |
| 1129 __ add(r0, end_of_input_address(), current_input_offset()); | |
| 1130 __ add(r0, r0, Operand(cp_offset * char_size())); | |
| 1131 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | |
| 1132 for (int i = 0; i < char_size(); i++) { | |
| 1133 __ add(r0, r0, r1); | |
| 1134 } | |
| 1135 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | |
| 1136 __ cmp(r0, r1); | |
| 1137 BranchOrBacktrack(lt, on_outside_input); | |
| 1138 } | |
| 1074 } | 1139 } |
| 1075 | 1140 |
| 1076 | 1141 |
| 1077 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, | 1142 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, |
| 1078 Label* to) { | 1143 Label* to) { |
| 1079 if (condition == al) { // Unconditional. | 1144 if (condition == al) { // Unconditional. |
| 1080 if (to == NULL) { | 1145 if (to == NULL) { |
| 1081 Backtrack(); | 1146 Backtrack(); |
| 1082 return; | 1147 return; |
| 1083 } | 1148 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1188 | 1253 |
| 1189 | 1254 |
| 1190 #undef __ | 1255 #undef __ |
| 1191 | 1256 |
| 1192 #endif // V8_INTERPRETED_REGEXP | 1257 #endif // V8_INTERPRETED_REGEXP |
| 1193 | 1258 |
| 1194 } // namespace internal | 1259 } // namespace internal |
| 1195 } // namespace v8 | 1260 } // namespace v8 |
| 1196 | 1261 |
| 1197 #endif // V8_TARGET_ARCH_ARM | 1262 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |