| 361 | } |
| 362 | |
| 363 | static Bytes eat_instructions(const Bytes &old_goal, bool back, std::deque<Instruction> &eaten, size_t *p_eaten_size) |
| 364 | { |
| 365 | Bytes goal = old_goal; |
| 366 | bool forward = true; |
| 367 | size_t eaten_size = 0; |
| 368 | while(forward) { |
| 369 | forward = false; |
| 370 | for (size_t sz = 2; sz<=4; sz+=2) { |
| 371 | if (goal.size() >= sz) { |
| 372 | Bytes instr_bytes = back ? |
| 373 | Bytes(goal.end() - sz, goal.end()) : |
| 374 | Bytes(goal.begin(), goal.begin() + sz); |
| 375 | auto it = instructions.find(instr_bytes); |
| 376 | if (it != instructions.end()) { |
| 377 | const Instruction &instr = it->second; |
| 378 | //std::cout << "EA: " << goal << " " << instr.bytes() << " T'" << instr.text() << "'" << std::endl; |
| 379 | if (instr.is_jump() && !back) { |
| 380 | forward = true; |
| 381 | eaten.push_back(instr); |
| 382 | if (instr.size() < goal.size()) { |
| 383 | Bytes trail = Bytes(goal.begin() + instr.size(), goal.end()); |
| 384 | eaten.push_back(Instruction(trail, "<after jump>")); |
| 385 | } |
| 386 | eaten_size = goal.size(); |
| 387 | goal = Bytes(); |
| 388 | } else if(instr.is_must_jump() && back) { |
| 389 | /* Bad instruction */ |
| 390 | } else { |
| 391 | forward = true; |
| 392 | if (back) { |
| 393 | eaten.push_front(instr); |
| 394 | } else { |
| 395 | eaten.push_back(instr); |
| 396 | } |
| 397 | eaten_size += sz; |
| 398 | goal = back ? |
| 399 | Bytes(goal.begin(), goal.end() - sz): |
| 400 | Bytes(goal.begin() + sz, goal.end()); |
| 401 | } |
| 402 | } |
| 403 | } |
| 404 | } |
| 405 | } |
| 406 | *p_eaten_size = eaten_size; |
| 407 | return goal; |
| 408 | } |
| 409 | |
| 410 | static void make_block(const Bytes &goal, int depth, bool prev, |
| 411 | const std::deque<Instruction> &already_eaten, BlockList &list) |
no test coverage detected