The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / interpreter-irregexp.cc @ 40c0f755

History | View | Annotate | Download (19.9 KB)

1
// Copyright 2008 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

    
38

    
39
namespace v8 { namespace internal {
40

    
41

    
42
static unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize;
43

    
44

    
45
static bool BackRefMatchesNoCase(int from,
46
                                 int current,
47
                                 int len,
48
                                 Vector<const uc16> subject) {
49
  for (int i = 0; i < len; i++) {
50
    unibrow::uchar old_char = subject[from++];
51
    unibrow::uchar new_char = subject[current++];
52
    if (old_char == new_char) continue;
53
    interp_canonicalize.get(old_char, '\0', &old_char);
54
    interp_canonicalize.get(new_char, '\0', &new_char);
55
    if (old_char != new_char) {
56
      return false;
57
    }
58
  }
59
  return true;
60
}
61

    
62

    
63
static bool BackRefMatchesNoCase(int from,
64
                                 int current,
65
                                 int len,
66
                                 Vector<const char> subject) {
67
  for (int i = 0; i < len; i++) {
68
    unsigned int old_char = subject[from++];
69
    unsigned int new_char = subject[current++];
70
    if (old_char == new_char) continue;
71
    if (old_char - 'A' <= 'Z' - 'A') old_char |= 0x20;
72
    if (new_char - 'A' <= 'Z' - 'A') new_char |= 0x20;
73
    if (old_char != new_char) return false;
74
  }
75
  return true;
76
}
77

    
78

    
79
#ifdef DEBUG
80
static void TraceInterpreter(const byte* code_base,
81
                             const byte* pc,
82
                             int stack_depth,
83
                             int current_position,
84
                             uint32_t current_char,
85
                             int bytecode_length,
86
                             const char* bytecode_name) {
87
  if (FLAG_trace_regexp_bytecodes) {
88
    bool printable = (current_char < 127 && current_char >= 32);
89
    const char* format =
90
        printable ?
91
        "pc = %02x, sp = %d, curpos = %d, curchar = %08x (%c), bc = %s" :
92
        "pc = %02x, sp = %d, curpos = %d, curchar = %08x .%c., bc = %s";
93
    PrintF(format,
94
           pc - code_base,
95
           stack_depth,
96
           current_position,
97
           current_char,
98
           printable ? current_char : '.',
99
           bytecode_name);
100
    for (int i = 0; i < bytecode_length; i++) {
101
      printf(", %02x", pc[i]);
102
    }
103
    printf(" ");
104
    for (int i = 1; i < bytecode_length; i++) {
105
      unsigned char b = pc[i];
106
      if (b < 127 && b >= 32) {
107
        printf("%c", b);
108
      } else {
109
        printf(".");
110
      }
111
    }
112
    printf("\n");
113
  }
114
}
115

    
116

    
117
#define BYTECODE(name)                                  \
118
  case BC_##name:                                       \
119
    TraceInterpreter(code_base,                         \
120
                     pc,                                \
121
                     backtrack_sp - backtrack_stack,    \
122
                     current,                           \
123
                     current_char,                      \
124
                     BC_##name##_LENGTH,                \
125
                     #name);
126
#else
127
#define BYTECODE(name)                                  \
128
  case BC_##name:
129
#endif
130

    
131

    
132
static int32_t Load32Aligned(const byte* pc) {
133
  ASSERT((reinterpret_cast<int>(pc) & 3) == 0);
134
  return *reinterpret_cast<const int32_t *>(pc);
135
}
136

    
137

    
138
static int32_t Load16Aligned(const byte* pc) {
139
  ASSERT((reinterpret_cast<int>(pc) & 1) == 0);
140
  return *reinterpret_cast<const uint16_t *>(pc);
141
}
142

    
143

    
144
template <typename Char>
145
static bool RawMatch(const byte* code_base,
146
                     Vector<const Char> subject,
147
                     int* registers,
148
                     int current,
149
                     uint32_t current_char) {
150
  const byte* pc = code_base;
151
  static const int kBacktrackStackSize = 10000;
152
  int backtrack_stack[kBacktrackStackSize];
153
  int backtrack_stack_space = kBacktrackStackSize;
154
  int* backtrack_sp = backtrack_stack;
155
#ifdef DEBUG
156
  if (FLAG_trace_regexp_bytecodes) {
157
    PrintF("\n\nStart bytecode interpreter\n\n");
158
  }
159
#endif
160
  while (true) {
161
    int32_t insn = Load32Aligned(pc);
162
    switch (insn & BYTECODE_MASK) {
163
      BYTECODE(BREAK)
164
        UNREACHABLE();
165
        return false;
166
      BYTECODE(PUSH_CP)
167
        if (--backtrack_stack_space < 0) {
168
          return false;  // No match on backtrack stack overflow.
169
        }
170
        *backtrack_sp++ = current;
171
        pc += BC_PUSH_CP_LENGTH;
172
        break;
173
      BYTECODE(PUSH_BT)
174
        if (--backtrack_stack_space < 0) {
175
          return false;  // No match on backtrack stack overflow.
176
        }
177
        *backtrack_sp++ = Load32Aligned(pc + 4);
178
        pc += BC_PUSH_BT_LENGTH;
179
        break;
180
      BYTECODE(PUSH_REGISTER)
181
        if (--backtrack_stack_space < 0) {
182
          return false;  // No match on backtrack stack overflow.
183
        }
184
        *backtrack_sp++ = registers[insn >> BYTECODE_SHIFT];
185
        pc += BC_PUSH_REGISTER_LENGTH;
186
        break;
187
      BYTECODE(SET_REGISTER)
188
        registers[insn >> BYTECODE_SHIFT] = Load32Aligned(pc + 4);
189
        pc += BC_SET_REGISTER_LENGTH;
190
        break;
191
      BYTECODE(ADVANCE_REGISTER)
192
        registers[insn >> BYTECODE_SHIFT] += Load32Aligned(pc + 4);
193
        pc += BC_ADVANCE_REGISTER_LENGTH;
194
        break;
195
      BYTECODE(SET_REGISTER_TO_CP)
196
        registers[insn >> BYTECODE_SHIFT] = current + Load32Aligned(pc + 4);
197
        pc += BC_SET_REGISTER_TO_CP_LENGTH;
198
        break;
199
      BYTECODE(SET_CP_TO_REGISTER)
200
        current = registers[insn >> BYTECODE_SHIFT];
201
        pc += BC_SET_CP_TO_REGISTER_LENGTH;
202
        break;
203
      BYTECODE(SET_REGISTER_TO_SP)
204
        registers[insn >> BYTECODE_SHIFT] = backtrack_sp - backtrack_stack;
205
        pc += BC_SET_REGISTER_TO_SP_LENGTH;
206
        break;
207
      BYTECODE(SET_SP_TO_REGISTER)
208
        backtrack_sp = backtrack_stack + registers[insn >> BYTECODE_SHIFT];
209
        backtrack_stack_space = kBacktrackStackSize -
210
                                (backtrack_sp - backtrack_stack);
211
        pc += BC_SET_SP_TO_REGISTER_LENGTH;
212
        break;
213
      BYTECODE(POP_CP)
214
        backtrack_stack_space++;
215
        --backtrack_sp;
216
        current = *backtrack_sp;
217
        pc += BC_POP_CP_LENGTH;
218
        break;
219
      BYTECODE(POP_BT)
220
        backtrack_stack_space++;
221
        --backtrack_sp;
222
        pc = code_base + *backtrack_sp;
223
        break;
224
      BYTECODE(POP_REGISTER)
225
        backtrack_stack_space++;
226
        --backtrack_sp;
227
        registers[insn >> BYTECODE_SHIFT] = *backtrack_sp;
228
        pc += BC_POP_REGISTER_LENGTH;
229
        break;
230
      BYTECODE(FAIL)
231
        return false;
232
      BYTECODE(SUCCEED)
233
        return true;
234
      BYTECODE(ADVANCE_CP)
235
        current += insn >> BYTECODE_SHIFT;
236
        pc += BC_ADVANCE_CP_LENGTH;
237
        break;
238
      BYTECODE(GOTO)
239
        pc = code_base + Load32Aligned(pc + 4);
240
        break;
241
      BYTECODE(ADVANCE_CP_AND_GOTO)
242
        current += insn >> BYTECODE_SHIFT;
243
        pc = code_base + Load32Aligned(pc + 4);
244
        break;
245
      BYTECODE(CHECK_GREEDY)
246
        if (current == backtrack_sp[-1]) {
247
          backtrack_sp--;
248
          backtrack_stack_space++;
249
          pc = code_base + Load32Aligned(pc + 4);
250
        } else {
251
          pc += BC_CHECK_GREEDY_LENGTH;
252
        }
253
        break;
254
      BYTECODE(LOAD_CURRENT_CHAR) {
255
        int pos = current + (insn >> BYTECODE_SHIFT);
256
        if (pos >= subject.length()) {
257
          pc = code_base + Load32Aligned(pc + 4);
258
        } else {
259
          current_char = subject[pos];
260
          pc += BC_LOAD_CURRENT_CHAR_LENGTH;
261
        }
262
        break;
263
      }
264
      BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) {
265
        int pos = current + (insn >> BYTECODE_SHIFT);
266
        current_char = subject[pos];
267
        pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH;
268
        break;
269
      }
270
      BYTECODE(LOAD_2_CURRENT_CHARS) {
271
        int pos = current + (insn >> BYTECODE_SHIFT);
272
        if (pos + 2 > subject.length()) {
273
          pc = code_base + Load32Aligned(pc + 4);
274
        } else {
275
          Char next = subject[pos + 1];
276
          current_char =
277
              (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
278
          pc += BC_LOAD_2_CURRENT_CHARS_LENGTH;
279
        }
280
        break;
281
      }
282
      BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) {
283
        int pos = current + (insn >> BYTECODE_SHIFT);
284
        Char next = subject[pos + 1];
285
        current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
286
        pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH;
287
        break;
288
      }
289
      BYTECODE(LOAD_4_CURRENT_CHARS) {
290
        ASSERT(sizeof(Char) == 1);
291
        int pos = current + (insn >> BYTECODE_SHIFT);
292
        if (pos + 4 > subject.length()) {
293
          pc = code_base + Load32Aligned(pc + 4);
294
        } else {
295
          Char next1 = subject[pos + 1];
296
          Char next2 = subject[pos + 2];
297
          Char next3 = subject[pos + 3];
298
          current_char = (subject[pos] |
299
                          (next1 << 8) |
300
                          (next2 << 16) |
301
                          (next3 << 24));
302
          pc += BC_LOAD_4_CURRENT_CHARS_LENGTH;
303
        }
304
        break;
305
      }
306
      BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) {
307
        ASSERT(sizeof(Char) == 1);
308
        int pos = current + (insn >> BYTECODE_SHIFT);
309
        Char next1 = subject[pos + 1];
310
        Char next2 = subject[pos + 2];
311
        Char next3 = subject[pos + 3];
312
        current_char = (subject[pos] |
313
                        (next1 << 8) |
314
                        (next2 << 16) |
315
                        (next3 << 24));
316
        pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH;
317
        break;
318
      }
319
      BYTECODE(CHECK_4_CHARS) {
320
        uint32_t c = Load32Aligned(pc + 4);
321
        if (c == current_char) {
322
          pc = code_base + Load32Aligned(pc + 8);
323
        } else {
324
          pc += BC_CHECK_4_CHARS_LENGTH;
325
        }
326
        break;
327
      }
328
      BYTECODE(CHECK_CHAR) {
329
        uint32_t c = (insn >> BYTECODE_SHIFT);
330
        if (c == current_char) {
331
          pc = code_base + Load32Aligned(pc + 4);
332
        } else {
333
          pc += BC_CHECK_CHAR_LENGTH;
334
        }
335
        break;
336
      }
337
      BYTECODE(CHECK_NOT_4_CHARS) {
338
        uint32_t c = Load32Aligned(pc + 4);
339
        if (c != current_char) {
340
          pc = code_base + Load32Aligned(pc + 8);
341
        } else {
342
          pc += BC_CHECK_NOT_4_CHARS_LENGTH;
343
        }
344
        break;
345
      }
346
      BYTECODE(CHECK_NOT_CHAR) {
347
        uint32_t c = (insn >> BYTECODE_SHIFT);
348
        if (c != current_char) {
349
          pc = code_base + Load32Aligned(pc + 4);
350
        } else {
351
          pc += BC_CHECK_NOT_CHAR_LENGTH;
352
        }
353
        break;
354
      }
355
      BYTECODE(AND_CHECK_4_CHARS) {
356
        uint32_t c = Load32Aligned(pc + 4);
357
        if (c == (current_char & Load32Aligned(pc + 8))) {
358
          pc = code_base + Load32Aligned(pc + 12);
359
        } else {
360
          pc += BC_AND_CHECK_4_CHARS_LENGTH;
361
        }
362
        break;
363
      }
364
      BYTECODE(AND_CHECK_CHAR) {
365
        uint32_t c = (insn >> BYTECODE_SHIFT);
366
        if (c == (current_char & Load32Aligned(pc + 4))) {
367
          pc = code_base + Load32Aligned(pc + 8);
368
        } else {
369
          pc += BC_AND_CHECK_CHAR_LENGTH;
370
        }
371
        break;
372
      }
373
      BYTECODE(AND_CHECK_NOT_4_CHARS) {
374
        uint32_t c = Load32Aligned(pc + 4);
375
        if (c != (current_char & Load32Aligned(pc + 8))) {
376
          pc = code_base + Load32Aligned(pc + 12);
377
        } else {
378
          pc += BC_AND_CHECK_NOT_4_CHARS_LENGTH;
379
        }
380
        break;
381
      }
382
      BYTECODE(AND_CHECK_NOT_CHAR) {
383
        uint32_t c = (insn >> BYTECODE_SHIFT);
384
        if (c != (current_char & Load32Aligned(pc + 4))) {
385
          pc = code_base + Load32Aligned(pc + 8);
386
        } else {
387
          pc += BC_AND_CHECK_NOT_CHAR_LENGTH;
388
        }
389
        break;
390
      }
391
      BYTECODE(MINUS_AND_CHECK_NOT_CHAR) {
392
        uint32_t c = (insn >> BYTECODE_SHIFT);
393
        uint32_t minus = Load16Aligned(pc + 4);
394
        uint32_t mask = Load16Aligned(pc + 6);
395
        if (c != ((current_char - minus) & mask)) {
396
          pc = code_base + Load32Aligned(pc + 8);
397
        } else {
398
          pc += BC_MINUS_AND_CHECK_NOT_CHAR_LENGTH;
399
        }
400
        break;
401
      }
402
      BYTECODE(CHECK_LT) {
403
        uint32_t limit = (insn >> BYTECODE_SHIFT);
404
        if (current_char < limit) {
405
          pc = code_base + Load32Aligned(pc + 4);
406
        } else {
407
          pc += BC_CHECK_LT_LENGTH;
408
        }
409
        break;
410
      }
411
      BYTECODE(CHECK_GT) {
412
        uint32_t limit = (insn >> BYTECODE_SHIFT);
413
        if (current_char > limit) {
414
          pc = code_base + Load32Aligned(pc + 4);
415
        } else {
416
          pc += BC_CHECK_GT_LENGTH;
417
        }
418
        break;
419
      }
420
      BYTECODE(CHECK_REGISTER_LT)
421
        if (registers[insn >> BYTECODE_SHIFT] < Load32Aligned(pc + 4)) {
422
          pc = code_base + Load32Aligned(pc + 8);
423
        } else {
424
          pc += BC_CHECK_REGISTER_LT_LENGTH;
425
        }
426
        break;
427
      BYTECODE(CHECK_REGISTER_GE)
428
        if (registers[insn >> BYTECODE_SHIFT] >= Load32Aligned(pc + 4)) {
429
          pc = code_base + Load32Aligned(pc + 8);
430
        } else {
431
          pc += BC_CHECK_REGISTER_GE_LENGTH;
432
        }
433
        break;
434
      BYTECODE(CHECK_REGISTER_EQ_POS)
435
        if (registers[insn >> BYTECODE_SHIFT] == current) {
436
          pc = code_base + Load32Aligned(pc + 4);
437
        } else {
438
          pc += BC_CHECK_REGISTER_EQ_POS_LENGTH;
439
        }
440
        break;
441
      BYTECODE(LOOKUP_MAP1) {
442
        // Look up character in a bitmap.  If we find a 0, then jump to the
443
        // location at pc + 8.  Otherwise fall through!
444
        int index = current_char - (insn >> BYTECODE_SHIFT);
445
        byte map = code_base[Load32Aligned(pc + 4) + (index >> 3)];
446
        map = ((map >> (index & 7)) & 1);
447
        if (map == 0) {
448
          pc = code_base + Load32Aligned(pc + 8);
449
        } else {
450
          pc += BC_LOOKUP_MAP1_LENGTH;
451
        }
452
        break;
453
      }
454
      BYTECODE(LOOKUP_MAP2) {
455
        // Look up character in a half-nibble map.  If we find 00, then jump to
456
        // the location at pc + 8.   If we find 01 then jump to location at
457
        // pc + 11, etc.
458
        int index = (current_char - (insn >> BYTECODE_SHIFT)) << 1;
459
        byte map = code_base[Load32Aligned(pc + 3) + (index >> 3)];
460
        map = ((map >> (index & 7)) & 3);
461
        if (map < 2) {
462
          if (map == 0) {
463
            pc = code_base + Load32Aligned(pc + 8);
464
          } else {
465
            pc = code_base + Load32Aligned(pc + 12);
466
          }
467
        } else {
468
          if (map == 2) {
469
            pc = code_base + Load32Aligned(pc + 16);
470
          } else {
471
            pc = code_base + Load32Aligned(pc + 20);
472
          }
473
        }
474
        break;
475
      }
476
      BYTECODE(LOOKUP_MAP8) {
477
        // Look up character in a byte map.  Use the byte as an index into a
478
        // table that follows this instruction immediately.
479
        int index = current_char - (insn >> BYTECODE_SHIFT);
480
        byte map = code_base[Load32Aligned(pc + 4) + index];
481
        const byte* new_pc = code_base + Load32Aligned(pc + 8) + (map << 2);
482
        pc = code_base + Load32Aligned(new_pc);
483
        break;
484
      }
485
      BYTECODE(LOOKUP_HI_MAP8) {
486
        // Look up high byte of this character in a byte map.  Use the byte as
487
        // an index into a table that follows this instruction immediately.
488
        int index = (current_char >> 8) - (insn >> BYTECODE_SHIFT);
489
        byte map = code_base[Load32Aligned(pc + 4) + index];
490
        const byte* new_pc = code_base + Load32Aligned(pc + 8) + (map << 2);
491
        pc = code_base + Load32Aligned(new_pc);
492
        break;
493
      }
494
      BYTECODE(CHECK_NOT_REGS_EQUAL)
495
        if (registers[insn >> BYTECODE_SHIFT] ==
496
            registers[Load32Aligned(pc + 4)]) {
497
          pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH;
498
        } else {
499
          pc = code_base + Load32Aligned(pc + 8);
500
        }
501
        break;
502
      BYTECODE(CHECK_NOT_BACK_REF) {
503
        int from = registers[insn >> BYTECODE_SHIFT];
504
        int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
505
        if (from < 0 || len <= 0) {
506
          pc += BC_CHECK_NOT_BACK_REF_LENGTH;
507
          break;
508
        }
509
        if (current + len > subject.length()) {
510
          pc = code_base + Load32Aligned(pc + 4);
511
          break;
512
        } else {
513
          int i;
514
          for (i = 0; i < len; i++) {
515
            if (subject[from + i] != subject[current + i]) {
516
              pc = code_base + Load32Aligned(pc + 4);
517
              break;
518
            }
519
          }
520
          if (i < len) break;
521
          current += len;
522
        }
523
        pc += BC_CHECK_NOT_BACK_REF_LENGTH;
524
        break;
525
      }
526
      BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
527
        int from = registers[insn >> BYTECODE_SHIFT];
528
        int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
529
        if (from < 0 || len <= 0) {
530
          pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
531
          break;
532
        }
533
        if (current + len > subject.length()) {
534
          pc = code_base + Load32Aligned(pc + 4);
535
          break;
536
        } else {
537
          if (BackRefMatchesNoCase(from, current, len, subject)) {
538
            current += len;
539
            pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
540
          } else {
541
            pc = code_base + Load32Aligned(pc + 4);
542
          }
543
        }
544
        break;
545
      }
546
      BYTECODE(CHECK_AT_START)
547
        if (current == 0) {
548
          pc = code_base + Load32Aligned(pc + 4);
549
        } else {
550
          pc += BC_CHECK_AT_START_LENGTH;
551
        }
552
        break;
553
      BYTECODE(CHECK_NOT_AT_START)
554
        if (current == 0) {
555
          pc += BC_CHECK_NOT_AT_START_LENGTH;
556
        } else {
557
          pc = code_base + Load32Aligned(pc + 4);
558
        }
559
        break;
560
      default:
561
        UNREACHABLE();
562
        break;
563
    }
564
  }
565
}
566

    
567

    
568
bool IrregexpInterpreter::Match(Handle<ByteArray> code_array,
569
                                Handle<String> subject,
570
                                int* registers,
571
                                int start_position) {
572
  ASSERT(subject->IsFlat());
573

    
574
  AssertNoAllocation a;
575
  const byte* code_base = code_array->GetDataStartAddress();
576
  uc16 previous_char = '\n';
577
  if (StringShape(*subject).IsAsciiRepresentation()) {
578
    Vector<const char> subject_vector = subject->ToAsciiVector();
579
    if (start_position != 0) previous_char = subject_vector[start_position - 1];
580
    return RawMatch(code_base,
581
                    subject_vector,
582
                    registers,
583
                    start_position,
584
                    previous_char);
585
  } else {
586
    Vector<const uc16> subject_vector = subject->ToUC16Vector();
587
    if (start_position != 0) previous_char = subject_vector[start_position - 1];
588
    return RawMatch(code_base,
589
                    subject_vector,
590
                    registers,
591
                    start_position,
592
                    previous_char);
593
  }
594
}
595

    
596
} }  // namespace v8::internal