| 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 |