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 
11 namespace v8 {
12 namespace internal {
13 
RegExpMacroAssemblerTracer(RegExpMacroAssembler * assembler)14 RegExpMacroAssemblerTracer::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 
~RegExpMacroAssemblerTracer()26 RegExpMacroAssemblerTracer::~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.
LabelToInt(Label * label)32 static int LabelToInt(Label* label) {
33   return static_cast<int>(reinterpret_cast<intptr_t>(label));
34 }
35 
36 
Bind(Label * label)37 void RegExpMacroAssemblerTracer::Bind(Label* label) {
38   PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
39   assembler_->Bind(label);
40 }
41 
42 
AdvanceCurrentPosition(int by)43 void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
44   PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
45   assembler_->AdvanceCurrentPosition(by);
46 }
47 
48 
CheckGreedyLoop(Label * label)49 void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
50   PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
51   assembler_->CheckGreedyLoop(label);
52 }
53 
54 
PopCurrentPosition()55 void RegExpMacroAssemblerTracer::PopCurrentPosition() {
56   PrintF(" PopCurrentPosition();\n");
57   assembler_->PopCurrentPosition();
58 }
59 
60 
PushCurrentPosition()61 void RegExpMacroAssemblerTracer::PushCurrentPosition() {
62   PrintF(" PushCurrentPosition();\n");
63   assembler_->PushCurrentPosition();
64 }
65 
66 
Backtrack()67 void RegExpMacroAssemblerTracer::Backtrack() {
68   PrintF(" Backtrack();\n");
69   assembler_->Backtrack();
70 }
71 
72 
GoTo(Label * label)73 void RegExpMacroAssemblerTracer::GoTo(Label* label) {
74   PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
75   assembler_->GoTo(label);
76 }
77 
78 
PushBacktrack(Label * label)79 void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
80   PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
81   assembler_->PushBacktrack(label);
82 }
83 
84 
Succeed()85 bool RegExpMacroAssemblerTracer::Succeed() {
86   bool restart = assembler_->Succeed();
87   PrintF(" Succeed();%s\n", restart ? " [restart for global match]" : "");
88   return restart;
89 }
90 
91 
Fail()92 void RegExpMacroAssemblerTracer::Fail() {
93   PrintF(" Fail();");
94   assembler_->Fail();
95 }
96 
97 
PopRegister(int register_index)98 void RegExpMacroAssemblerTracer::PopRegister(int register_index) {
99   PrintF(" PopRegister(register=%d);\n", register_index);
100   assembler_->PopRegister(register_index);
101 }
102 
103 
PushRegister(int register_index,StackCheckFlag check_stack_limit)104 void 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 
AdvanceRegister(int reg,int by)114 void RegExpMacroAssemblerTracer::AdvanceRegister(int reg, int by) {
115   PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
116   assembler_->AdvanceRegister(reg, by);
117 }
118 
119 
SetCurrentPositionFromEnd(int by)120 void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
121   PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
122   assembler_->SetCurrentPositionFromEnd(by);
123 }
124 
125 
SetRegister(int register_index,int to)126 void 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 
WriteCurrentPositionToRegister(int reg,int cp_offset)132 void 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 
ClearRegisters(int reg_from,int reg_to)141 void 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 
ReadCurrentPositionFromRegister(int reg)147 void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) {
148   PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
149   assembler_->ReadCurrentPositionFromRegister(reg);
150 }
151 
152 
WriteStackPointerToRegister(int reg)153 void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) {
154   PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
155   assembler_->WriteStackPointerToRegister(reg);
156 }
157 
158 
ReadStackPointerFromRegister(int reg)159 void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
160   PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
161   assembler_->ReadStackPointerFromRegister(reg);
162 }
163 
164 
LoadCurrentCharacter(int cp_offset,Label * on_end_of_input,bool check_bounds,int characters)165 void 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 
182 class PrintablePrinter {
183  public:
PrintablePrinter(uc16 character)184   explicit PrintablePrinter(uc16 character) : character_(character) { }
185 
operator *()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 
CheckCharacterLT(uc16 limit,Label * on_less)204 void 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 
CheckCharacterGT(uc16 limit,Label * on_greater)214 void 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 
CheckCharacter(unsigned c,Label * on_equal)225 void 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 
CheckAtStart(Label * on_at_start)235 void 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 
CheckNotAtStart(Label * on_not_at_start)241 void 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 
CheckNotCharacter(unsigned c,Label * on_not_equal)247 void 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 
CheckCharacterAfterAnd(unsigned c,unsigned mask,Label * on_equal)258 void 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 
CheckNotCharacterAfterAnd(unsigned c,unsigned mask,Label * on_not_equal)272 void 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 
CheckNotCharacterAfterMinusAnd(uc16 c,uc16 minus,uc16 mask,Label * on_not_equal)286 void 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 
CheckCharacterInRange(uc16 from,uc16 to,Label * on_not_in_range)301 void 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 
CheckCharacterNotInRange(uc16 from,uc16 to,Label * on_in_range)317 void 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 
CheckBitInTable(Handle<ByteArray> table,Label * on_bit_set)334 void 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 
CheckNotBackReference(int start_reg,Label * on_no_match)348 void 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 
CheckNotBackReferenceIgnoreCase(int start_reg,Label * on_no_match)356 void 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 
CheckSpecialCharacterClass(uc16 type,Label * on_no_match)365 bool 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 
IfRegisterLT(int register_index,int comparand,Label * if_lt)378 void 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 
IfRegisterEqPos(int register_index,Label * if_eq)386 void 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 
IfRegisterGE(int register_index,int comparand,Label * if_ge)394 void 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 
402 RegExpMacroAssembler::IrregexpImplementation
Implementation()403     RegExpMacroAssemblerTracer::Implementation() {
404   return assembler_->Implementation();
405 }
406 
407 
GetCode(Handle<String> source)408 Handle<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