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