void make_instruction()

in tools/oatmeal/dex.cpp [33:282]


void make_instruction(const uint16_t** insns_ptr,
                      const QuickData* quick_data,
                      const std::string* dex,
                      size_t& file_ptr,
                      WritableBuffer& out_buffer) {
  auto& insns = *insns_ptr;
  auto fopcode = static_cast<DexOpcode>(*insns++);
  DexOpcode opcode = static_cast<DexOpcode>(fopcode & 0xff);

  // clang-format off

#ifdef DEBUG_LOG
  printf("Processing FOPCODE::OPCODE: %04x :: %02x :: %s\n",
         fopcode,
         opcode,
         print(opcode).c_str());
#endif

  switch (opcode) {
  case DOPCODE_NOP: {
#ifdef DEBUG_LOG
    printf("Processing FOPCODE: %s\n", print(fopcode).c_str());
#endif
    if (fopcode == FOPCODE_PACKED_SWITCH) {
      size_t count = (*insns--) * 2 + 4;
      for (size_t i = 0; i < count; i++) {
        WRITE16_TO_BUFFER(out_buffer, insns, file_ptr)
        insns++;
      }
      return;
    } else if (fopcode == FOPCODE_SPARSE_SWITCH) {
      size_t count = (*insns--) * 4 + 2;
      for (size_t i = 0; i < count; i++) {
        WRITE16_TO_BUFFER(out_buffer, insns, file_ptr)
        insns++;
      }
      return;
    } else if (fopcode == FOPCODE_FILLED_ARRAY) {
      uint16_t ewidth = *insns++;
      uint32_t size = *((uint32_t*)insns);
      size_t count = (ewidth * size + 1) / 2 + 4;
      insns -= 2;
      for (size_t i = 0; i < count; i++) {
        WRITE16_TO_BUFFER(out_buffer, insns, file_ptr)
        insns++;
      }
      return;
    }
  }

    /* fall through for NOP */
    SWITCH_FORMAT_10 {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x :: %s\n", opcode, print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_20 {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t arg = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x :: %s\n",
             opcode,
             arg,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_30 {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t arg_low = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_low, file_ptr)

      uint16_t arg_high = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_high, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x%02x :: %s\n",
             opcode,
             arg_low,
             arg_high,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_50 {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t arg_0 = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_0, file_ptr)

      uint16_t arg_1 = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_1, file_ptr)

      uint16_t arg_2 = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_2, file_ptr)

      uint16_t arg_3 = *insns++;
      WRITE16_TO_BUFFER(out_buffer, arg_3, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x%02x%02x%02x :: %s\n",
             opcode,
             arg_0,
             arg_1,
             arg_2,
             arg_3,
             print(opcode).c_str());
#endif
      break;
      // return new DexInstruction(insns - 5, 4);
  }

  SWITCH_FORMAT_REGULAR_FIELD_REF {
    uint16_t fidx = *insns++;

    uint16_t quick_fopcode = fopcode;
    uint16_t quick_arg = fidx;
    uint16_t quick_data_off = quick_data->get_field_offset(*dex, fidx);
    if (quick_data_off > 0) {
      quick_fopcode = (fopcode & 0xff00) | (quicken(opcode) & 0x00ff);
      quick_arg = quick_data_off;
#ifdef DEBUG_LOG
      printf("QUICKEN: [%s] %s :: %02x->%02x :: %02x->%02x\n",
        (*dex).c_str(),
        print(opcode).c_str(),
        fopcode,
        quick_fopcode,
        fidx,
        quick_arg);
#endif
    } else {
#ifdef DEBUG_LOG
      printf("No quick mapping for: [%s]:%u\n", (*dex).c_str(), fidx);
#endif
    }

      WRITE16_TO_BUFFER(out_buffer, quick_fopcode, file_ptr)
      WRITE16_TO_BUFFER(out_buffer, quick_arg, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x :: %s\n",
             quick_fopcode,
             quick_arg,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_REGULAR_METHOD_REF {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t midx = *insns++;
      uint16_t arg = *insns++;

      WRITE16_TO_BUFFER(out_buffer, midx, file_ptr)
      WRITE16_TO_BUFFER(out_buffer, arg, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x %02x :: %s\n",
             fopcode,
             midx,
             arg,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_CONST_STRING {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t sidx = *insns++;
      WRITE16_TO_BUFFER(out_buffer, sidx, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x :: %s\n",
             fopcode,
             sidx,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_CONST_STRING_JUMBO {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t sidx_partial_low = *insns++;
      uint16_t sidx_partial_high = *insns++;

      WRITE16_TO_BUFFER(out_buffer, sidx_partial_low, file_ptr)
      WRITE16_TO_BUFFER(out_buffer, sidx_partial_high, file_ptr)

#ifdef DEBUG_LOG
      uint32_t sidx = sidx_partial_high << 16 | sidx_partial_low;
      printf("Writing OPCODE: %02x %04x :: %s\n",
             fopcode,
             sidx,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_TYPE_REF {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t tidx = *insns++;

      WRITE16_TO_BUFFER(out_buffer, tidx, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x :: %s\n",
             fopcode,
             tidx,
             print(opcode).c_str());
#endif
      break;
    }

    SWITCH_FORMAT_FILL_ARRAY {
      WRITE16_TO_BUFFER(out_buffer, fopcode, file_ptr)

      uint16_t tidx = *insns++;
      uint16_t arg = *insns++;

      WRITE16_TO_BUFFER(out_buffer, tidx, file_ptr)
      WRITE16_TO_BUFFER(out_buffer, arg, file_ptr)

#ifdef DEBUG_LOG
      printf("Writing OPCODE: %02x %02x :: %s\n",
             fopcode,
             tidx,
             print(opcode).c_str());
#endif
      break;
    }
  default:
    fprintf(stderr, "Unknown opcode %02x\n", opcode);
    // return nullptr;
  }
  // clang-format on
}