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