v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interpreter-irregexp.cc
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 // A simple interpreter for the Irregexp byte code.
29 
30 
31 #include "v8.h"
32 #include "unicode.h"
33 #include "utils.h"
34 #include "ast.h"
35 #include "bytecodes-irregexp.h"
36 #include "interpreter-irregexp.h"
37 #include "jsregexp.h"
38 #include "regexp-macro-assembler.h"
39 
40 namespace v8 {
41 namespace internal {
42 
43 
45 
46 static bool BackRefMatchesNoCase(Canonicalize* interp_canonicalize,
47  int from,
48  int current,
49  int len,
50  Vector<const uc16> subject) {
51  for (int i = 0; i < len; i++) {
52  unibrow::uchar old_char = subject[from++];
53  unibrow::uchar new_char = subject[current++];
54  if (old_char == new_char) continue;
55  unibrow::uchar old_string[1] = { old_char };
56  unibrow::uchar new_string[1] = { new_char };
57  interp_canonicalize->get(old_char, '\0', old_string);
58  interp_canonicalize->get(new_char, '\0', new_string);
59  if (old_string[0] != new_string[0]) {
60  return false;
61  }
62  }
63  return true;
64 }
65 
66 
67 static bool BackRefMatchesNoCase(Canonicalize* interp_canonicalize,
68  int from,
69  int current,
70  int len,
71  Vector<const char> subject) {
72  for (int i = 0; i < len; i++) {
73  unsigned int old_char = subject[from++];
74  unsigned int new_char = subject[current++];
75  if (old_char == new_char) continue;
76  if (old_char - 'A' <= 'Z' - 'A') old_char |= 0x20;
77  if (new_char - 'A' <= 'Z' - 'A') new_char |= 0x20;
78  if (old_char != new_char) return false;
79  }
80  return true;
81 }
82 
83 
84 #ifdef DEBUG
85 static void TraceInterpreter(const byte* code_base,
86  const byte* pc,
87  int stack_depth,
88  int current_position,
89  uint32_t current_char,
90  int bytecode_length,
91  const char* bytecode_name) {
92  if (FLAG_trace_regexp_bytecodes) {
93  bool printable = (current_char < 127 && current_char >= 32);
94  const char* format =
95  printable ?
96  "pc = %02x, sp = %d, curpos = %d, curchar = %08x (%c), bc = %s" :
97  "pc = %02x, sp = %d, curpos = %d, curchar = %08x .%c., bc = %s";
98  PrintF(format,
99  pc - code_base,
100  stack_depth,
101  current_position,
102  current_char,
103  printable ? current_char : '.',
104  bytecode_name);
105  for (int i = 0; i < bytecode_length; i++) {
106  printf(", %02x", pc[i]);
107  }
108  printf(" ");
109  for (int i = 1; i < bytecode_length; i++) {
110  unsigned char b = pc[i];
111  if (b < 127 && b >= 32) {
112  printf("%c", b);
113  } else {
114  printf(".");
115  }
116  }
117  printf("\n");
118  }
119 }
120 
121 
122 #define BYTECODE(name) \
123  case BC_##name: \
124  TraceInterpreter(code_base, \
125  pc, \
126  static_cast<int>(backtrack_sp - backtrack_stack_base), \
127  current, \
128  current_char, \
129  BC_##name##_LENGTH, \
130  #name);
131 #else
132 #define BYTECODE(name) \
133  case BC_##name:
134 #endif
135 
136 
137 static int32_t Load32Aligned(const byte* pc) {
138  ASSERT((reinterpret_cast<intptr_t>(pc) & 3) == 0);
139  return *reinterpret_cast<const int32_t *>(pc);
140 }
141 
142 
143 static int32_t Load16Aligned(const byte* pc) {
144  ASSERT((reinterpret_cast<intptr_t>(pc) & 1) == 0);
145  return *reinterpret_cast<const uint16_t *>(pc);
146 }
147 
148 
149 // A simple abstraction over the backtracking stack used by the interpreter.
150 // This backtracking stack does not grow automatically, but it ensures that the
151 // the memory held by the stack is released or remembered in a cache if the
152 // matching terminates.
154  public:
155  explicit BacktrackStack(Isolate* isolate) : isolate_(isolate) {
156  if (isolate->irregexp_interpreter_backtrack_stack_cache() != NULL) {
157  // If the cache is not empty reuse the previously allocated stack.
158  data_ = isolate->irregexp_interpreter_backtrack_stack_cache();
159  isolate->set_irregexp_interpreter_backtrack_stack_cache(NULL);
160  } else {
161  // Cache was empty. Allocate a new backtrack stack.
162  data_ = NewArray<int>(kBacktrackStackSize);
163  }
164  }
165 
167  if (isolate_->irregexp_interpreter_backtrack_stack_cache() == NULL) {
168  // The cache is empty. Keep this backtrack stack around.
169  isolate_->set_irregexp_interpreter_backtrack_stack_cache(data_);
170  } else {
171  // A backtrack stack was already cached, just release this one.
172  DeleteArray(data_);
173  }
174  }
175 
176  int* data() const { return data_; }
177 
178  int max_size() const { return kBacktrackStackSize; }
179 
180  private:
181  static const int kBacktrackStackSize = 10000;
182 
183  int* data_;
184  Isolate* isolate_;
185 
186  DISALLOW_COPY_AND_ASSIGN(BacktrackStack);
187 };
188 
189 
190 template <typename Char>
191 static RegExpImpl::IrregexpResult RawMatch(Isolate* isolate,
192  const byte* code_base,
193  Vector<const Char> subject,
194  int* registers,
195  int current,
196  uint32_t current_char) {
197  const byte* pc = code_base;
198  // BacktrackStack ensures that the memory allocated for the backtracking stack
199  // is returned to the system or cached if there is no stack being cached at
200  // the moment.
201  BacktrackStack backtrack_stack(isolate);
202  int* backtrack_stack_base = backtrack_stack.data();
203  int* backtrack_sp = backtrack_stack_base;
204  int backtrack_stack_space = backtrack_stack.max_size();
205 #ifdef DEBUG
206  if (FLAG_trace_regexp_bytecodes) {
207  PrintF("\n\nStart bytecode interpreter\n\n");
208  }
209 #endif
210  while (true) {
211  int32_t insn = Load32Aligned(pc);
212  switch (insn & BYTECODE_MASK) {
213  BYTECODE(BREAK)
214  UNREACHABLE();
215  return RegExpImpl::RE_FAILURE;
216  BYTECODE(PUSH_CP)
217  if (--backtrack_stack_space < 0) {
219  }
220  *backtrack_sp++ = current;
221  pc += BC_PUSH_CP_LENGTH;
222  break;
223  BYTECODE(PUSH_BT)
224  if (--backtrack_stack_space < 0) {
226  }
227  *backtrack_sp++ = Load32Aligned(pc + 4);
228  pc += BC_PUSH_BT_LENGTH;
229  break;
230  BYTECODE(PUSH_REGISTER)
231  if (--backtrack_stack_space < 0) {
233  }
234  *backtrack_sp++ = registers[insn >> BYTECODE_SHIFT];
235  pc += BC_PUSH_REGISTER_LENGTH;
236  break;
237  BYTECODE(SET_REGISTER)
238  registers[insn >> BYTECODE_SHIFT] = Load32Aligned(pc + 4);
239  pc += BC_SET_REGISTER_LENGTH;
240  break;
241  BYTECODE(ADVANCE_REGISTER)
242  registers[insn >> BYTECODE_SHIFT] += Load32Aligned(pc + 4);
243  pc += BC_ADVANCE_REGISTER_LENGTH;
244  break;
245  BYTECODE(SET_REGISTER_TO_CP)
246  registers[insn >> BYTECODE_SHIFT] = current + Load32Aligned(pc + 4);
247  pc += BC_SET_REGISTER_TO_CP_LENGTH;
248  break;
249  BYTECODE(SET_CP_TO_REGISTER)
250  current = registers[insn >> BYTECODE_SHIFT];
251  pc += BC_SET_CP_TO_REGISTER_LENGTH;
252  break;
253  BYTECODE(SET_REGISTER_TO_SP)
254  registers[insn >> BYTECODE_SHIFT] =
255  static_cast<int>(backtrack_sp - backtrack_stack_base);
256  pc += BC_SET_REGISTER_TO_SP_LENGTH;
257  break;
258  BYTECODE(SET_SP_TO_REGISTER)
259  backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT];
260  backtrack_stack_space = backtrack_stack.max_size() -
261  static_cast<int>(backtrack_sp - backtrack_stack_base);
262  pc += BC_SET_SP_TO_REGISTER_LENGTH;
263  break;
264  BYTECODE(POP_CP)
265  backtrack_stack_space++;
266  --backtrack_sp;
267  current = *backtrack_sp;
268  pc += BC_POP_CP_LENGTH;
269  break;
270  BYTECODE(POP_BT)
271  backtrack_stack_space++;
272  --backtrack_sp;
273  pc = code_base + *backtrack_sp;
274  break;
275  BYTECODE(POP_REGISTER)
276  backtrack_stack_space++;
277  --backtrack_sp;
278  registers[insn >> BYTECODE_SHIFT] = *backtrack_sp;
279  pc += BC_POP_REGISTER_LENGTH;
280  break;
281  BYTECODE(FAIL)
282  return RegExpImpl::RE_FAILURE;
283  BYTECODE(SUCCEED)
284  return RegExpImpl::RE_SUCCESS;
285  BYTECODE(ADVANCE_CP)
286  current += insn >> BYTECODE_SHIFT;
287  pc += BC_ADVANCE_CP_LENGTH;
288  break;
289  BYTECODE(GOTO)
290  pc = code_base + Load32Aligned(pc + 4);
291  break;
292  BYTECODE(ADVANCE_CP_AND_GOTO)
293  current += insn >> BYTECODE_SHIFT;
294  pc = code_base + Load32Aligned(pc + 4);
295  break;
296  BYTECODE(CHECK_GREEDY)
297  if (current == backtrack_sp[-1]) {
298  backtrack_sp--;
299  backtrack_stack_space++;
300  pc = code_base + Load32Aligned(pc + 4);
301  } else {
302  pc += BC_CHECK_GREEDY_LENGTH;
303  }
304  break;
305  BYTECODE(LOAD_CURRENT_CHAR) {
306  int pos = current + (insn >> BYTECODE_SHIFT);
307  if (pos >= subject.length()) {
308  pc = code_base + Load32Aligned(pc + 4);
309  } else {
310  current_char = subject[pos];
311  pc += BC_LOAD_CURRENT_CHAR_LENGTH;
312  }
313  break;
314  }
315  BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) {
316  int pos = current + (insn >> BYTECODE_SHIFT);
317  current_char = subject[pos];
318  pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH;
319  break;
320  }
321  BYTECODE(LOAD_2_CURRENT_CHARS) {
322  int pos = current + (insn >> BYTECODE_SHIFT);
323  if (pos + 2 > subject.length()) {
324  pc = code_base + Load32Aligned(pc + 4);
325  } else {
326  Char next = subject[pos + 1];
327  current_char =
328  (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
329  pc += BC_LOAD_2_CURRENT_CHARS_LENGTH;
330  }
331  break;
332  }
333  BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) {
334  int pos = current + (insn >> BYTECODE_SHIFT);
335  Char next = subject[pos + 1];
336  current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
337  pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH;
338  break;
339  }
340  BYTECODE(LOAD_4_CURRENT_CHARS) {
341  ASSERT(sizeof(Char) == 1);
342  int pos = current + (insn >> BYTECODE_SHIFT);
343  if (pos + 4 > subject.length()) {
344  pc = code_base + Load32Aligned(pc + 4);
345  } else {
346  Char next1 = subject[pos + 1];
347  Char next2 = subject[pos + 2];
348  Char next3 = subject[pos + 3];
349  current_char = (subject[pos] |
350  (next1 << 8) |
351  (next2 << 16) |
352  (next3 << 24));
353  pc += BC_LOAD_4_CURRENT_CHARS_LENGTH;
354  }
355  break;
356  }
357  BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) {
358  ASSERT(sizeof(Char) == 1);
359  int pos = current + (insn >> BYTECODE_SHIFT);
360  Char next1 = subject[pos + 1];
361  Char next2 = subject[pos + 2];
362  Char next3 = subject[pos + 3];
363  current_char = (subject[pos] |
364  (next1 << 8) |
365  (next2 << 16) |
366  (next3 << 24));
367  pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH;
368  break;
369  }
370  BYTECODE(CHECK_4_CHARS) {
371  uint32_t c = Load32Aligned(pc + 4);
372  if (c == current_char) {
373  pc = code_base + Load32Aligned(pc + 8);
374  } else {
375  pc += BC_CHECK_4_CHARS_LENGTH;
376  }
377  break;
378  }
379  BYTECODE(CHECK_CHAR) {
380  uint32_t c = (insn >> BYTECODE_SHIFT);
381  if (c == current_char) {
382  pc = code_base + Load32Aligned(pc + 4);
383  } else {
384  pc += BC_CHECK_CHAR_LENGTH;
385  }
386  break;
387  }
388  BYTECODE(CHECK_NOT_4_CHARS) {
389  uint32_t c = Load32Aligned(pc + 4);
390  if (c != current_char) {
391  pc = code_base + Load32Aligned(pc + 8);
392  } else {
393  pc += BC_CHECK_NOT_4_CHARS_LENGTH;
394  }
395  break;
396  }
397  BYTECODE(CHECK_NOT_CHAR) {
398  uint32_t c = (insn >> BYTECODE_SHIFT);
399  if (c != current_char) {
400  pc = code_base + Load32Aligned(pc + 4);
401  } else {
402  pc += BC_CHECK_NOT_CHAR_LENGTH;
403  }
404  break;
405  }
406  BYTECODE(AND_CHECK_4_CHARS) {
407  uint32_t c = Load32Aligned(pc + 4);
408  if (c == (current_char & Load32Aligned(pc + 8))) {
409  pc = code_base + Load32Aligned(pc + 12);
410  } else {
411  pc += BC_AND_CHECK_4_CHARS_LENGTH;
412  }
413  break;
414  }
415  BYTECODE(AND_CHECK_CHAR) {
416  uint32_t c = (insn >> BYTECODE_SHIFT);
417  if (c == (current_char & Load32Aligned(pc + 4))) {
418  pc = code_base + Load32Aligned(pc + 8);
419  } else {
420  pc += BC_AND_CHECK_CHAR_LENGTH;
421  }
422  break;
423  }
424  BYTECODE(AND_CHECK_NOT_4_CHARS) {
425  uint32_t c = Load32Aligned(pc + 4);
426  if (c != (current_char & Load32Aligned(pc + 8))) {
427  pc = code_base + Load32Aligned(pc + 12);
428  } else {
429  pc += BC_AND_CHECK_NOT_4_CHARS_LENGTH;
430  }
431  break;
432  }
433  BYTECODE(AND_CHECK_NOT_CHAR) {
434  uint32_t c = (insn >> BYTECODE_SHIFT);
435  if (c != (current_char & Load32Aligned(pc + 4))) {
436  pc = code_base + Load32Aligned(pc + 8);
437  } else {
438  pc += BC_AND_CHECK_NOT_CHAR_LENGTH;
439  }
440  break;
441  }
442  BYTECODE(MINUS_AND_CHECK_NOT_CHAR) {
443  uint32_t c = (insn >> BYTECODE_SHIFT);
444  uint32_t minus = Load16Aligned(pc + 4);
445  uint32_t mask = Load16Aligned(pc + 6);
446  if (c != ((current_char - minus) & mask)) {
447  pc = code_base + Load32Aligned(pc + 8);
448  } else {
449  pc += BC_MINUS_AND_CHECK_NOT_CHAR_LENGTH;
450  }
451  break;
452  }
453  BYTECODE(CHECK_CHAR_IN_RANGE) {
454  uint32_t from = Load16Aligned(pc + 4);
455  uint32_t to = Load16Aligned(pc + 6);
456  if (from <= current_char && current_char <= to) {
457  pc = code_base + Load32Aligned(pc + 8);
458  } else {
459  pc += BC_CHECK_CHAR_IN_RANGE_LENGTH;
460  }
461  break;
462  }
463  BYTECODE(CHECK_CHAR_NOT_IN_RANGE) {
464  uint32_t from = Load16Aligned(pc + 4);
465  uint32_t to = Load16Aligned(pc + 6);
466  if (from > current_char || current_char > to) {
467  pc = code_base + Load32Aligned(pc + 8);
468  } else {
469  pc += BC_CHECK_CHAR_NOT_IN_RANGE_LENGTH;
470  }
471  break;
472  }
473  BYTECODE(CHECK_BIT_IN_TABLE) {
475  byte b = pc[8 + ((current_char & mask) >> kBitsPerByteLog2)];
476  int bit = (current_char & (kBitsPerByte - 1));
477  if ((b & (1 << bit)) != 0) {
478  pc = code_base + Load32Aligned(pc + 4);
479  } else {
480  pc += BC_CHECK_BIT_IN_TABLE_LENGTH;
481  }
482  break;
483  }
484  BYTECODE(CHECK_LT) {
485  uint32_t limit = (insn >> BYTECODE_SHIFT);
486  if (current_char < limit) {
487  pc = code_base + Load32Aligned(pc + 4);
488  } else {
489  pc += BC_CHECK_LT_LENGTH;
490  }
491  break;
492  }
493  BYTECODE(CHECK_GT) {
494  uint32_t limit = (insn >> BYTECODE_SHIFT);
495  if (current_char > limit) {
496  pc = code_base + Load32Aligned(pc + 4);
497  } else {
498  pc += BC_CHECK_GT_LENGTH;
499  }
500  break;
501  }
502  BYTECODE(CHECK_REGISTER_LT)
503  if (registers[insn >> BYTECODE_SHIFT] < Load32Aligned(pc + 4)) {
504  pc = code_base + Load32Aligned(pc + 8);
505  } else {
506  pc += BC_CHECK_REGISTER_LT_LENGTH;
507  }
508  break;
509  BYTECODE(CHECK_REGISTER_GE)
510  if (registers[insn >> BYTECODE_SHIFT] >= Load32Aligned(pc + 4)) {
511  pc = code_base + Load32Aligned(pc + 8);
512  } else {
513  pc += BC_CHECK_REGISTER_GE_LENGTH;
514  }
515  break;
516  BYTECODE(CHECK_REGISTER_EQ_POS)
517  if (registers[insn >> BYTECODE_SHIFT] == current) {
518  pc = code_base + Load32Aligned(pc + 4);
519  } else {
520  pc += BC_CHECK_REGISTER_EQ_POS_LENGTH;
521  }
522  break;
523  BYTECODE(CHECK_NOT_REGS_EQUAL)
524  if (registers[insn >> BYTECODE_SHIFT] ==
525  registers[Load32Aligned(pc + 4)]) {
526  pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH;
527  } else {
528  pc = code_base + Load32Aligned(pc + 8);
529  }
530  break;
531  BYTECODE(CHECK_NOT_BACK_REF) {
532  int from = registers[insn >> BYTECODE_SHIFT];
533  int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
534  if (from < 0 || len <= 0) {
535  pc += BC_CHECK_NOT_BACK_REF_LENGTH;
536  break;
537  }
538  if (current + len > subject.length()) {
539  pc = code_base + Load32Aligned(pc + 4);
540  break;
541  } else {
542  int i;
543  for (i = 0; i < len; i++) {
544  if (subject[from + i] != subject[current + i]) {
545  pc = code_base + Load32Aligned(pc + 4);
546  break;
547  }
548  }
549  if (i < len) break;
550  current += len;
551  }
552  pc += BC_CHECK_NOT_BACK_REF_LENGTH;
553  break;
554  }
555  BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
556  int from = registers[insn >> BYTECODE_SHIFT];
557  int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
558  if (from < 0 || len <= 0) {
559  pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
560  break;
561  }
562  if (current + len > subject.length()) {
563  pc = code_base + Load32Aligned(pc + 4);
564  break;
565  } else {
566  if (BackRefMatchesNoCase(isolate->interp_canonicalize_mapping(),
567  from, current, len, subject)) {
568  current += len;
569  pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
570  } else {
571  pc = code_base + Load32Aligned(pc + 4);
572  }
573  }
574  break;
575  }
576  BYTECODE(CHECK_AT_START)
577  if (current == 0) {
578  pc = code_base + Load32Aligned(pc + 4);
579  } else {
580  pc += BC_CHECK_AT_START_LENGTH;
581  }
582  break;
583  BYTECODE(CHECK_NOT_AT_START)
584  if (current == 0) {
585  pc += BC_CHECK_NOT_AT_START_LENGTH;
586  } else {
587  pc = code_base + Load32Aligned(pc + 4);
588  }
589  break;
590  BYTECODE(SET_CURRENT_POSITION_FROM_END) {
591  int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT;
592  if (subject.length() - current > by) {
593  current = subject.length() - by;
594  current_char = subject[current - 1];
595  }
596  pc += BC_SET_CURRENT_POSITION_FROM_END_LENGTH;
597  break;
598  }
599  default:
600  UNREACHABLE();
601  break;
602  }
603  }
604 }
605 
606 
608  Isolate* isolate,
609  Handle<ByteArray> code_array,
610  Handle<String> subject,
611  int* registers,
612  int start_position) {
613  ASSERT(subject->IsFlat());
614 
616  const byte* code_base = code_array->GetDataStartAddress();
617  uc16 previous_char = '\n';
618  String::FlatContent subject_content = subject->GetFlatContent();
619  if (subject_content.IsAscii()) {
620  Vector<const char> subject_vector = subject_content.ToAsciiVector();
621  if (start_position != 0) previous_char = subject_vector[start_position - 1];
622  return RawMatch(isolate,
623  code_base,
624  subject_vector,
625  registers,
626  start_position,
627  previous_char);
628  } else {
629  ASSERT(subject_content.IsTwoByte());
630  Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
631  if (start_position != 0) previous_char = subject_vector[start_position - 1];
632  return RawMatch(isolate,
633  code_base,
634  subject_vector,
635  registers,
636  start_position,
637  previous_char);
638  }
639 }
640 
641 } } // namespace v8::internal
void PrintF(const char *format,...)
Definition: v8utils.cc:40
#define CHECK_GT(a, b)
Definition: checks.h:227
Vector< const char > ToAsciiVector()
Definition: objects.h:6918
int int32_t
Definition: unicode.cc:47
const int kBitsPerByteLog2
Definition: globals.h:252
#define CHECK_LT(a, b)
Definition: checks.h:229
unibrow::Mapping< unibrow::Ecma262Canonicalize > Canonicalize
const int BYTECODE_MASK
#define ASSERT(condition)
Definition: checks.h:270
unsigned short uint16_t
Definition: unicode.cc:46
int get(uchar c, uchar n, uchar *result)
Definition: unicode-inl.h:48
uint8_t byte
Definition: globals.h:171
#define UNREACHABLE()
Definition: checks.h:50
static RegExpImpl::IrregexpResult Match(Isolate *isolate, Handle< ByteArray > code, Handle< String > subject, int *captures, int start_position)
const Register pc
Vector< const uc16 > ToUC16Vector()
Definition: objects.h:6924
const int kBitsPerByte
Definition: globals.h:251
uint16_t uc16
Definition: globals.h:273
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
void DeleteArray(T *array)
Definition: allocation.h:91
const int BYTECODE_SHIFT
#define BYTECODE(name)
unsigned int uchar
Definition: unicode.h:40