| OLD | NEW | 
|    1 // Copyright 2016 the V8 project authors. All rights reserved. |    1 // Copyright 2016 the V8 project authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "test/unittests/test-utils.h" |    5 #include "test/unittests/test-utils.h" | 
|    6 #include "testing/gmock/include/gmock/gmock.h" |    6 #include "testing/gmock/include/gmock/gmock.h" | 
|    7  |    7  | 
|    8 #include "src/v8.h" |    8 #include "src/v8.h" | 
|    9  |    9  | 
|   10 #include "src/wasm/wasm-interpreter.h" |   10 #include "src/wasm/wasm-interpreter.h" | 
|   11 #include "src/wasm/wasm-macro-gen.h" |   11 #include "src/wasm/wasm-macro-gen.h" | 
|   12  |   12  | 
|   13 using testing::MakeMatcher; |   13 using testing::MakeMatcher; | 
|   14 using testing::Matcher; |   14 using testing::Matcher; | 
|   15 using testing::MatcherInterface; |   15 using testing::MatcherInterface; | 
|   16 using testing::MatchResultListener; |   16 using testing::MatchResultListener; | 
|   17 using testing::StringMatchResultListener; |   17 using testing::StringMatchResultListener; | 
|   18  |   18  | 
|   19 namespace v8 { |   19 namespace v8 { | 
|   20 namespace internal { |   20 namespace internal { | 
|   21 namespace wasm { |   21 namespace wasm { | 
|   22  |   22  | 
|   23 #define B1(a) kExprBlock, a, kExprEnd |   23 #define B1(a) kExprBlock, a, kExprEnd | 
|   24 #define B2(a, b) kExprBlock, a, b, kExprEnd |   24 #define B2(a, b) kExprBlock, a, b, kExprEnd | 
|   25 #define B3(a, b, c) kExprBlock, a, b, c, kExprEnd |   25 #define B3(a, b, c) kExprBlock, a, b, c, kExprEnd | 
|   26  |   26  | 
|   27 struct ExpectedTarget { |   27 #define TRANSFER_VOID 0 | 
 |   28 #define TRANSFER_ONE 1 | 
 |   29  | 
 |   30 struct ExpectedPcDelta { | 
|   28   pc_t pc; |   31   pc_t pc; | 
|   29   ControlTransfer expected; |   32   pcdiff_t expected; | 
|   30 }; |   33 }; | 
|   31  |   34  | 
|   32 // For nicer error messages. |   35 // For nicer error messages. | 
|   33 class ControlTransferMatcher : public MatcherInterface<const ControlTransfer&> { |   36 class ControlTransferMatcher : public MatcherInterface<const pcdiff_t&> { | 
|   34  public: |   37  public: | 
|   35   explicit ControlTransferMatcher(pc_t pc, const ControlTransfer& expected) |   38   explicit ControlTransferMatcher(pc_t pc, const pcdiff_t& expected) | 
|   36       : pc_(pc), expected_(expected) {} |   39       : pc_(pc), expected_(expected) {} | 
|   37  |   40  | 
|   38   void DescribeTo(std::ostream* os) const override { |   41   void DescribeTo(std::ostream* os) const override { | 
|   39     *os << "@" << pc_ << " {pcdiff = " << expected_.pcdiff |   42     *os << "@" << pc_ << " pcdiff = " << expected_; | 
|   40         << ", spdiff = " << expected_.spdiff |  | 
|   41         << ", action = " << expected_.action << "}"; |  | 
|   42   } |   43   } | 
|   43  |   44  | 
|   44   bool MatchAndExplain(const ControlTransfer& input, |   45   bool MatchAndExplain(const pcdiff_t& input, | 
|   45                        MatchResultListener* listener) const override { |   46                        MatchResultListener* listener) const override { | 
|   46     if (input.pcdiff != expected_.pcdiff || input.spdiff != expected_.spdiff || |   47     if (input != expected_) { | 
|   47         input.action != expected_.action) { |   48       *listener << "@" << pc_ << " pcdiff = " << input; | 
|   48       *listener << "@" << pc_ << " {pcdiff = " << input.pcdiff |  | 
|   49                 << ", spdiff = " << input.spdiff |  | 
|   50                 << ", action = " << input.action << "}"; |  | 
|   51       return false; |   49       return false; | 
|   52     } |   50     } | 
|   53     return true; |   51     return true; | 
|   54   } |   52   } | 
|   55  |   53  | 
|   56  private: |   54  private: | 
|   57   pc_t pc_; |   55   pc_t pc_; | 
|   58   const ControlTransfer& expected_; |   56   const pcdiff_t& expected_; | 
|   59 }; |   57 }; | 
|   60  |   58  | 
|   61 class ControlTransferTest : public TestWithZone { |   59 class ControlTransferTest : public TestWithZone { | 
|   62  public: |   60  public: | 
|   63   void CheckControlTransfers(const byte* start, const byte* end, |   61   void CheckPcDeltas(const byte* start, const byte* end, | 
|   64                              ExpectedTarget* expected_targets, |   62                      ExpectedPcDelta* expected_deltas, size_t num_targets) { | 
|   65                              size_t num_targets) { |  | 
|   66     ControlTransferMap map = |   63     ControlTransferMap map = | 
|   67         WasmInterpreter::ComputeControlTransfersForTesting(zone(), start, end); |   64         WasmInterpreter::ComputeControlTransfersForTesting(zone(), start, end); | 
|   68     // Check all control targets in the map. |   65     // Check all control targets in the map. | 
|   69     for (size_t i = 0; i < num_targets; i++) { |   66     for (size_t i = 0; i < num_targets; i++) { | 
|   70       pc_t pc = expected_targets[i].pc; |   67       pc_t pc = expected_deltas[i].pc; | 
|   71       auto it = map.find(pc); |   68       auto it = map.find(pc); | 
|   72       if (it == map.end()) { |   69       if (it == map.end()) { | 
|   73         printf("expected control target @ +%zu\n", pc); |   70         EXPECT_TRUE(false) << "expected control target @ " << pc; | 
|   74         EXPECT_TRUE(false); |  | 
|   75       } else { |   71       } else { | 
|   76         ControlTransfer& expected = expected_targets[i].expected; |   72         pcdiff_t expected = expected_deltas[i].expected; | 
|   77         ControlTransfer& target = it->second; |   73         pcdiff_t& target = it->second; | 
|   78         EXPECT_THAT(target, |   74         EXPECT_THAT(target, | 
|   79                     MakeMatcher(new ControlTransferMatcher(pc, expected))); |   75                     MakeMatcher(new ControlTransferMatcher(pc, expected))); | 
|   80       } |   76       } | 
|   81     } |   77     } | 
|   82  |   78  | 
|   83     // Check there are no other control targets. |   79     // Check there are no other control targets. | 
 |   80     CheckNoOtherTargets<ExpectedPcDelta>(start, end, map, expected_deltas, | 
 |   81                                          num_targets); | 
 |   82   } | 
 |   83  | 
 |   84   template <typename T> | 
 |   85   void CheckNoOtherTargets(const byte* start, const byte* end, | 
 |   86                            ControlTransferMap& map, T* targets, | 
 |   87                            size_t num_targets) { | 
 |   88     // Check there are no other control targets. | 
|   84     for (pc_t pc = 0; start + pc < end; pc++) { |   89     for (pc_t pc = 0; start + pc < end; pc++) { | 
|   85       bool found = false; |   90       bool found = false; | 
|   86       for (size_t i = 0; i < num_targets; i++) { |   91       for (size_t i = 0; i < num_targets; i++) { | 
|   87         if (expected_targets[i].pc == pc) { |   92         if (targets[i].pc == pc) { | 
|   88           found = true; |   93           found = true; | 
|   89           break; |   94           break; | 
|   90         } |   95         } | 
|   91       } |   96       } | 
|   92       if (found) continue; |   97       if (found) continue; | 
|   93       if (map.find(pc) != map.end()) { |   98       if (map.find(pc) != map.end()) { | 
|   94         printf("expected no control @ +%zu\n", pc); |   99         printf("expected no control @ +%zu\n", pc); | 
|   95         EXPECT_TRUE(false); |  100         EXPECT_TRUE(false); | 
|   96       } |  101       } | 
|   97     } |  102     } | 
|   98   } |  103   } | 
|   99 }; |  104 }; | 
|  100  |  105  | 
|  101 // Macro for simplifying tests below. |  106 #define EXPECT_PC_DELTAS(...)                                          \ | 
|  102 #define EXPECT_TARGETS(...)                                                    \ |  107   do {                                                                 \ | 
|  103   do {                                                                         \ |  108     ExpectedPcDelta pairs[] = {__VA_ARGS__};                           \ | 
|  104     ExpectedTarget pairs[] = {__VA_ARGS__};                                    \ |  109     CheckPcDeltas(code, code + sizeof(code), pairs, arraysize(pairs)); \ | 
|  105     CheckControlTransfers(code, code + sizeof(code), pairs, arraysize(pairs)); \ |  | 
|  106   } while (false) |  110   } while (false) | 
|  107  |  111  | 
|  108 TEST_F(ControlTransferTest, SimpleIf) { |  112 TEST_F(ControlTransferTest, SimpleIf) { | 
|  109   byte code[] = { |  113   byte code[] = { | 
|  110       kExprI32Const,  // @0 |  114       kExprI32Const,  // @0 | 
|  111       0,              //   +1 |  115       0,              // @1 | 
|  112       kExprIf,        // @2 |  116       kExprIf,        // @2 | 
|  113       kExprEnd        // @3 |  117       kLocalVoid,     // @3 | 
 |  118       kExprEnd        // @4 | 
|  114   }; |  119   }; | 
|  115   EXPECT_TARGETS({2, {2, 0, ControlTransfer::kPushVoid}},  // -- |  120   EXPECT_PC_DELTAS({2, 2}); | 
|  116                  {3, {1, 0, ControlTransfer::kPushVoid}}); |  | 
|  117 } |  121 } | 
|  118  |  122  | 
|  119 TEST_F(ControlTransferTest, SimpleIf1) { |  123 TEST_F(ControlTransferTest, SimpleIf1) { | 
|  120   byte code[] = { |  124   byte code[] = { | 
|  121       kExprI32Const,  // @0 |  125       kExprI32Const,  // @0 | 
|  122       0,              //   +1 |  126       0,              // @1 | 
|  123       kExprIf,        // @2 |  127       kExprIf,        // @2 | 
|  124       kExprNop,       // @3 |  128       kLocalVoid,     // @3 | 
|  125       kExprEnd        // @4 |  129       kExprNop,       // @4 | 
 |  130       kExprEnd        // @5 | 
|  126   }; |  131   }; | 
|  127   EXPECT_TARGETS({2, {3, 0, ControlTransfer::kPushVoid}},  // -- |  132   EXPECT_PC_DELTAS({2, 3}); | 
|  128                  {4, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  129 } |  133 } | 
|  130  |  134  | 
|  131 TEST_F(ControlTransferTest, SimpleIf2) { |  135 TEST_F(ControlTransferTest, SimpleIf2) { | 
|  132   byte code[] = { |  136   byte code[] = { | 
|  133       kExprI32Const,  // @0 |  137       kExprI32Const,  // @0 | 
|  134       0,              //   +1 |  138       0,              // @1 | 
|  135       kExprIf,        // @2 |  139       kExprIf,        // @2 | 
|  136       kExprNop,       // @3 |  140       kLocalVoid,     // @3 | 
|  137       kExprNop,       // @4 |  141       kExprNop,       // @4 | 
|  138       kExprEnd        // @5 |  142       kExprNop,       // @5 | 
 |  143       kExprEnd        // @6 | 
|  139   }; |  144   }; | 
|  140   EXPECT_TARGETS({2, {4, 0, ControlTransfer::kPushVoid}},  // -- |  145   EXPECT_PC_DELTAS({2, 4}); | 
|  141                  {5, {1, 2, ControlTransfer::kPopAndRepush}}); |  | 
|  142 } |  146 } | 
|  143  |  147  | 
|  144 TEST_F(ControlTransferTest, SimpleIfElse) { |  148 TEST_F(ControlTransferTest, SimpleIfElse) { | 
|  145   byte code[] = { |  149   byte code[] = { | 
|  146       kExprI32Const,  // @0 |  150       kExprI32Const,  // @0 | 
|  147       0,              //   +1 |  151       0,              // @1 | 
|  148       kExprIf,        // @2 |  152       kExprIf,        // @2 | 
|  149       kExprElse,      // @3 |  153       kLocalVoid,     // @3 | 
|  150       kExprEnd        // @4 |  154       kExprElse,      // @4 | 
 |  155       kExprEnd        // @5 | 
|  151   }; |  156   }; | 
|  152   EXPECT_TARGETS({2, {2, 0, ControlTransfer::kNoAction}},  // -- |  157   EXPECT_PC_DELTAS({2, 3}, {4, 2}); | 
|  153                  {3, {2, 0, ControlTransfer::kPushVoid}},  // -- |  158 } | 
|  154                  {4, {1, 0, ControlTransfer::kPushVoid}}); |  159  | 
 |  160 TEST_F(ControlTransferTest, SimpleIfElse_v1) { | 
 |  161   byte code[] = { | 
 |  162       kExprI32Const,  // @0 | 
 |  163       0,              // @1 | 
 |  164       kExprIf,        // @2 | 
 |  165       kLocalVoid,     // @3 | 
 |  166       kExprI8Const,   // @4 | 
 |  167       0,              // @5 | 
 |  168       kExprElse,      // @6 | 
 |  169       kExprI8Const,   // @7 | 
 |  170       0,              // @8 | 
 |  171       kExprEnd        // @9 | 
 |  172   }; | 
 |  173   EXPECT_PC_DELTAS({2, 5}, {6, 4}); | 
|  155 } |  174 } | 
|  156  |  175  | 
|  157 TEST_F(ControlTransferTest, SimpleIfElse1) { |  176 TEST_F(ControlTransferTest, SimpleIfElse1) { | 
|  158   byte code[] = { |  177   byte code[] = { | 
|  159       kExprI32Const,  // @0 |  178       kExprI32Const,  // @0 | 
|  160       0,              //   +1 |  179       0,              // @1 | 
|  161       kExprIf,        // @2 |  180       kExprIf,        // @2 | 
|  162       kExprNop,       // @3 |  181       kLocalVoid,     // @3 | 
|  163       kExprElse,      // @4 |  182       kExprElse,      // @4 | 
|  164       kExprNop,       // @5 |  183       kExprNop,       // @5 | 
|  165       kExprEnd        // @6 |  184       kExprEnd        // @6 | 
|  166   }; |  185   }; | 
|  167   EXPECT_TARGETS({2, {3, 0, ControlTransfer::kNoAction}},      // -- |  186   EXPECT_PC_DELTAS({2, 3}, {4, 3}); | 
|  168                  {4, {3, 1, ControlTransfer::kPopAndRepush}},  // -- |  | 
|  169                  {6, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  170 } |  187 } | 
|  171  |  188  | 
|  172 TEST_F(ControlTransferTest, IfBr) { |  189 TEST_F(ControlTransferTest, IfBr) { | 
|  173   byte code[] = { |  190   byte code[] = { | 
|  174       kExprI32Const,  // @0 |  191       kExprI32Const,  // @0 | 
|  175       0,              //   +1 |  192       0,              // @1 | 
|  176       kExprIf,        // @2 |  193       kExprIf,        // @2 | 
|  177       kExprBr,        // @3 |  194       kLocalVoid,     // @3 | 
|  178       ARITY_0,        //   +1 |  195       kExprBr,        // @4 | 
|  179       0,              //   +1 |  196       0,              // @5 | 
|  180       kExprEnd        // @6 |  197       kExprEnd        // @6 | 
|  181   }; |  198   }; | 
|  182   EXPECT_TARGETS({2, {5, 0, ControlTransfer::kPushVoid}},  // -- |  199   EXPECT_PC_DELTAS({2, 4}, {4, 3}); | 
|  183                  {3, {4, 0, ControlTransfer::kPushVoid}},  // -- |  | 
|  184                  {6, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  185 } |  200 } | 
|  186  |  201  | 
|  187 TEST_F(ControlTransferTest, IfBrElse) { |  202 TEST_F(ControlTransferTest, IfBrElse) { | 
|  188   byte code[] = { |  203   byte code[] = { | 
|  189       kExprI32Const,  // @0 |  204       kExprI32Const,  // @0 | 
|  190       0,              //   +1 |  205       0,              // @1 | 
|  191       kExprIf,        // @2 |  206       kExprIf,        // @2 | 
|  192       kExprBr,        // @3 |  207       kLocalVoid,     // @3 | 
|  193       ARITY_0,        //   +1 |  208       kExprBr,        // @4 | 
|  194       0,              //   +1 |  209       0,              // @5 | 
|  195       kExprElse,      // @6 |  210       kExprElse,      // @6 | 
|  196       kExprEnd        // @7 |  211       kExprEnd        // @7 | 
|  197   }; |  212   }; | 
|  198   EXPECT_TARGETS({2, {5, 0, ControlTransfer::kNoAction}},      // -- |  213   EXPECT_PC_DELTAS({2, 5}, {4, 4}, {6, 2}); | 
|  199                  {3, {5, 0, ControlTransfer::kPushVoid}},      // -- |  | 
|  200                  {6, {2, 1, ControlTransfer::kPopAndRepush}},  // -- |  | 
|  201                  {7, {1, 0, ControlTransfer::kPushVoid}}); |  | 
|  202 } |  214 } | 
|  203  |  215  | 
|  204 TEST_F(ControlTransferTest, IfElseBr) { |  216 TEST_F(ControlTransferTest, IfElseBr) { | 
|  205   byte code[] = { |  217   byte code[] = { | 
|  206       kExprI32Const,  // @0 |  218       kExprI32Const,  // @0 | 
|  207       0,              //   +1 |  219       0,              // @1 | 
|  208       kExprIf,        // @2 |  220       kExprIf,        // @2 | 
|  209       kExprNop,       // @3 |  221       kLocalVoid,     // @3 | 
|  210       kExprElse,      // @4 |  222       kExprElse,      // @4 | 
|  211       kExprBr,        // @5 |  223       kExprBr,        // @5 | 
|  212       ARITY_0,        //   +1 |  224       0,              // @6 | 
|  213       0,              //   +1 |  225       kExprEnd        // @7 | 
|  214       kExprEnd        // @8 |  | 
|  215   }; |  226   }; | 
|  216   EXPECT_TARGETS({2, {3, 0, ControlTransfer::kNoAction}},      // -- |  227   EXPECT_PC_DELTAS({2, 3}, {4, 4}, {5, 3}); | 
|  217                  {4, {5, 1, ControlTransfer::kPopAndRepush}},  // -- |  | 
|  218                  {5, {4, 0, ControlTransfer::kPushVoid}},      // -- |  | 
|  219                  {8, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  220 } |  228 } | 
|  221  |  229  | 
|  222 TEST_F(ControlTransferTest, BlockEmpty) { |  230 TEST_F(ControlTransferTest, BlockEmpty) { | 
|  223   byte code[] = { |  231   byte code[] = { | 
|  224       kExprBlock,  // @0 |  232       kExprBlock,  // @0 | 
|  225       kExprEnd     // @1 |  233       kExprEnd     // @1 | 
|  226   }; |  234   }; | 
|  227   EXPECT_TARGETS({1, {1, 0, ControlTransfer::kPushVoid}}); |  235   CheckPcDeltas(code, code + sizeof(code), nullptr, 0); | 
|  228 } |  236 } | 
|  229  |  237  | 
|  230 TEST_F(ControlTransferTest, Br0) { |  238 TEST_F(ControlTransferTest, Br0) { | 
|  231   byte code[] = { |  239   byte code[] = { | 
|  232       kExprBlock,  // @0 |  240       kExprBlock,  // @0 | 
|  233       kExprBr,     // @1 |  241       kLocalVoid,  // @1 | 
|  234       ARITY_0,     //   +1 |  242       kExprBr,     // @2 | 
|  235       0,           //   +1 |  243       0,           // @3 | 
|  236       kExprEnd     // @4 |  244       kExprEnd     // @4 | 
|  237   }; |  245   }; | 
|  238   EXPECT_TARGETS({1, {4, 0, ControlTransfer::kPushVoid}}, |  246   EXPECT_PC_DELTAS({2, 3}); | 
|  239                  {4, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  240 } |  247 } | 
|  241  |  248  | 
|  242 TEST_F(ControlTransferTest, Br1) { |  249 TEST_F(ControlTransferTest, Br1) { | 
|  243   byte code[] = { |  250   byte code[] = { | 
|  244       kExprBlock,  // @0 |  251       kExprBlock,  // @0 | 
|  245       kExprNop,    // @1 |  252       kLocalVoid,  // @1 | 
|  246       kExprBr,     // @2 |  253       kExprNop,    // @2 | 
|  247       ARITY_0,     //   +1 |  254       kExprBr,     // @3 | 
|  248       0,           //   +1 |  255       0,           // @4 | 
|  249       kExprEnd     // @5 |  256       kExprEnd     // @5 | 
|  250   }; |  257   }; | 
|  251   EXPECT_TARGETS({2, {4, 1, ControlTransfer::kPopAndRepush}},  // -- |  258   EXPECT_PC_DELTAS({3, 3}); | 
|  252                  {5, {1, 2, ControlTransfer::kPopAndRepush}}); |  259 } | 
 |  260  | 
 |  261 TEST_F(ControlTransferTest, Br_v1a) { | 
 |  262   byte code[] = { | 
 |  263       kExprBlock,    // @0 | 
 |  264       kLocalVoid,    // @1 | 
 |  265       kExprI8Const,  // @2 | 
 |  266       0,             // @3 | 
 |  267       kExprBr,       // @4 | 
 |  268       0,             // @5 | 
 |  269       kExprEnd       // @6 | 
 |  270   }; | 
 |  271   EXPECT_PC_DELTAS({4, 3}); | 
 |  272 } | 
 |  273  | 
 |  274 TEST_F(ControlTransferTest, Br_v1b) { | 
 |  275   byte code[] = { | 
 |  276       kExprBlock,    // @0 | 
 |  277       kLocalVoid,    // @1 | 
 |  278       kExprI8Const,  // @2 | 
 |  279       0,             // @3 | 
 |  280       kExprBr,       // @4 | 
 |  281       0,             // @5 | 
 |  282       kExprEnd       // @6 | 
 |  283   }; | 
 |  284   EXPECT_PC_DELTAS({4, 3}); | 
 |  285 } | 
 |  286  | 
 |  287 TEST_F(ControlTransferTest, Br_v1c) { | 
 |  288   byte code[] = { | 
 |  289       kExprI8Const,  // @0 | 
 |  290       0,             // @1 | 
 |  291       kExprBlock,    // @2 | 
 |  292       kLocalVoid,    // @3 | 
 |  293       kExprBr,       // @4 | 
 |  294       0,             // @5 | 
 |  295       kExprEnd       // @6 | 
 |  296   }; | 
 |  297   EXPECT_PC_DELTAS({4, 3}); | 
|  253 } |  298 } | 
|  254  |  299  | 
|  255 TEST_F(ControlTransferTest, Br2) { |  300 TEST_F(ControlTransferTest, Br2) { | 
|  256   byte code[] = { |  301   byte code[] = { | 
|  257       kExprBlock,  // @0 |  302       kExprBlock,  // @0 | 
|  258       kExprNop,    // @1 |  303       kLocalVoid,  // @1 | 
|  259       kExprNop,    // @2 |  304       kExprNop,    // @2 | 
|  260       kExprBr,     // @3 |  305       kExprNop,    // @3 | 
|  261       ARITY_0,     //   +1 |  306       kExprBr,     // @4 | 
|  262       0,           //   +1 |  307       0,           // @5 | 
|  263       kExprEnd     // @6 |  308       kExprEnd     // @6 | 
|  264   }; |  309   }; | 
|  265   EXPECT_TARGETS({3, {4, 2, ControlTransfer::kPopAndRepush}},  // -- |  310   EXPECT_PC_DELTAS({4, 3}); | 
|  266                  {6, {1, 3, ControlTransfer::kPopAndRepush}}); |  | 
|  267 } |  311 } | 
|  268  |  312  | 
|  269 TEST_F(ControlTransferTest, Br0b) { |  313 TEST_F(ControlTransferTest, Br0b) { | 
|  270   byte code[] = { |  314   byte code[] = { | 
|  271       kExprBlock,  // @0 |  315       kExprBlock,  // @0 | 
|  272       kExprBr,     // @1 |  316       kLocalVoid,  // @1 | 
|  273       ARITY_0,     //   +1 |  317       kExprBr,     // @2 | 
|  274       0,           //   +1 |  318       0,           // @3 | 
|  275       kExprNop,    // @4 |  319       kExprNop,    // @4 | 
|  276       kExprEnd     // @5 |  320       kExprEnd     // @5 | 
|  277   }; |  321   }; | 
|  278   EXPECT_TARGETS({1, {5, 0, ControlTransfer::kPushVoid}},  // -- |  322   EXPECT_PC_DELTAS({2, 4}); | 
|  279                  {5, {1, 2, ControlTransfer::kPopAndRepush}}); |  | 
|  280 } |  323 } | 
|  281  |  324  | 
|  282 TEST_F(ControlTransferTest, Br0c) { |  325 TEST_F(ControlTransferTest, Br0c) { | 
|  283   byte code[] = { |  326   byte code[] = { | 
|  284       kExprBlock,  // @0 |  327       kExprBlock,  // @0 | 
|  285       kExprBr,     // @1 |  328       kLocalVoid,  // @1 | 
|  286       ARITY_0,     //   +1 |  329       kExprBr,     // @2 | 
|  287       0,           //   +1 |  330       0,           // @3 | 
|  288       kExprNop,    // @4 |  331       kExprNop,    // @4 | 
|  289       kExprNop,    // @5 |  332       kExprNop,    // @5 | 
|  290       kExprEnd     // @6 |  333       kExprEnd     // @6 | 
|  291   }; |  334   }; | 
|  292   EXPECT_TARGETS({1, {6, 0, ControlTransfer::kPushVoid}},  // -- |  335   EXPECT_PC_DELTAS({2, 5}); | 
|  293                  {6, {1, 3, ControlTransfer::kPopAndRepush}}); |  | 
|  294 } |  336 } | 
|  295  |  337  | 
|  296 TEST_F(ControlTransferTest, SimpleLoop1) { |  338 TEST_F(ControlTransferTest, SimpleLoop1) { | 
|  297   byte code[] = { |  339   byte code[] = { | 
|  298       kExprLoop,  // @0 |  340       kExprLoop,   // @0 | 
|  299       kExprBr,    // @1 |  341       kLocalVoid,  // @1 | 
|  300       ARITY_0,    //   +1 |  342       kExprBr,     // @2 | 
|  301       0,          //   +1 |  343       0,           // @3 | 
|  302       kExprEnd    // @4 |  344       kExprEnd     // @4 | 
|  303   }; |  345   }; | 
|  304   EXPECT_TARGETS({1, {-1, 0, ControlTransfer::kNoAction}},  // -- |  346   EXPECT_PC_DELTAS({2, -2}); | 
|  305                  {4, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  306 } |  347 } | 
|  307  |  348  | 
|  308 TEST_F(ControlTransferTest, SimpleLoop2) { |  349 TEST_F(ControlTransferTest, SimpleLoop2) { | 
|  309   byte code[] = { |  350   byte code[] = { | 
|  310       kExprLoop,  // @0 |  351       kExprLoop,   // @0 | 
|  311       kExprNop,   // @1 |  352       kLocalVoid,  // @1 | 
|  312       kExprBr,    // @2 |  353       kExprNop,    // @2 | 
|  313       ARITY_0,    //   +1 |  354       kExprBr,     // @3 | 
|  314       0,          //   +1 |  355       0,           // @4 | 
|  315       kExprEnd    // @5 |  356       kExprEnd     // @5 | 
|  316   }; |  357   }; | 
|  317   EXPECT_TARGETS({2, {-2, 1, ControlTransfer::kNoAction}},  // -- |  358   EXPECT_PC_DELTAS({3, -3}); | 
|  318                  {5, {1, 2, ControlTransfer::kPopAndRepush}}); |  | 
|  319 } |  359 } | 
|  320  |  360  | 
|  321 TEST_F(ControlTransferTest, SimpleLoopExit1) { |  361 TEST_F(ControlTransferTest, SimpleLoopExit1) { | 
|  322   byte code[] = { |  362   byte code[] = { | 
|  323       kExprLoop,  // @0 |  363       kExprLoop,   // @0 | 
|  324       kExprBr,    // @1 |  364       kLocalVoid,  // @1 | 
|  325       ARITY_0,    //   +1 |  365       kExprBr,     // @2 | 
|  326       1,          //   +1 |  366       1,           // @3 | 
|  327       kExprEnd    // @4 |  367       kExprEnd     // @4 | 
|  328   }; |  368   }; | 
|  329   EXPECT_TARGETS({1, {4, 0, ControlTransfer::kPushVoid}},  // -- |  369   EXPECT_PC_DELTAS({2, 3}); | 
|  330                  {4, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  331 } |  370 } | 
|  332  |  371  | 
|  333 TEST_F(ControlTransferTest, SimpleLoopExit2) { |  372 TEST_F(ControlTransferTest, SimpleLoopExit2) { | 
|  334   byte code[] = { |  373   byte code[] = { | 
|  335       kExprLoop,  // @0 |  374       kExprLoop,   // @0 | 
|  336       kExprNop,   // @1 |  375       kLocalVoid,  // @1 | 
|  337       kExprBr,    // @2 |  376       kExprNop,    // @2 | 
|  338       ARITY_0,    //   +1 |  377       kExprBr,     // @3 | 
|  339       1,          //   +1 |  378       1,           // @4 | 
|  340       kExprEnd    // @5 |  379       kExprEnd     // @5 | 
|  341   }; |  380   }; | 
|  342   EXPECT_TARGETS({2, {4, 1, ControlTransfer::kPopAndRepush}},  // -- |  381   EXPECT_PC_DELTAS({3, 3}); | 
|  343                  {5, {1, 2, ControlTransfer::kPopAndRepush}}); |  | 
|  344 } |  382 } | 
|  345  |  383  | 
|  346 TEST_F(ControlTransferTest, BrTable0) { |  384 TEST_F(ControlTransferTest, BrTable0) { | 
|  347   byte code[] = { |  385   byte code[] = { | 
|  348       kExprBlock,    // @0 |  386       kExprBlock,    // @0 | 
|  349       kExprI8Const,  // @1 |  387       kLocalVoid,    // @1 | 
|  350       0,             //   +1 |  388       kExprI8Const,  // @2 | 
|  351       kExprBrTable,  // @3 |  389       0,             // @3 | 
|  352       ARITY_0,       //   +1 |  390       kExprBrTable,  // @4 | 
|  353       0,             //   +1 |  391       0,             // @5 | 
|  354       U32_LE(0),     //   +4 |  392       U32V_1(0),     // @6 | 
|  355       kExprEnd       // @10 |  393       kExprEnd       // @7 | 
|  356   }; |  394   }; | 
|  357   EXPECT_TARGETS({3, {8, 0, ControlTransfer::kPushVoid}},  // -- |  395   EXPECT_PC_DELTAS({4, 4}); | 
|  358                  {10, {1, 1, ControlTransfer::kPopAndRepush}}); |  396 } | 
 |  397  | 
 |  398 TEST_F(ControlTransferTest, BrTable0_v1a) { | 
 |  399   byte code[] = { | 
 |  400       kExprBlock,    // @0 | 
 |  401       kLocalVoid,    // @1 | 
 |  402       kExprI8Const,  // @2 | 
 |  403       0,             // @3 | 
 |  404       kExprI8Const,  // @4 | 
 |  405       0,             // @5 | 
 |  406       kExprBrTable,  // @6 | 
 |  407       0,             // @7 | 
 |  408       U32V_1(0),     // @8 | 
 |  409       kExprEnd       // @9 | 
 |  410   }; | 
 |  411   EXPECT_PC_DELTAS({6, 4}); | 
 |  412 } | 
 |  413  | 
 |  414 TEST_F(ControlTransferTest, BrTable0_v1b) { | 
 |  415   byte code[] = { | 
 |  416       kExprBlock,    // @0 | 
 |  417       kLocalVoid,    // @1 | 
 |  418       kExprI8Const,  // @2 | 
 |  419       0,             // @3 | 
 |  420       kExprI8Const,  // @4 | 
 |  421       0,             // @5 | 
 |  422       kExprBrTable,  // @6 | 
 |  423       0,             // @7 | 
 |  424       U32V_1(0),     // @8 | 
 |  425       kExprEnd       // @9 | 
 |  426   }; | 
 |  427   EXPECT_PC_DELTAS({6, 4}); | 
|  359 } |  428 } | 
|  360  |  429  | 
|  361 TEST_F(ControlTransferTest, BrTable1) { |  430 TEST_F(ControlTransferTest, BrTable1) { | 
|  362   byte code[] = { |  431   byte code[] = { | 
|  363       kExprBlock,    // @0 |  432       kExprBlock,    // @0 | 
|  364       kExprI8Const,  // @1 |  433       kLocalVoid,    // @1 | 
|  365       0,             //   +1 |  434       kExprI8Const,  // @2 | 
|  366       kExprBrTable,  // @3 |  435       0,             // @3 | 
|  367       ARITY_0,       //   +1 |  436       kExprBrTable,  // @4 | 
|  368       1,             //   +1 |  437       1,             // @5 | 
|  369       U32_LE(0),     //   +4 |  438       U32V_1(0),     // @6 | 
|  370       U32_LE(0),     //   +4 |  439       U32V_1(0),     // @7 | 
|  371       kExprEnd       // @14 |  440       kExprEnd       // @8 | 
|  372   }; |  441   }; | 
|  373   EXPECT_TARGETS({3, {12, 0, ControlTransfer::kPushVoid}},  // -- |  442   EXPECT_PC_DELTAS({4, 5}, {5, 4}); | 
|  374                  {4, {11, 0, ControlTransfer::kPushVoid}},  // -- |  | 
|  375                  {14, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  376 } |  443 } | 
|  377  |  444  | 
|  378 TEST_F(ControlTransferTest, BrTable2) { |  445 TEST_F(ControlTransferTest, BrTable2) { | 
|  379   byte code[] = { |  446   byte code[] = { | 
|  380       kExprBlock,    // @0 |  447       kExprBlock,    // @0 | 
|  381       kExprBlock,    // @1 |  448       kLocalVoid,    // @1 | 
|  382       kExprI8Const,  // @2 |  449       kExprBlock,    // @2 | 
|  383       0,             //   +1 |  450       kLocalVoid,    // @3 | 
|  384       kExprBrTable,  // @4 |  451       kExprI8Const,  // @4 | 
|  385       ARITY_0,       //   +1 |  452       0,             // @5 | 
|  386       2,             //   +1 |  453       kExprBrTable,  // @6 | 
|  387       U32_LE(0),     //   +4 |  454       2,             // @7 | 
|  388       U32_LE(0),     //   +4 |  455       U32V_1(0),     // @8 | 
|  389       U32_LE(1),     //   +4 |  456       U32V_1(0),     // @9 | 
|  390       kExprEnd,      // @19 |  457       U32V_1(1),     // @10 | 
|  391       kExprEnd       // @19 |  458       kExprEnd,      // @11 | 
|  392   }; |  459       kExprEnd       // @12 | 
|  393   EXPECT_TARGETS({4, {16, 0, ControlTransfer::kPushVoid}},      // -- |  460   }; | 
|  394                  {5, {15, 0, ControlTransfer::kPushVoid}},      // -- |  461   EXPECT_PC_DELTAS({6, 6}, {7, 5}, {8, 5}); | 
|  395                  {6, {15, 0, ControlTransfer::kPushVoid}},      // -- |  | 
|  396                  {19, {1, 1, ControlTransfer::kPopAndRepush}},  // -- |  | 
|  397                  {20, {1, 1, ControlTransfer::kPopAndRepush}}); |  | 
|  398 } |  462 } | 
|  399  |  463  | 
|  400 }  // namespace wasm |  464 }  // namespace wasm | 
|  401 }  // namespace internal |  465 }  // namespace internal | 
|  402 }  // namespace v8 |  466 }  // namespace v8 | 
| OLD | NEW |