1// Copyright 2012 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#include "src/v8.h"
6
7#include "src/ast.h"
8#include "src/regexp-macro-assembler.h"
9#include "src/regexp-macro-assembler-tracer.h"
10
11namespace v8 {
12namespace internal {
13
14RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer(
15    RegExpMacroAssembler* assembler) :
16  RegExpMacroAssembler(assembler->zone()),
17  assembler_(assembler) {
18  unsigned int type = assembler->Implementation();
19  DCHECK(type < 6);
20  const char* impl_names[] = {"IA32", "ARM", "ARM64",
21                              "MIPS", "X64", "X87", "Bytecode"};
22  PrintF("RegExpMacroAssembler%s();\n", impl_names[type]);
23}
24
25
26RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() {
27}
28
29
30// This is used for printing out debugging information.  It makes an integer
31// that is closely related to the address of an object.
32static int LabelToInt(Label* label) {
33  return static_cast<int>(reinterpret_cast<intptr_t>(label));
34}
35
36
37void RegExpMacroAssemblerTracer::Bind(Label* label) {
38  PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
39  assembler_->Bind(label);
40}
41
42
43void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
44  PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
45  assembler_->AdvanceCurrentPosition(by);
46}
47
48
49void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
50  PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
51  assembler_->CheckGreedyLoop(label);
52}
53
54
55void RegExpMacroAssemblerTracer::PopCurrentPosition() {
56  PrintF(" PopCurrentPosition();\n");
57  assembler_->PopCurrentPosition();
58}
59
60
61void RegExpMacroAssemblerTracer::PushCurrentPosition() {
62  PrintF(" PushCurrentPosition();\n");
63  assembler_->PushCurrentPosition();
64}
65
66
67void RegExpMacroAssemblerTracer::Backtrack() {
68  PrintF(" Backtrack();\n");
69  assembler_->Backtrack();
70}
71
72
73void RegExpMacroAssemblerTracer::GoTo(Label* label) {
74  PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
75  assembler_->GoTo(label);
76}
77
78
79void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
80  PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
81  assembler_->PushBacktrack(label);
82}
83
84
85bool RegExpMacroAssemblerTracer::Succeed() {
86  bool restart = assembler_->Succeed();
87  PrintF(" Succeed();%s\n", restart ? " [restart for global match]" : "");
88  return restart;
89}
90
91
92void RegExpMacroAssemblerTracer::Fail() {
93  PrintF(" Fail();");
94  assembler_->Fail();
95}
96
97
98void RegExpMacroAssemblerTracer::PopRegister(int register_index) {
99  PrintF(" PopRegister(register=%d);\n", register_index);
100  assembler_->PopRegister(register_index);
101}
102
103
104void RegExpMacroAssemblerTracer::PushRegister(
105    int register_index,
106    StackCheckFlag check_stack_limit) {
107  PrintF(" PushRegister(register=%d, %s);\n",
108         register_index,
109         check_stack_limit ? "check stack limit" : "");
110  assembler_->PushRegister(register_index, check_stack_limit);
111}
112
113
114void RegExpMacroAssemblerTracer::AdvanceRegister(int reg, int by) {
115  PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
116  assembler_->AdvanceRegister(reg, by);
117}
118
119
120void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
121  PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
122  assembler_->SetCurrentPositionFromEnd(by);
123}
124
125
126void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
127  PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
128  assembler_->SetRegister(register_index, to);
129}
130
131
132void RegExpMacroAssemblerTracer::WriteCurrentPositionToRegister(int reg,
133                                                                int cp_offset) {
134  PrintF(" WriteCurrentPositionToRegister(register=%d,cp_offset=%d);\n",
135         reg,
136         cp_offset);
137  assembler_->WriteCurrentPositionToRegister(reg, cp_offset);
138}
139
140
141void RegExpMacroAssemblerTracer::ClearRegisters(int reg_from, int reg_to) {
142  PrintF(" ClearRegister(from=%d, to=%d);\n", reg_from, reg_to);
143  assembler_->ClearRegisters(reg_from, reg_to);
144}
145
146
147void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) {
148  PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
149  assembler_->ReadCurrentPositionFromRegister(reg);
150}
151
152
153void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) {
154  PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
155  assembler_->WriteStackPointerToRegister(reg);
156}
157
158
159void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
160  PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
161  assembler_->ReadStackPointerFromRegister(reg);
162}
163
164
165void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset,
166                                                      Label* on_end_of_input,
167                                                      bool check_bounds,
168                                                      int characters) {
169  const char* check_msg = check_bounds ? "" : " (unchecked)";
170  PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
171         cp_offset,
172         LabelToInt(on_end_of_input),
173         check_msg,
174         characters);
175  assembler_->LoadCurrentCharacter(cp_offset,
176                                   on_end_of_input,
177                                   check_bounds,
178                                   characters);
179}
180
181
182class PrintablePrinter {
183 public:
184  explicit PrintablePrinter(uc16 character) : character_(character) { }
185
186  const char* operator*() {
187    if (character_ >= ' ' && character_ <= '~') {
188      buffer_[0] = '(';
189      buffer_[1] = static_cast<char>(character_);
190      buffer_[2] = ')';
191      buffer_[3] = '\0';
192    } else {
193      buffer_[0] = '\0';
194    }
195    return &buffer_[0];
196  }
197
198 private:
199  uc16 character_;
200  char buffer_[4];
201};
202
203
204void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) {
205  PrintablePrinter printable(limit);
206  PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
207         limit,
208         *printable,
209         LabelToInt(on_less));
210  assembler_->CheckCharacterLT(limit, on_less);
211}
212
213
214void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
215                                                  Label* on_greater) {
216  PrintablePrinter printable(limit);
217  PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
218         limit,
219         *printable,
220         LabelToInt(on_greater));
221  assembler_->CheckCharacterGT(limit, on_greater);
222}
223
224
225void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
226  PrintablePrinter printable(c);
227  PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
228         c,
229         *printable,
230         LabelToInt(on_equal));
231  assembler_->CheckCharacter(c, on_equal);
232}
233
234
235void RegExpMacroAssemblerTracer::CheckAtStart(Label* on_at_start) {
236  PrintF(" CheckAtStart(label[%08x]);\n", LabelToInt(on_at_start));
237  assembler_->CheckAtStart(on_at_start);
238}
239
240
241void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
242  PrintF(" CheckNotAtStart(label[%08x]);\n", LabelToInt(on_not_at_start));
243  assembler_->CheckNotAtStart(on_not_at_start);
244}
245
246
247void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c,
248                                                   Label* on_not_equal) {
249  PrintablePrinter printable(c);
250  PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
251         c,
252         *printable,
253         LabelToInt(on_not_equal));
254  assembler_->CheckNotCharacter(c, on_not_equal);
255}
256
257
258void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd(
259    unsigned c,
260    unsigned mask,
261    Label* on_equal) {
262  PrintablePrinter printable(c);
263  PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
264         c,
265         *printable,
266         mask,
267         LabelToInt(on_equal));
268  assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
269}
270
271
272void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
273    unsigned c,
274    unsigned mask,
275    Label* on_not_equal) {
276  PrintablePrinter printable(c);
277  PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
278         c,
279         *printable,
280         mask,
281         LabelToInt(on_not_equal));
282  assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
283}
284
285
286void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd(
287    uc16 c,
288    uc16 minus,
289    uc16 mask,
290    Label* on_not_equal) {
291  PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
292             "label[%08x]);\n",
293         c,
294         minus,
295         mask,
296         LabelToInt(on_not_equal));
297  assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
298}
299
300
301void RegExpMacroAssemblerTracer::CheckCharacterInRange(
302    uc16 from,
303    uc16 to,
304    Label* on_not_in_range) {
305  PrintablePrinter printable_from(from);
306  PrintablePrinter printable_to(to);
307  PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n",
308         from,
309         *printable_from,
310         to,
311         *printable_to,
312         LabelToInt(on_not_in_range));
313  assembler_->CheckCharacterInRange(from, to, on_not_in_range);
314}
315
316
317void RegExpMacroAssemblerTracer::CheckCharacterNotInRange(
318    uc16 from,
319    uc16 to,
320    Label* on_in_range) {
321  PrintablePrinter printable_from(from);
322  PrintablePrinter printable_to(to);
323  PrintF(
324      " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n",
325      from,
326      *printable_from,
327      to,
328      *printable_to,
329      LabelToInt(on_in_range));
330  assembler_->CheckCharacterNotInRange(from, to, on_in_range);
331}
332
333
334void RegExpMacroAssemblerTracer::CheckBitInTable(
335    Handle<ByteArray> table, Label* on_bit_set) {
336  PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set));
337  for (int i = 0; i < kTableSize; i++) {
338    PrintF("%c", table->get(i) != 0 ? 'X' : '.');
339    if (i % 32 == 31 && i != kTableMask) {
340      PrintF("\n                                 ");
341    }
342  }
343  PrintF(");\n");
344  assembler_->CheckBitInTable(table, on_bit_set);
345}
346
347
348void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg,
349                                                       Label* on_no_match) {
350  PrintF(" CheckNotBackReference(register=%d, label[%08x]);\n", start_reg,
351         LabelToInt(on_no_match));
352  assembler_->CheckNotBackReference(start_reg, on_no_match);
353}
354
355
356void RegExpMacroAssemblerTracer::CheckNotBackReferenceIgnoreCase(
357    int start_reg,
358    Label* on_no_match) {
359  PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, label[%08x]);\n",
360         start_reg, LabelToInt(on_no_match));
361  assembler_->CheckNotBackReferenceIgnoreCase(start_reg, on_no_match);
362}
363
364
365bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
366    uc16 type,
367    Label* on_no_match) {
368  bool supported = assembler_->CheckSpecialCharacterClass(type,
369                                                          on_no_match);
370  PrintF(" CheckSpecialCharacterClass(type='%c', label[%08x]): %s;\n",
371         type,
372         LabelToInt(on_no_match),
373         supported ? "true" : "false");
374  return supported;
375}
376
377
378void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
379                                              int comparand, Label* if_lt) {
380  PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
381         register_index, comparand, LabelToInt(if_lt));
382  assembler_->IfRegisterLT(register_index, comparand, if_lt);
383}
384
385
386void RegExpMacroAssemblerTracer::IfRegisterEqPos(int register_index,
387                                                 Label* if_eq) {
388  PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
389         register_index, LabelToInt(if_eq));
390  assembler_->IfRegisterEqPos(register_index, if_eq);
391}
392
393
394void RegExpMacroAssemblerTracer::IfRegisterGE(int register_index,
395                                              int comparand, Label* if_ge) {
396  PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
397         register_index, comparand, LabelToInt(if_ge));
398  assembler_->IfRegisterGE(register_index, comparand, if_ge);
399}
400
401
402RegExpMacroAssembler::IrregexpImplementation
403    RegExpMacroAssemblerTracer::Implementation() {
404  return assembler_->Implementation();
405}
406
407
408Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
409  PrintF(" GetCode(%s);\n", source->ToCString().get());
410  return assembler_->GetCode(source);
411}
412
413}}  // namespace v8::internal
414