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