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
regexp-macro-assembler-irregexp.cc
Go to the documentation of this file.
1 // Copyright 2008-2009 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 #include "v8.h"
29 #include "ast.h"
30 #include "bytecodes-irregexp.h"
31 #include "regexp-macro-assembler.h"
34 
35 
36 namespace v8 {
37 namespace internal {
38 
39 #ifdef V8_INTERPRETED_REGEXP
40 
41 RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer)
42  : buffer_(buffer),
43  pc_(0),
44  own_buffer_(false),
45  advance_current_end_(kInvalidPC) {
46 }
47 
48 
49 RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() {
50  if (backtrack_.is_linked()) backtrack_.Unuse();
51  if (own_buffer_) buffer_.Dispose();
52 }
53 
54 
55 RegExpMacroAssemblerIrregexp::IrregexpImplementation
56 RegExpMacroAssemblerIrregexp::Implementation() {
57  return kBytecodeImplementation;
58 }
59 
60 
61 void RegExpMacroAssemblerIrregexp::Bind(Label* l) {
62  advance_current_end_ = kInvalidPC;
63  ASSERT(!l->is_bound());
64  if (l->is_linked()) {
65  int pos = l->pos();
66  while (pos != 0) {
67  int fixup = pos;
68  pos = *reinterpret_cast<int32_t*>(buffer_.start() + fixup);
69  *reinterpret_cast<uint32_t*>(buffer_.start() + fixup) = pc_;
70  }
71  }
72  l->bind_to(pc_);
73 }
74 
75 
76 void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) {
77  if (l == NULL) l = &backtrack_;
78  if (l->is_bound()) {
79  Emit32(l->pos());
80  } else {
81  int pos = 0;
82  if (l->is_linked()) {
83  pos = l->pos();
84  }
85  l->link_to(pc_);
86  Emit32(pos);
87  }
88 }
89 
90 
91 void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) {
92  ASSERT(register_index >= 0);
93  ASSERT(register_index <= kMaxRegister);
94  Emit(BC_POP_REGISTER, register_index);
95 }
96 
97 
98 void RegExpMacroAssemblerIrregexp::PushRegister(
99  int register_index,
100  StackCheckFlag check_stack_limit) {
101  ASSERT(register_index >= 0);
102  ASSERT(register_index <= kMaxRegister);
103  Emit(BC_PUSH_REGISTER, register_index);
104 }
105 
106 
107 void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister(
108  int register_index, int cp_offset) {
109  ASSERT(register_index >= 0);
110  ASSERT(register_index <= kMaxRegister);
111  Emit(BC_SET_REGISTER_TO_CP, register_index);
112  Emit32(cp_offset); // Current position offset.
113 }
114 
115 
116 void RegExpMacroAssemblerIrregexp::ClearRegisters(int reg_from, int reg_to) {
117  ASSERT(reg_from <= reg_to);
118  for (int reg = reg_from; reg <= reg_to; reg++) {
119  SetRegister(reg, -1);
120  }
121 }
122 
123 
124 void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister(
125  int register_index) {
126  ASSERT(register_index >= 0);
127  ASSERT(register_index <= kMaxRegister);
128  Emit(BC_SET_CP_TO_REGISTER, register_index);
129 }
130 
131 
132 void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister(
133  int register_index) {
134  ASSERT(register_index >= 0);
135  ASSERT(register_index <= kMaxRegister);
136  Emit(BC_SET_REGISTER_TO_SP, register_index);
137 }
138 
139 
140 void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister(
141  int register_index) {
142  ASSERT(register_index >= 0);
143  ASSERT(register_index <= kMaxRegister);
144  Emit(BC_SET_SP_TO_REGISTER, register_index);
145 }
146 
147 
148 void RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
149  ASSERT(is_uint24(by));
150  Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
151 }
152 
153 
154 void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
155  ASSERT(register_index >= 0);
156  ASSERT(register_index <= kMaxRegister);
157  Emit(BC_SET_REGISTER, register_index);
158  Emit32(to);
159 }
160 
161 
162 void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) {
163  ASSERT(register_index >= 0);
164  ASSERT(register_index <= kMaxRegister);
165  Emit(BC_ADVANCE_REGISTER, register_index);
166  Emit32(by);
167 }
168 
169 
170 void RegExpMacroAssemblerIrregexp::PopCurrentPosition() {
171  Emit(BC_POP_CP, 0);
172 }
173 
174 
175 void RegExpMacroAssemblerIrregexp::PushCurrentPosition() {
176  Emit(BC_PUSH_CP, 0);
177 }
178 
179 
180 void RegExpMacroAssemblerIrregexp::Backtrack() {
181  Emit(BC_POP_BT, 0);
182 }
183 
184 
185 void RegExpMacroAssemblerIrregexp::GoTo(Label* l) {
186  if (advance_current_end_ == pc_) {
187  // Combine advance current and goto.
188  pc_ = advance_current_start_;
189  Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
190  EmitOrLink(l);
191  advance_current_end_ = kInvalidPC;
192  } else {
193  // Regular goto.
194  Emit(BC_GOTO, 0);
195  EmitOrLink(l);
196  }
197 }
198 
199 
200 void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) {
201  Emit(BC_PUSH_BT, 0);
202  EmitOrLink(l);
203 }
204 
205 
206 bool RegExpMacroAssemblerIrregexp::Succeed() {
207  Emit(BC_SUCCEED, 0);
208  return false; // Restart matching for global regexp not supported.
209 }
210 
211 
213  Emit(BC_FAIL, 0);
214 }
215 
216 
217 void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) {
218  ASSERT(by >= kMinCPOffset);
219  ASSERT(by <= kMaxCPOffset);
220  advance_current_start_ = pc_;
221  advance_current_offset_ = by;
222  Emit(BC_ADVANCE_CP, by);
223  advance_current_end_ = pc_;
224 }
225 
226 
227 void RegExpMacroAssemblerIrregexp::CheckGreedyLoop(
228  Label* on_tos_equals_current_position) {
229  Emit(BC_CHECK_GREEDY, 0);
230  EmitOrLink(on_tos_equals_current_position);
231 }
232 
233 
234 void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset,
235  Label* on_failure,
236  bool check_bounds,
237  int characters) {
238  ASSERT(cp_offset >= kMinCPOffset);
239  ASSERT(cp_offset <= kMaxCPOffset);
240  int bytecode;
241  if (check_bounds) {
242  if (characters == 4) {
243  bytecode = BC_LOAD_4_CURRENT_CHARS;
244  } else if (characters == 2) {
245  bytecode = BC_LOAD_2_CURRENT_CHARS;
246  } else {
247  ASSERT(characters == 1);
248  bytecode = BC_LOAD_CURRENT_CHAR;
249  }
250  } else {
251  if (characters == 4) {
252  bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
253  } else if (characters == 2) {
254  bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
255  } else {
256  ASSERT(characters == 1);
257  bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
258  }
259  }
260  Emit(bytecode, cp_offset);
261  if (check_bounds) EmitOrLink(on_failure);
262 }
263 
264 
265 void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit,
266  Label* on_less) {
267  Emit(BC_CHECK_LT, limit);
268  EmitOrLink(on_less);
269 }
270 
271 
272 void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit,
273  Label* on_greater) {
274  Emit(BC_CHECK_GT, limit);
275  EmitOrLink(on_greater);
276 }
277 
278 
279 void RegExpMacroAssemblerIrregexp::CheckCharacter(uint32_t c, Label* on_equal) {
280  if (c > MAX_FIRST_ARG) {
281  Emit(BC_CHECK_4_CHARS, 0);
282  Emit32(c);
283  } else {
284  Emit(BC_CHECK_CHAR, c);
285  }
286  EmitOrLink(on_equal);
287 }
288 
289 
290 void RegExpMacroAssemblerIrregexp::CheckAtStart(Label* on_at_start) {
291  Emit(BC_CHECK_AT_START, 0);
292  EmitOrLink(on_at_start);
293 }
294 
295 
296 void RegExpMacroAssemblerIrregexp::CheckNotAtStart(Label* on_not_at_start) {
297  Emit(BC_CHECK_NOT_AT_START, 0);
298  EmitOrLink(on_not_at_start);
299 }
300 
301 
302 void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uint32_t c,
303  Label* on_not_equal) {
304  if (c > MAX_FIRST_ARG) {
305  Emit(BC_CHECK_NOT_4_CHARS, 0);
306  Emit32(c);
307  } else {
308  Emit(BC_CHECK_NOT_CHAR, c);
309  }
310  EmitOrLink(on_not_equal);
311 }
312 
313 
314 void RegExpMacroAssemblerIrregexp::CheckCharacterAfterAnd(
315  uint32_t c,
316  uint32_t mask,
317  Label* on_equal) {
318  if (c > MAX_FIRST_ARG) {
319  Emit(BC_AND_CHECK_4_CHARS, 0);
320  Emit32(c);
321  } else {
322  Emit(BC_AND_CHECK_CHAR, c);
323  }
324  Emit32(mask);
325  EmitOrLink(on_equal);
326 }
327 
328 
329 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterAnd(
330  uint32_t c,
331  uint32_t mask,
332  Label* on_not_equal) {
333  if (c > MAX_FIRST_ARG) {
334  Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
335  Emit32(c);
336  } else {
337  Emit(BC_AND_CHECK_NOT_CHAR, c);
338  }
339  Emit32(mask);
340  EmitOrLink(on_not_equal);
341 }
342 
343 
344 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd(
345  uc16 c,
346  uc16 minus,
347  uc16 mask,
348  Label* on_not_equal) {
349  Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
350  Emit16(minus);
351  Emit16(mask);
352  EmitOrLink(on_not_equal);
353 }
354 
355 
356 void RegExpMacroAssemblerIrregexp::CheckCharacterInRange(
357  uc16 from,
358  uc16 to,
359  Label* on_in_range) {
360  Emit(BC_CHECK_CHAR_IN_RANGE, 0);
361  Emit16(from);
362  Emit16(to);
363  EmitOrLink(on_in_range);
364 }
365 
366 
367 void RegExpMacroAssemblerIrregexp::CheckCharacterNotInRange(
368  uc16 from,
369  uc16 to,
370  Label* on_not_in_range) {
371  Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
372  Emit16(from);
373  Emit16(to);
374  EmitOrLink(on_not_in_range);
375 }
376 
377 
378 void RegExpMacroAssemblerIrregexp::CheckBitInTable(
379  Handle<ByteArray> table, Label* on_bit_set) {
380  Emit(BC_CHECK_BIT_IN_TABLE, 0);
381  EmitOrLink(on_bit_set);
382  for (int i = 0; i < kTableSize; i += kBitsPerByte) {
383  int byte = 0;
384  for (int j = 0; j < kBitsPerByte; j++) {
385  if (table->get(i + j) != 0) byte |= 1 << j;
386  }
387  Emit8(byte);
388  }
389 }
390 
391 
392 void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg,
393  Label* on_not_equal) {
394  ASSERT(start_reg >= 0);
395  ASSERT(start_reg <= kMaxRegister);
396  Emit(BC_CHECK_NOT_BACK_REF, start_reg);
397  EmitOrLink(on_not_equal);
398 }
399 
400 
401 void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
402  int start_reg,
403  Label* on_not_equal) {
404  ASSERT(start_reg >= 0);
405  ASSERT(start_reg <= kMaxRegister);
406  Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
407  EmitOrLink(on_not_equal);
408 }
409 
410 
411 void RegExpMacroAssemblerIrregexp::CheckCharacters(
412  Vector<const uc16> str,
413  int cp_offset,
414  Label* on_failure,
415  bool check_end_of_string) {
416  ASSERT(cp_offset >= kMinCPOffset);
417  ASSERT(cp_offset + str.length() - 1 <= kMaxCPOffset);
418  // It is vital that this loop is backwards due to the unchecked character
419  // load below.
420  for (int i = str.length() - 1; i >= 0; i--) {
421  if (check_end_of_string && i == str.length() - 1) {
422  Emit(BC_LOAD_CURRENT_CHAR, cp_offset + i);
423  EmitOrLink(on_failure);
424  } else {
425  Emit(BC_LOAD_CURRENT_CHAR_UNCHECKED, cp_offset + i);
426  }
427  Emit(BC_CHECK_NOT_CHAR, str[i]);
428  EmitOrLink(on_failure);
429  }
430 }
431 
432 
433 void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
434  int comparand,
435  Label* on_less_than) {
436  ASSERT(register_index >= 0);
437  ASSERT(register_index <= kMaxRegister);
438  Emit(BC_CHECK_REGISTER_LT, register_index);
439  Emit32(comparand);
440  EmitOrLink(on_less_than);
441 }
442 
443 
444 void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index,
445  int comparand,
446  Label* on_greater_or_equal) {
447  ASSERT(register_index >= 0);
448  ASSERT(register_index <= kMaxRegister);
449  Emit(BC_CHECK_REGISTER_GE, register_index);
450  Emit32(comparand);
451  EmitOrLink(on_greater_or_equal);
452 }
453 
454 
455 void RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
456  Label* on_eq) {
457  ASSERT(register_index >= 0);
458  ASSERT(register_index <= kMaxRegister);
459  Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
460  EmitOrLink(on_eq);
461 }
462 
463 
464 Handle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
465  Handle<String> source) {
466  Bind(&backtrack_);
467  Emit(BC_POP_BT, 0);
468  Handle<ByteArray> array = FACTORY->NewByteArray(length());
469  Copy(array->GetDataStartAddress());
470  return array;
471 }
472 
473 
474 int RegExpMacroAssemblerIrregexp::length() {
475  return pc_;
476 }
477 
478 
480  memcpy(a, buffer_.start(), length());
481 }
482 
483 
484 void RegExpMacroAssemblerIrregexp::Expand() {
485  bool old_buffer_was_our_own = own_buffer_;
486  Vector<byte> old_buffer = buffer_;
487  buffer_ = Vector<byte>::New(old_buffer.length() * 2);
488  own_buffer_ = true;
489  memcpy(buffer_.start(), old_buffer.start(), old_buffer.length());
490  if (old_buffer_was_our_own) {
491  old_buffer.Dispose();
492  }
493 }
494 
495 #endif // V8_INTERPRETED_REGEXP
496 
497 } } // namespace v8::internal
byte * Address
Definition: globals.h:172
v8::Handle< v8::Value > Fail(const v8::Arguments &args)
int int32_t
Definition: unicode.cc:47
bool is_uint24(int x)
Definition: assembler.h:848
#define ASSERT(condition)
Definition: checks.h:270
StringInputBuffer *const buffer_
uint8_t byte
Definition: globals.h:171
const int kBitsPerByte
Definition: globals.h:251
static Vector< T > New(int length)
Definition: utils.h:369
uint16_t uc16
Definition: globals.h:273
const unsigned int MAX_FIRST_ARG
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
#define FACTORY
Definition: isolate.h:1409
Handle< JSObject > Copy(Handle< JSObject > obj)
Definition: handles.cc:335