OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 // A simple interpreter for the Irregexp byte code. | 5 // A simple interpreter for the Irregexp byte code. |
6 | 6 |
7 #include "src/regexp/interpreter-irregexp.h" | 7 #include "src/regexp/interpreter-irregexp.h" |
8 | 8 |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/regexp/bytecodes-irregexp.h" | 10 #include "src/regexp/bytecodes-irregexp.h" |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 if (current == backtrack_sp[-1]) { | 263 if (current == backtrack_sp[-1]) { |
264 backtrack_sp--; | 264 backtrack_sp--; |
265 backtrack_stack_space++; | 265 backtrack_stack_space++; |
266 pc = code_base + Load32Aligned(pc + 4); | 266 pc = code_base + Load32Aligned(pc + 4); |
267 } else { | 267 } else { |
268 pc += BC_CHECK_GREEDY_LENGTH; | 268 pc += BC_CHECK_GREEDY_LENGTH; |
269 } | 269 } |
270 break; | 270 break; |
271 BYTECODE(LOAD_CURRENT_CHAR) { | 271 BYTECODE(LOAD_CURRENT_CHAR) { |
272 int pos = current + (insn >> BYTECODE_SHIFT); | 272 int pos = current + (insn >> BYTECODE_SHIFT); |
273 if (pos >= subject.length()) { | 273 if (pos >= subject.length() || pos < 0) { |
274 pc = code_base + Load32Aligned(pc + 4); | 274 pc = code_base + Load32Aligned(pc + 4); |
275 } else { | 275 } else { |
276 current_char = subject[pos]; | 276 current_char = subject[pos]; |
277 pc += BC_LOAD_CURRENT_CHAR_LENGTH; | 277 pc += BC_LOAD_CURRENT_CHAR_LENGTH; |
278 } | 278 } |
279 break; | 279 break; |
280 } | 280 } |
281 BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) { | 281 BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) { |
282 int pos = current + (insn >> BYTECODE_SHIFT); | 282 int pos = current + (insn >> BYTECODE_SHIFT); |
283 current_char = subject[pos]; | 283 current_char = subject[pos]; |
284 pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH; | 284 pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH; |
285 break; | 285 break; |
286 } | 286 } |
287 BYTECODE(LOAD_2_CURRENT_CHARS) { | 287 BYTECODE(LOAD_2_CURRENT_CHARS) { |
288 int pos = current + (insn >> BYTECODE_SHIFT); | 288 int pos = current + (insn >> BYTECODE_SHIFT); |
289 if (pos + 2 > subject.length()) { | 289 if (pos + 2 > subject.length() || pos < 0) { |
290 pc = code_base + Load32Aligned(pc + 4); | 290 pc = code_base + Load32Aligned(pc + 4); |
291 } else { | 291 } else { |
292 Char next = subject[pos + 1]; | 292 Char next = subject[pos + 1]; |
293 current_char = | 293 current_char = |
294 (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); | 294 (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); |
295 pc += BC_LOAD_2_CURRENT_CHARS_LENGTH; | 295 pc += BC_LOAD_2_CURRENT_CHARS_LENGTH; |
296 } | 296 } |
297 break; | 297 break; |
298 } | 298 } |
299 BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { | 299 BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { |
300 int pos = current + (insn >> BYTECODE_SHIFT); | 300 int pos = current + (insn >> BYTECODE_SHIFT); |
301 Char next = subject[pos + 1]; | 301 Char next = subject[pos + 1]; |
302 current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); | 302 current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); |
303 pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH; | 303 pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH; |
304 break; | 304 break; |
305 } | 305 } |
306 BYTECODE(LOAD_4_CURRENT_CHARS) { | 306 BYTECODE(LOAD_4_CURRENT_CHARS) { |
307 DCHECK(sizeof(Char) == 1); | 307 DCHECK(sizeof(Char) == 1); |
308 int pos = current + (insn >> BYTECODE_SHIFT); | 308 int pos = current + (insn >> BYTECODE_SHIFT); |
309 if (pos + 4 > subject.length()) { | 309 if (pos + 4 > subject.length() || pos < 0) { |
310 pc = code_base + Load32Aligned(pc + 4); | 310 pc = code_base + Load32Aligned(pc + 4); |
311 } else { | 311 } else { |
312 Char next1 = subject[pos + 1]; | 312 Char next1 = subject[pos + 1]; |
313 Char next2 = subject[pos + 2]; | 313 Char next2 = subject[pos + 2]; |
314 Char next3 = subject[pos + 3]; | 314 Char next3 = subject[pos + 3]; |
315 current_char = (subject[pos] | | 315 current_char = (subject[pos] | |
316 (next1 << 8) | | 316 (next1 << 8) | |
317 (next2 << 16) | | 317 (next2 << 16) | |
318 (next3 << 24)); | 318 (next3 << 24)); |
319 pc += BC_LOAD_4_CURRENT_CHARS_LENGTH; | 319 pc += BC_LOAD_4_CURRENT_CHARS_LENGTH; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 if (registers[insn >> BYTECODE_SHIFT] == | 490 if (registers[insn >> BYTECODE_SHIFT] == |
491 registers[Load32Aligned(pc + 4)]) { | 491 registers[Load32Aligned(pc + 4)]) { |
492 pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH; | 492 pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH; |
493 } else { | 493 } else { |
494 pc = code_base + Load32Aligned(pc + 8); | 494 pc = code_base + Load32Aligned(pc + 8); |
495 } | 495 } |
496 break; | 496 break; |
497 BYTECODE(CHECK_NOT_BACK_REF) { | 497 BYTECODE(CHECK_NOT_BACK_REF) { |
498 int from = registers[insn >> BYTECODE_SHIFT]; | 498 int from = registers[insn >> BYTECODE_SHIFT]; |
499 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; | 499 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; |
500 if (from < 0 || len <= 0) { | 500 if (from >= 0 && len > 0) { |
501 pc += BC_CHECK_NOT_BACK_REF_LENGTH; | 501 if (current + len > subject.length() || |
502 break; | 502 CompareChars(&subject[from], &subject[current], len) != 0) { |
503 } | 503 pc = code_base + Load32Aligned(pc + 4); |
504 if (current + len > subject.length()) { | 504 break; |
505 pc = code_base + Load32Aligned(pc + 4); | |
506 break; | |
507 } else { | |
508 int i; | |
509 for (i = 0; i < len; i++) { | |
510 if (subject[from + i] != subject[current + i]) { | |
511 pc = code_base + Load32Aligned(pc + 4); | |
512 break; | |
513 } | |
514 } | 505 } |
515 if (i < len) break; | |
516 current += len; | 506 current += len; |
517 } | 507 } |
518 pc += BC_CHECK_NOT_BACK_REF_LENGTH; | 508 pc += BC_CHECK_NOT_BACK_REF_LENGTH; |
519 break; | 509 break; |
520 } | 510 } |
| 511 BYTECODE(CHECK_NOT_BACK_REF_BACKWARD) { |
| 512 int from = registers[insn >> BYTECODE_SHIFT]; |
| 513 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; |
| 514 if (from >= 0 && len > 0) { |
| 515 if (current - len < 0 || |
| 516 CompareChars(&subject[from], &subject[current - len], len) != 0) { |
| 517 pc = code_base + Load32Aligned(pc + 4); |
| 518 break; |
| 519 } |
| 520 current -= len; |
| 521 } |
| 522 pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH; |
| 523 break; |
| 524 } |
521 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) { | 525 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) { |
522 int from = registers[insn >> BYTECODE_SHIFT]; | 526 int from = registers[insn >> BYTECODE_SHIFT]; |
523 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; | 527 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; |
524 if (from < 0 || len <= 0) { | 528 if (from >= 0 && len > 0) { |
525 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH; | 529 if (current + len > subject.length() || |
526 break; | 530 !BackRefMatchesNoCase(isolate->interp_canonicalize_mapping(), |
| 531 from, current, len, subject)) { |
| 532 pc = code_base + Load32Aligned(pc + 4); |
| 533 break; |
| 534 } |
| 535 current += len; |
527 } | 536 } |
528 if (current + len > subject.length()) { | 537 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH; |
529 pc = code_base + Load32Aligned(pc + 4); | 538 break; |
530 break; | 539 } |
531 } else { | 540 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD) { |
532 if (BackRefMatchesNoCase(isolate->interp_canonicalize_mapping(), | 541 int from = registers[insn >> BYTECODE_SHIFT]; |
533 from, current, len, subject)) { | 542 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; |
534 current += len; | 543 if (from >= 0 && len > 0) { |
535 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH; | 544 if (current - len < 0 || |
536 } else { | 545 !BackRefMatchesNoCase(isolate->interp_canonicalize_mapping(), |
| 546 from, current - len, len, subject)) { |
537 pc = code_base + Load32Aligned(pc + 4); | 547 pc = code_base + Load32Aligned(pc + 4); |
| 548 break; |
538 } | 549 } |
| 550 current -= len; |
539 } | 551 } |
| 552 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH; |
540 break; | 553 break; |
541 } | 554 } |
542 BYTECODE(CHECK_AT_START) | 555 BYTECODE(CHECK_AT_START) |
543 if (current == 0) { | 556 if (current == 0) { |
544 pc = code_base + Load32Aligned(pc + 4); | 557 pc = code_base + Load32Aligned(pc + 4); |
545 } else { | 558 } else { |
546 pc += BC_CHECK_AT_START_LENGTH; | 559 pc += BC_CHECK_AT_START_LENGTH; |
547 } | 560 } |
548 break; | 561 break; |
549 BYTECODE(CHECK_NOT_AT_START) | 562 BYTECODE(CHECK_NOT_AT_START) |
550 if (current == 0) { | 563 if (current + (insn >> BYTECODE_SHIFT) == 0) { |
551 pc += BC_CHECK_NOT_AT_START_LENGTH; | 564 pc += BC_CHECK_NOT_AT_START_LENGTH; |
552 } else { | 565 } else { |
553 pc = code_base + Load32Aligned(pc + 4); | 566 pc = code_base + Load32Aligned(pc + 4); |
554 } | 567 } |
555 break; | 568 break; |
556 BYTECODE(SET_CURRENT_POSITION_FROM_END) { | 569 BYTECODE(SET_CURRENT_POSITION_FROM_END) { |
557 int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT; | 570 int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT; |
558 if (subject.length() - current > by) { | 571 if (subject.length() - current > by) { |
559 current = subject.length() - by; | 572 current = subject.length() - by; |
560 current_char = subject[current - 1]; | 573 current_char = subject[current - 1]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 code_base, | 612 code_base, |
600 subject_vector, | 613 subject_vector, |
601 registers, | 614 registers, |
602 start_position, | 615 start_position, |
603 previous_char); | 616 previous_char); |
604 } | 617 } |
605 } | 618 } |
606 | 619 |
607 } // namespace internal | 620 } // namespace internal |
608 } // namespace v8 | 621 } // namespace v8 |
OLD | NEW |