blob: 14834d512a5c9aba83d1740f6e5d645375035673 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5// A simple interpreter for the Irregexp byte code.
6
Ben Murdoch097c5b22016-05-18 11:27:45 +01007#ifdef V8_INTERPRETED_REGEXP
8
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/regexp/interpreter-irregexp.h"
10
11#include "src/ast/ast.h"
12#include "src/regexp/bytecodes-irregexp.h"
13#include "src/regexp/jsregexp.h"
14#include "src/regexp/regexp-macro-assembler.h"
15#include "src/unicode.h"
16#include "src/utils.h"
17
Ben Murdoch097c5b22016-05-18 11:27:45 +010018#ifdef V8_I18N_SUPPORT
19#include "unicode/uchar.h"
20#endif // V8_I18N_SUPPORT
21
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022namespace v8 {
23namespace internal {
24
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025typedef unibrow::Mapping<unibrow::Ecma262Canonicalize> Canonicalize;
26
Ben Murdoch097c5b22016-05-18 11:27:45 +010027static bool BackRefMatchesNoCase(Isolate* isolate, int from, int current,
28 int len, Vector<const uc16> subject,
29 bool unicode) {
30 Address offset_a =
31 reinterpret_cast<Address>(const_cast<uc16*>(&subject.at(from)));
32 Address offset_b =
33 reinterpret_cast<Address>(const_cast<uc16*>(&subject.at(current)));
34 size_t length = len * kUC16Size;
35 return RegExpMacroAssembler::CaseInsensitiveCompareUC16(
36 offset_a, offset_b, length, unicode ? nullptr : isolate) == 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037}
38
39
Ben Murdoch097c5b22016-05-18 11:27:45 +010040static bool BackRefMatchesNoCase(Isolate* isolate, int from, int current,
41 int len, Vector<const uint8_t> subject,
42 bool unicode) {
43 // For Latin1 characters the unicode flag makes no difference.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 for (int i = 0; i < len; i++) {
45 unsigned int old_char = subject[from++];
46 unsigned int new_char = subject[current++];
47 if (old_char == new_char) continue;
48 // Convert both characters to lower case.
49 old_char |= 0x20;
50 new_char |= 0x20;
51 if (old_char != new_char) return false;
52 // Not letters in the ASCII range and Latin-1 range.
53 if (!(old_char - 'a' <= 'z' - 'a') &&
54 !(old_char - 224 <= 254 - 224 && old_char != 247)) {
55 return false;
56 }
57 }
58 return true;
59}
60
61
62#ifdef DEBUG
63static void TraceInterpreter(const byte* code_base,
64 const byte* pc,
65 int stack_depth,
66 int current_position,
67 uint32_t current_char,
68 int bytecode_length,
69 const char* bytecode_name) {
70 if (FLAG_trace_regexp_bytecodes) {
71 bool printable = (current_char < 127 && current_char >= 32);
72 const char* format =
73 printable ?
74 "pc = %02x, sp = %d, curpos = %d, curchar = %08x (%c), bc = %s" :
75 "pc = %02x, sp = %d, curpos = %d, curchar = %08x .%c., bc = %s";
76 PrintF(format,
77 pc - code_base,
78 stack_depth,
79 current_position,
80 current_char,
81 printable ? current_char : '.',
82 bytecode_name);
83 for (int i = 0; i < bytecode_length; i++) {
84 printf(", %02x", pc[i]);
85 }
86 printf(" ");
87 for (int i = 1; i < bytecode_length; i++) {
88 unsigned char b = pc[i];
89 if (b < 127 && b >= 32) {
90 printf("%c", b);
91 } else {
92 printf(".");
93 }
94 }
95 printf("\n");
96 }
97}
98
99
100#define BYTECODE(name) \
101 case BC_##name: \
102 TraceInterpreter(code_base, \
103 pc, \
104 static_cast<int>(backtrack_sp - backtrack_stack_base), \
105 current, \
106 current_char, \
107 BC_##name##_LENGTH, \
108 #name);
109#else
110#define BYTECODE(name) \
111 case BC_##name:
112#endif
113
114
115static int32_t Load32Aligned(const byte* pc) {
116 DCHECK((reinterpret_cast<intptr_t>(pc) & 3) == 0);
117 return *reinterpret_cast<const int32_t *>(pc);
118}
119
120
121static int32_t Load16Aligned(const byte* pc) {
122 DCHECK((reinterpret_cast<intptr_t>(pc) & 1) == 0);
123 return *reinterpret_cast<const uint16_t *>(pc);
124}
125
126
127// A simple abstraction over the backtracking stack used by the interpreter.
128// This backtracking stack does not grow automatically, but it ensures that the
129// the memory held by the stack is released or remembered in a cache if the
130// matching terminates.
131class BacktrackStack {
132 public:
133 BacktrackStack() { data_ = NewArray<int>(kBacktrackStackSize); }
134
135 ~BacktrackStack() {
136 DeleteArray(data_);
137 }
138
139 int* data() const { return data_; }
140
141 int max_size() const { return kBacktrackStackSize; }
142
143 private:
144 static const int kBacktrackStackSize = 10000;
145
146 int* data_;
147
148 DISALLOW_COPY_AND_ASSIGN(BacktrackStack);
149};
150
151
152template <typename Char>
153static RegExpImpl::IrregexpResult RawMatch(Isolate* isolate,
154 const byte* code_base,
155 Vector<const Char> subject,
156 int* registers,
157 int current,
158 uint32_t current_char) {
159 const byte* pc = code_base;
160 // BacktrackStack ensures that the memory allocated for the backtracking stack
161 // is returned to the system or cached if there is no stack being cached at
162 // the moment.
163 BacktrackStack backtrack_stack;
164 int* backtrack_stack_base = backtrack_stack.data();
165 int* backtrack_sp = backtrack_stack_base;
166 int backtrack_stack_space = backtrack_stack.max_size();
167#ifdef DEBUG
168 if (FLAG_trace_regexp_bytecodes) {
169 PrintF("\n\nStart bytecode interpreter\n\n");
170 }
171#endif
172 while (true) {
173 int32_t insn = Load32Aligned(pc);
174 switch (insn & BYTECODE_MASK) {
175 BYTECODE(BREAK)
176 UNREACHABLE();
177 return RegExpImpl::RE_FAILURE;
178 BYTECODE(PUSH_CP)
179 if (--backtrack_stack_space < 0) {
180 return RegExpImpl::RE_EXCEPTION;
181 }
182 *backtrack_sp++ = current;
183 pc += BC_PUSH_CP_LENGTH;
184 break;
185 BYTECODE(PUSH_BT)
186 if (--backtrack_stack_space < 0) {
187 return RegExpImpl::RE_EXCEPTION;
188 }
189 *backtrack_sp++ = Load32Aligned(pc + 4);
190 pc += BC_PUSH_BT_LENGTH;
191 break;
192 BYTECODE(PUSH_REGISTER)
193 if (--backtrack_stack_space < 0) {
194 return RegExpImpl::RE_EXCEPTION;
195 }
196 *backtrack_sp++ = registers[insn >> BYTECODE_SHIFT];
197 pc += BC_PUSH_REGISTER_LENGTH;
198 break;
199 BYTECODE(SET_REGISTER)
200 registers[insn >> BYTECODE_SHIFT] = Load32Aligned(pc + 4);
201 pc += BC_SET_REGISTER_LENGTH;
202 break;
203 BYTECODE(ADVANCE_REGISTER)
204 registers[insn >> BYTECODE_SHIFT] += Load32Aligned(pc + 4);
205 pc += BC_ADVANCE_REGISTER_LENGTH;
206 break;
207 BYTECODE(SET_REGISTER_TO_CP)
208 registers[insn >> BYTECODE_SHIFT] = current + Load32Aligned(pc + 4);
209 pc += BC_SET_REGISTER_TO_CP_LENGTH;
210 break;
211 BYTECODE(SET_CP_TO_REGISTER)
212 current = registers[insn >> BYTECODE_SHIFT];
213 pc += BC_SET_CP_TO_REGISTER_LENGTH;
214 break;
215 BYTECODE(SET_REGISTER_TO_SP)
216 registers[insn >> BYTECODE_SHIFT] =
217 static_cast<int>(backtrack_sp - backtrack_stack_base);
218 pc += BC_SET_REGISTER_TO_SP_LENGTH;
219 break;
220 BYTECODE(SET_SP_TO_REGISTER)
221 backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT];
222 backtrack_stack_space = backtrack_stack.max_size() -
223 static_cast<int>(backtrack_sp - backtrack_stack_base);
224 pc += BC_SET_SP_TO_REGISTER_LENGTH;
225 break;
226 BYTECODE(POP_CP)
227 backtrack_stack_space++;
228 --backtrack_sp;
229 current = *backtrack_sp;
230 pc += BC_POP_CP_LENGTH;
231 break;
232 BYTECODE(POP_BT)
233 backtrack_stack_space++;
234 --backtrack_sp;
235 pc = code_base + *backtrack_sp;
236 break;
237 BYTECODE(POP_REGISTER)
238 backtrack_stack_space++;
239 --backtrack_sp;
240 registers[insn >> BYTECODE_SHIFT] = *backtrack_sp;
241 pc += BC_POP_REGISTER_LENGTH;
242 break;
243 BYTECODE(FAIL)
244 return RegExpImpl::RE_FAILURE;
245 BYTECODE(SUCCEED)
246 return RegExpImpl::RE_SUCCESS;
247 BYTECODE(ADVANCE_CP)
248 current += insn >> BYTECODE_SHIFT;
249 pc += BC_ADVANCE_CP_LENGTH;
250 break;
251 BYTECODE(GOTO)
252 pc = code_base + Load32Aligned(pc + 4);
253 break;
254 BYTECODE(ADVANCE_CP_AND_GOTO)
255 current += insn >> BYTECODE_SHIFT;
256 pc = code_base + Load32Aligned(pc + 4);
257 break;
258 BYTECODE(CHECK_GREEDY)
259 if (current == backtrack_sp[-1]) {
260 backtrack_sp--;
261 backtrack_stack_space++;
262 pc = code_base + Load32Aligned(pc + 4);
263 } else {
264 pc += BC_CHECK_GREEDY_LENGTH;
265 }
266 break;
267 BYTECODE(LOAD_CURRENT_CHAR) {
268 int pos = current + (insn >> BYTECODE_SHIFT);
269 if (pos >= subject.length() || pos < 0) {
270 pc = code_base + Load32Aligned(pc + 4);
271 } else {
272 current_char = subject[pos];
273 pc += BC_LOAD_CURRENT_CHAR_LENGTH;
274 }
275 break;
276 }
277 BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) {
278 int pos = current + (insn >> BYTECODE_SHIFT);
279 current_char = subject[pos];
280 pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH;
281 break;
282 }
283 BYTECODE(LOAD_2_CURRENT_CHARS) {
284 int pos = current + (insn >> BYTECODE_SHIFT);
285 if (pos + 2 > subject.length() || pos < 0) {
286 pc = code_base + Load32Aligned(pc + 4);
287 } else {
288 Char next = subject[pos + 1];
289 current_char =
290 (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
291 pc += BC_LOAD_2_CURRENT_CHARS_LENGTH;
292 }
293 break;
294 }
295 BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) {
296 int pos = current + (insn >> BYTECODE_SHIFT);
297 Char next = subject[pos + 1];
298 current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
299 pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH;
300 break;
301 }
302 BYTECODE(LOAD_4_CURRENT_CHARS) {
303 DCHECK(sizeof(Char) == 1);
304 int pos = current + (insn >> BYTECODE_SHIFT);
305 if (pos + 4 > subject.length() || pos < 0) {
306 pc = code_base + Load32Aligned(pc + 4);
307 } else {
308 Char next1 = subject[pos + 1];
309 Char next2 = subject[pos + 2];
310 Char next3 = subject[pos + 3];
311 current_char = (subject[pos] |
312 (next1 << 8) |
313 (next2 << 16) |
314 (next3 << 24));
315 pc += BC_LOAD_4_CURRENT_CHARS_LENGTH;
316 }
317 break;
318 }
319 BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) {
320 DCHECK(sizeof(Char) == 1);
321 int pos = current + (insn >> BYTECODE_SHIFT);
322 Char next1 = subject[pos + 1];
323 Char next2 = subject[pos + 2];
324 Char next3 = subject[pos + 3];
325 current_char = (subject[pos] |
326 (next1 << 8) |
327 (next2 << 16) |
328 (next3 << 24));
329 pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH;
330 break;
331 }
332 BYTECODE(CHECK_4_CHARS) {
333 uint32_t c = Load32Aligned(pc + 4);
334 if (c == current_char) {
335 pc = code_base + Load32Aligned(pc + 8);
336 } else {
337 pc += BC_CHECK_4_CHARS_LENGTH;
338 }
339 break;
340 }
341 BYTECODE(CHECK_CHAR) {
342 uint32_t c = (insn >> BYTECODE_SHIFT);
343 if (c == current_char) {
344 pc = code_base + Load32Aligned(pc + 4);
345 } else {
346 pc += BC_CHECK_CHAR_LENGTH;
347 }
348 break;
349 }
350 BYTECODE(CHECK_NOT_4_CHARS) {
351 uint32_t c = Load32Aligned(pc + 4);
352 if (c != current_char) {
353 pc = code_base + Load32Aligned(pc + 8);
354 } else {
355 pc += BC_CHECK_NOT_4_CHARS_LENGTH;
356 }
357 break;
358 }
359 BYTECODE(CHECK_NOT_CHAR) {
360 uint32_t c = (insn >> BYTECODE_SHIFT);
361 if (c != current_char) {
362 pc = code_base + Load32Aligned(pc + 4);
363 } else {
364 pc += BC_CHECK_NOT_CHAR_LENGTH;
365 }
366 break;
367 }
368 BYTECODE(AND_CHECK_4_CHARS) {
369 uint32_t c = Load32Aligned(pc + 4);
370 if (c == (current_char & Load32Aligned(pc + 8))) {
371 pc = code_base + Load32Aligned(pc + 12);
372 } else {
373 pc += BC_AND_CHECK_4_CHARS_LENGTH;
374 }
375 break;
376 }
377 BYTECODE(AND_CHECK_CHAR) {
378 uint32_t c = (insn >> BYTECODE_SHIFT);
379 if (c == (current_char & Load32Aligned(pc + 4))) {
380 pc = code_base + Load32Aligned(pc + 8);
381 } else {
382 pc += BC_AND_CHECK_CHAR_LENGTH;
383 }
384 break;
385 }
386 BYTECODE(AND_CHECK_NOT_4_CHARS) {
387 uint32_t c = Load32Aligned(pc + 4);
388 if (c != (current_char & Load32Aligned(pc + 8))) {
389 pc = code_base + Load32Aligned(pc + 12);
390 } else {
391 pc += BC_AND_CHECK_NOT_4_CHARS_LENGTH;
392 }
393 break;
394 }
395 BYTECODE(AND_CHECK_NOT_CHAR) {
396 uint32_t c = (insn >> BYTECODE_SHIFT);
397 if (c != (current_char & Load32Aligned(pc + 4))) {
398 pc = code_base + Load32Aligned(pc + 8);
399 } else {
400 pc += BC_AND_CHECK_NOT_CHAR_LENGTH;
401 }
402 break;
403 }
404 BYTECODE(MINUS_AND_CHECK_NOT_CHAR) {
405 uint32_t c = (insn >> BYTECODE_SHIFT);
406 uint32_t minus = Load16Aligned(pc + 4);
407 uint32_t mask = Load16Aligned(pc + 6);
408 if (c != ((current_char - minus) & mask)) {
409 pc = code_base + Load32Aligned(pc + 8);
410 } else {
411 pc += BC_MINUS_AND_CHECK_NOT_CHAR_LENGTH;
412 }
413 break;
414 }
415 BYTECODE(CHECK_CHAR_IN_RANGE) {
416 uint32_t from = Load16Aligned(pc + 4);
417 uint32_t to = Load16Aligned(pc + 6);
418 if (from <= current_char && current_char <= to) {
419 pc = code_base + Load32Aligned(pc + 8);
420 } else {
421 pc += BC_CHECK_CHAR_IN_RANGE_LENGTH;
422 }
423 break;
424 }
425 BYTECODE(CHECK_CHAR_NOT_IN_RANGE) {
426 uint32_t from = Load16Aligned(pc + 4);
427 uint32_t to = Load16Aligned(pc + 6);
428 if (from > current_char || current_char > to) {
429 pc = code_base + Load32Aligned(pc + 8);
430 } else {
431 pc += BC_CHECK_CHAR_NOT_IN_RANGE_LENGTH;
432 }
433 break;
434 }
435 BYTECODE(CHECK_BIT_IN_TABLE) {
436 int mask = RegExpMacroAssembler::kTableMask;
437 byte b = pc[8 + ((current_char & mask) >> kBitsPerByteLog2)];
438 int bit = (current_char & (kBitsPerByte - 1));
439 if ((b & (1 << bit)) != 0) {
440 pc = code_base + Load32Aligned(pc + 4);
441 } else {
442 pc += BC_CHECK_BIT_IN_TABLE_LENGTH;
443 }
444 break;
445 }
446 BYTECODE(CHECK_LT) {
447 uint32_t limit = (insn >> BYTECODE_SHIFT);
448 if (current_char < limit) {
449 pc = code_base + Load32Aligned(pc + 4);
450 } else {
451 pc += BC_CHECK_LT_LENGTH;
452 }
453 break;
454 }
455 BYTECODE(CHECK_GT) {
456 uint32_t limit = (insn >> BYTECODE_SHIFT);
457 if (current_char > limit) {
458 pc = code_base + Load32Aligned(pc + 4);
459 } else {
460 pc += BC_CHECK_GT_LENGTH;
461 }
462 break;
463 }
464 BYTECODE(CHECK_REGISTER_LT)
465 if (registers[insn >> BYTECODE_SHIFT] < Load32Aligned(pc + 4)) {
466 pc = code_base + Load32Aligned(pc + 8);
467 } else {
468 pc += BC_CHECK_REGISTER_LT_LENGTH;
469 }
470 break;
471 BYTECODE(CHECK_REGISTER_GE)
472 if (registers[insn >> BYTECODE_SHIFT] >= Load32Aligned(pc + 4)) {
473 pc = code_base + Load32Aligned(pc + 8);
474 } else {
475 pc += BC_CHECK_REGISTER_GE_LENGTH;
476 }
477 break;
478 BYTECODE(CHECK_REGISTER_EQ_POS)
479 if (registers[insn >> BYTECODE_SHIFT] == current) {
480 pc = code_base + Load32Aligned(pc + 4);
481 } else {
482 pc += BC_CHECK_REGISTER_EQ_POS_LENGTH;
483 }
484 break;
485 BYTECODE(CHECK_NOT_REGS_EQUAL)
486 if (registers[insn >> BYTECODE_SHIFT] ==
487 registers[Load32Aligned(pc + 4)]) {
488 pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH;
489 } else {
490 pc = code_base + Load32Aligned(pc + 8);
491 }
492 break;
493 BYTECODE(CHECK_NOT_BACK_REF) {
494 int from = registers[insn >> BYTECODE_SHIFT];
495 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
496 if (from >= 0 && len > 0) {
497 if (current + len > subject.length() ||
498 CompareChars(&subject[from], &subject[current], len) != 0) {
499 pc = code_base + Load32Aligned(pc + 4);
500 break;
501 }
502 current += len;
503 }
504 pc += BC_CHECK_NOT_BACK_REF_LENGTH;
505 break;
506 }
507 BYTECODE(CHECK_NOT_BACK_REF_BACKWARD) {
508 int from = registers[insn >> BYTECODE_SHIFT];
509 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
510 if (from >= 0 && len > 0) {
511 if (current - len < 0 ||
512 CompareChars(&subject[from], &subject[current - len], len) != 0) {
513 pc = code_base + Load32Aligned(pc + 4);
514 break;
515 }
516 current -= len;
517 }
518 pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH;
519 break;
520 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100521 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_UNICODE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000522 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100523 bool unicode =
524 (insn & BYTECODE_MASK) == BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525 int from = registers[insn >> BYTECODE_SHIFT];
526 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
527 if (from >= 0 && len > 0) {
528 if (current + len > subject.length() ||
Ben Murdoch097c5b22016-05-18 11:27:45 +0100529 !BackRefMatchesNoCase(isolate, from, current, len, subject,
530 unicode)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000531 pc = code_base + Load32Aligned(pc + 4);
532 break;
533 }
534 current += len;
535 }
536 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
537 break;
538 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100539 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_UNICODE_BACKWARD)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000540 BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100541 bool unicode = (insn & BYTECODE_MASK) ==
542 BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE_BACKWARD;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000543 int from = registers[insn >> BYTECODE_SHIFT];
544 int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
545 if (from >= 0 && len > 0) {
546 if (current - len < 0 ||
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 !BackRefMatchesNoCase(isolate, from, current - len, len, subject,
548 unicode)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000549 pc = code_base + Load32Aligned(pc + 4);
550 break;
551 }
552 current -= len;
553 }
554 pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
555 break;
556 }
557 BYTECODE(CHECK_AT_START)
558 if (current == 0) {
559 pc = code_base + Load32Aligned(pc + 4);
560 } else {
561 pc += BC_CHECK_AT_START_LENGTH;
562 }
563 break;
564 BYTECODE(CHECK_NOT_AT_START)
565 if (current + (insn >> BYTECODE_SHIFT) == 0) {
566 pc += BC_CHECK_NOT_AT_START_LENGTH;
567 } else {
568 pc = code_base + Load32Aligned(pc + 4);
569 }
570 break;
571 BYTECODE(SET_CURRENT_POSITION_FROM_END) {
572 int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT;
573 if (subject.length() - current > by) {
574 current = subject.length() - by;
575 current_char = subject[current - 1];
576 }
577 pc += BC_SET_CURRENT_POSITION_FROM_END_LENGTH;
578 break;
579 }
580 default:
581 UNREACHABLE();
582 break;
583 }
584 }
585}
586
587
588RegExpImpl::IrregexpResult IrregexpInterpreter::Match(
589 Isolate* isolate,
590 Handle<ByteArray> code_array,
591 Handle<String> subject,
592 int* registers,
593 int start_position) {
594 DCHECK(subject->IsFlat());
595
596 DisallowHeapAllocation no_gc;
597 const byte* code_base = code_array->GetDataStartAddress();
598 uc16 previous_char = '\n';
599 String::FlatContent subject_content = subject->GetFlatContent();
600 if (subject_content.IsOneByte()) {
601 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
602 if (start_position != 0) previous_char = subject_vector[start_position - 1];
603 return RawMatch(isolate,
604 code_base,
605 subject_vector,
606 registers,
607 start_position,
608 previous_char);
609 } else {
610 DCHECK(subject_content.IsTwoByte());
611 Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
612 if (start_position != 0) previous_char = subject_vector[start_position - 1];
613 return RawMatch(isolate,
614 code_base,
615 subject_vector,
616 registers,
617 start_position,
618 previous_char);
619 }
620}
621
622} // namespace internal
623} // namespace v8
Ben Murdoch097c5b22016-05-18 11:27:45 +0100624
625#endif // V8_INTERPRETED_REGEXP