androscalpel/androscalpel/src/instructions.rs
2024-04-24 11:27:21 +02:00

29126 lines
886 KiB
Rust

//! Representation of the instructions.
//!
//! Instruction at a sligthly higher level than
//! <https://source.android.com/docs/core/runtime/dalvik-bytecode>
use serde::{Deserialize, Serialize};
use crate::hashmap_vectorize;
use crate::{DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result};
use androscalpel_serializer::Instruction as InsFormat;
use androscalpel_serializer::Serializable;
use anyhow::anyhow;
use pyo3::exceptions::PyTypeError;
use pyo3::prelude::*;
use std::collections::{HashMap, HashSet};
const I8_MIN_AS_I16: i16 = i8::MIN as i16;
const I8_MAX_AS_I16: i16 = i8::MAX as i16;
const I8_MIN_AS_I32: i32 = i8::MIN as i32;
const I8_MAX_AS_I32: i32 = i8::MAX as i32;
const I16_MIN_AS_I32: i32 = i16::MIN as i32;
const I16_MAX_AS_I32: i32 = i16::MAX as i32;
const I16_MIN_AS_I64: i64 = i16::MIN as i64;
const I16_MAX_AS_I64: i64 = i16::MAX as i64;
const I32_MIN_AS_I64: i64 = i32::MIN as i64;
const I32_MAX_AS_I64: i64 = i32::MAX as i64;
const U16_MAX_AS_USIZE: usize = u16::MAX as usize;
// TODO: impl PartialEq and Eq for call site to derive them here
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub enum Instruction {
Nop(Nop),
Move(Move),
MoveWide(MoveWide),
MoveObject(MoveObject),
MoveResult(MoveResult),
MoveResultWide(MoveResultWide),
MoveException(MoveException),
MoveResultObject(MoveResultObject),
ReturnVoid(ReturnVoid),
Return(Return),
ReturnWide(ReturnWide),
ReturnObject(ReturnObject),
Const(Const),
ConstWide(ConstWide),
ConstString(ConstString),
ConstClass(ConstClass),
MonitorEnter(MonitorEnter),
MonitorExit(MonitorExit),
CheckCast(CheckCast),
InstanceOf(InstanceOf),
ArrayLength(ArrayLength),
NewInstance(NewInstance),
NewArray(NewArray),
FilledNewArray(FilledNewArray),
FillArrayData(FillArrayData),
Throw(Throw),
Goto(Goto),
Switch(Switch),
CmpLFloat(CmpLFloat),
CmpGFloat(CmpGFloat),
CmpLDouble(CmpLDouble),
CmpGDouble(CmpGDouble),
CmpLong(CmpLong),
IfEq(IfEq),
IfNe(IfNe),
IfLt(IfLt),
IfGe(IfGe),
IfGt(IfGt),
IfLe(IfLe),
IfEqZ(IfEqZ),
IfNeZ(IfNeZ),
IfLtZ(IfLtZ),
IfGeZ(IfGeZ),
IfGtZ(IfGtZ),
IfLeZ(IfLeZ),
AGet(AGet),
AGetWide(AGetWide),
AGetObject(AGetObject),
AGetBoolean(AGetBoolean),
AGetByte(AGetByte),
AGetChar(AGetChar),
AGetShort(AGetShort),
APut(APut),
APutWide(APutWide),
APutObject(APutObject),
APutBoolean(APutBoolean),
APutByte(APutByte),
APutChar(APutChar),
APutShort(APutShort),
IGet(IGet),
IGetWide(IGetWide),
IGetObject(IGetObject),
IGetBoolean(IGetBoolean),
IGetByte(IGetByte),
IGetChar(IGetChar),
IGetShort(IGetShort),
IPut(IPut),
IPutWide(IPutWide),
IPutObject(IPutObject),
IPutBoolean(IPutBoolean),
IPutByte(IPutByte),
IPutChar(IPutChar),
IPutShort(IPutShort),
SGet(SGet),
SGetWide(SGetWide),
SGetObject(SGetObject),
SGetBoolean(SGetBoolean),
SGetByte(SGetByte),
SGetChar(SGetChar),
SGetShort(SGetShort),
SPut(SPut),
SPutWide(SPutWide),
SPutObject(SPutObject),
SPutBoolean(SPutBoolean),
SPutByte(SPutByte),
SPutChar(SPutChar),
SPutShort(SPutShort),
InvokeVirtual(InvokeVirtual),
InvokeSuper(InvokeSuper),
InvokeDirect(InvokeDirect),
InvokeStatic(InvokeStatic),
InvokeInterface(InvokeInterface),
NegInt(NegInt),
NotInt(NotInt),
NegLong(NegLong),
NotLong(NotLong),
NegFloat(NegFloat),
NegDouble(NegDouble),
IntToLong(IntToLong),
IntToFloat(IntToFloat),
IntToDouble(IntToDouble),
LongToInt(LongToInt),
LongToFloat(LongToFloat),
LongToDouble(LongToDouble),
FloatToInt(FloatToInt),
FloatToLong(FloatToLong),
FloatToDouble(FloatToDouble),
DoubleToInt(DoubleToInt),
DoubleToLong(DoubleToLong),
DoubleToFloat(DoubleToFloat),
IntToByte(IntToByte),
IntToChar(IntToChar),
IntToShort(IntToShort),
AddInt(AddInt),
SubInt(SubInt),
MulInt(MulInt),
DivInt(DivInt),
RemInt(RemInt),
AndInt(AndInt),
OrInt(OrInt),
XorInt(XorInt),
ShlInt(ShlInt),
ShrInt(ShrInt),
UshrInt(UshrInt),
AddLong(AddLong),
SubLong(SubLong),
MulLong(MulLong),
DivLong(DivLong),
RemLong(RemLong),
AndLong(AndLong),
OrLong(OrLong),
XorLong(XorLong),
ShlLong(ShlLong),
ShrLong(ShrLong),
UshrLong(UshrLong),
AddFloat(AddFloat),
SubFloat(SubFloat),
MulFloat(MulFloat),
DivFloat(DivFloat),
RemFloat(RemFloat),
AddDouble(AddDouble),
SubDouble(SubDouble),
MulDouble(MulDouble),
DivDouble(DivDouble),
RemDouble(RemDouble),
AddInt2Addr(AddInt2Addr),
SubInt2Addr(SubInt2Addr),
MulInt2Addr(MulInt2Addr),
DivInt2Addr(DivInt2Addr),
RemInt2Addr(RemInt2Addr),
AndInt2Addr(AndInt2Addr),
OrInt2Addr(OrInt2Addr),
XorInt2Addr(XorInt2Addr),
ShlInt2Addr(ShlInt2Addr),
ShrInt2Addr(ShrInt2Addr),
UshrInt2Addr(UshrInt2Addr),
AddLong2Addr(AddLong2Addr),
SubLong2Addr(SubLong2Addr),
MulLong2Addr(MulLong2Addr),
DivLong2Addr(DivLong2Addr),
RemLong2Addr(RemLong2Addr),
AndLong2Addr(AndLong2Addr),
OrLong2Addr(OrLong2Addr),
XorLong2Addr(XorLong2Addr),
ShlLong2Addr(ShlLong2Addr),
ShrLong2Addr(ShrLong2Addr),
UshrLong2Addr(UshrLong2Addr),
AddFloat2Addr(AddFloat2Addr),
SubFloat2Addr(SubFloat2Addr),
MulFloat2Addr(MulFloat2Addr),
DivFloat2Addr(DivFloat2Addr),
RemFloat2Addr(RemFloat2Addr),
AddDouble2Addr(AddDouble2Addr),
SubDouble2Addr(SubDouble2Addr),
MulDouble2Addr(MulDouble2Addr),
DivDouble2Addr(DivDouble2Addr),
RemDouble2Addr(RemDouble2Addr),
AddIntLit(AddIntLit),
RsubIntLit(RsubIntLit),
MulIntLit(MulIntLit),
DivIntLit(DivIntLit),
RemIntLit(RemIntLit),
AndIntLit(AndIntLit),
OrIntLit(OrIntLit),
XorIntLit(XorIntLit),
ShlIntLit(ShlIntLit),
ShrIntLit(ShrIntLit),
UshrIntLit(UshrIntLit),
InvokePolymorphic(InvokePolymorphic),
InvokeCustom(InvokeCustom),
ConstMethodHandle(ConstMethodHandle),
ConstMethodType(ConstMethodType),
Try(Try),
Label(Label),
}
impl Instruction {
pub fn __str__(&self) -> String {
match self {
Self::Nop(ins) => ins.__str__(),
Self::Move(ins) => ins.__str__(),
Self::MoveWide(ins) => ins.__str__(),
Self::MoveObject(ins) => ins.__str__(),
Self::MoveResult(ins) => ins.__str__(),
Self::MoveResultWide(ins) => ins.__str__(),
Self::MoveException(ins) => ins.__str__(),
Self::MoveResultObject(ins) => ins.__str__(),
Self::ReturnVoid(ins) => ins.__str__(),
Self::Return(ins) => ins.__str__(),
Self::ReturnWide(ins) => ins.__str__(),
Self::ReturnObject(ins) => ins.__str__(),
Self::Const(ins) => ins.__str__(),
Self::ConstWide(ins) => ins.__str__(),
Self::ConstString(ins) => ins.__str__(),
Self::ConstClass(ins) => ins.__str__(),
Self::MonitorEnter(ins) => ins.__str__(),
Self::MonitorExit(ins) => ins.__str__(),
Self::CheckCast(ins) => ins.__str__(),
Self::InstanceOf(ins) => ins.__str__(),
Self::ArrayLength(ins) => ins.__str__(),
Self::NewInstance(ins) => ins.__str__(),
Self::NewArray(ins) => ins.__str__(),
Self::FilledNewArray(ins) => ins.__str__(),
Self::FillArrayData(ins) => ins.__str__(),
Self::Throw(ins) => ins.__str__(),
Self::Goto(ins) => ins.__str__(),
Self::Switch(ins) => ins.__str__(),
Self::CmpLFloat(ins) => ins.__str__(),
Self::CmpGFloat(ins) => ins.__str__(),
Self::CmpLDouble(ins) => ins.__str__(),
Self::CmpGDouble(ins) => ins.__str__(),
Self::CmpLong(ins) => ins.__str__(),
Self::IfEq(ins) => ins.__str__(),
Self::IfNe(ins) => ins.__str__(),
Self::IfLt(ins) => ins.__str__(),
Self::IfGe(ins) => ins.__str__(),
Self::IfGt(ins) => ins.__str__(),
Self::IfLe(ins) => ins.__str__(),
Self::IfEqZ(ins) => ins.__str__(),
Self::IfNeZ(ins) => ins.__str__(),
Self::IfLtZ(ins) => ins.__str__(),
Self::IfGeZ(ins) => ins.__str__(),
Self::IfGtZ(ins) => ins.__str__(),
Self::IfLeZ(ins) => ins.__str__(),
Self::AGet(ins) => ins.__str__(),
Self::AGetWide(ins) => ins.__str__(),
Self::AGetObject(ins) => ins.__str__(),
Self::AGetBoolean(ins) => ins.__str__(),
Self::AGetByte(ins) => ins.__str__(),
Self::AGetChar(ins) => ins.__str__(),
Self::AGetShort(ins) => ins.__str__(),
Self::APut(ins) => ins.__str__(),
Self::APutWide(ins) => ins.__str__(),
Self::APutObject(ins) => ins.__str__(),
Self::APutBoolean(ins) => ins.__str__(),
Self::APutByte(ins) => ins.__str__(),
Self::APutChar(ins) => ins.__str__(),
Self::APutShort(ins) => ins.__str__(),
Self::IGet(ins) => ins.__str__(),
Self::IGetWide(ins) => ins.__str__(),
Self::IGetObject(ins) => ins.__str__(),
Self::IGetBoolean(ins) => ins.__str__(),
Self::IGetByte(ins) => ins.__str__(),
Self::IGetChar(ins) => ins.__str__(),
Self::IGetShort(ins) => ins.__str__(),
Self::IPut(ins) => ins.__str__(),
Self::IPutWide(ins) => ins.__str__(),
Self::IPutObject(ins) => ins.__str__(),
Self::IPutBoolean(ins) => ins.__str__(),
Self::IPutByte(ins) => ins.__str__(),
Self::IPutChar(ins) => ins.__str__(),
Self::IPutShort(ins) => ins.__str__(),
Self::SGet(ins) => ins.__str__(),
Self::SGetWide(ins) => ins.__str__(),
Self::SGetObject(ins) => ins.__str__(),
Self::SGetBoolean(ins) => ins.__str__(),
Self::SGetByte(ins) => ins.__str__(),
Self::SGetChar(ins) => ins.__str__(),
Self::SGetShort(ins) => ins.__str__(),
Self::SPut(ins) => ins.__str__(),
Self::SPutWide(ins) => ins.__str__(),
Self::SPutObject(ins) => ins.__str__(),
Self::SPutBoolean(ins) => ins.__str__(),
Self::SPutByte(ins) => ins.__str__(),
Self::SPutChar(ins) => ins.__str__(),
Self::SPutShort(ins) => ins.__str__(),
Self::InvokeVirtual(ins) => ins.__str__(),
Self::InvokeSuper(ins) => ins.__str__(),
Self::InvokeDirect(ins) => ins.__str__(),
Self::InvokeStatic(ins) => ins.__str__(),
Self::InvokeInterface(ins) => ins.__str__(),
Self::NegInt(ins) => ins.__str__(),
Self::NotInt(ins) => ins.__str__(),
Self::NegLong(ins) => ins.__str__(),
Self::NotLong(ins) => ins.__str__(),
Self::NegFloat(ins) => ins.__str__(),
Self::NegDouble(ins) => ins.__str__(),
Self::IntToLong(ins) => ins.__str__(),
Self::IntToFloat(ins) => ins.__str__(),
Self::IntToDouble(ins) => ins.__str__(),
Self::LongToInt(ins) => ins.__str__(),
Self::LongToFloat(ins) => ins.__str__(),
Self::LongToDouble(ins) => ins.__str__(),
Self::FloatToInt(ins) => ins.__str__(),
Self::FloatToLong(ins) => ins.__str__(),
Self::FloatToDouble(ins) => ins.__str__(),
Self::DoubleToInt(ins) => ins.__str__(),
Self::DoubleToLong(ins) => ins.__str__(),
Self::DoubleToFloat(ins) => ins.__str__(),
Self::IntToByte(ins) => ins.__str__(),
Self::IntToChar(ins) => ins.__str__(),
Self::IntToShort(ins) => ins.__str__(),
Self::AddInt(ins) => ins.__str__(),
Self::SubInt(ins) => ins.__str__(),
Self::MulInt(ins) => ins.__str__(),
Self::DivInt(ins) => ins.__str__(),
Self::RemInt(ins) => ins.__str__(),
Self::AndInt(ins) => ins.__str__(),
Self::OrInt(ins) => ins.__str__(),
Self::XorInt(ins) => ins.__str__(),
Self::ShlInt(ins) => ins.__str__(),
Self::ShrInt(ins) => ins.__str__(),
Self::UshrInt(ins) => ins.__str__(),
Self::AddLong(ins) => ins.__str__(),
Self::SubLong(ins) => ins.__str__(),
Self::MulLong(ins) => ins.__str__(),
Self::DivLong(ins) => ins.__str__(),
Self::RemLong(ins) => ins.__str__(),
Self::AndLong(ins) => ins.__str__(),
Self::OrLong(ins) => ins.__str__(),
Self::XorLong(ins) => ins.__str__(),
Self::ShlLong(ins) => ins.__str__(),
Self::ShrLong(ins) => ins.__str__(),
Self::UshrLong(ins) => ins.__str__(),
Self::AddFloat(ins) => ins.__str__(),
Self::SubFloat(ins) => ins.__str__(),
Self::MulFloat(ins) => ins.__str__(),
Self::DivFloat(ins) => ins.__str__(),
Self::RemFloat(ins) => ins.__str__(),
Self::AddDouble(ins) => ins.__str__(),
Self::SubDouble(ins) => ins.__str__(),
Self::MulDouble(ins) => ins.__str__(),
Self::DivDouble(ins) => ins.__str__(),
Self::RemDouble(ins) => ins.__str__(),
Self::AddInt2Addr(ins) => ins.__str__(),
Self::SubInt2Addr(ins) => ins.__str__(),
Self::MulInt2Addr(ins) => ins.__str__(),
Self::DivInt2Addr(ins) => ins.__str__(),
Self::RemInt2Addr(ins) => ins.__str__(),
Self::AndInt2Addr(ins) => ins.__str__(),
Self::OrInt2Addr(ins) => ins.__str__(),
Self::XorInt2Addr(ins) => ins.__str__(),
Self::ShlInt2Addr(ins) => ins.__str__(),
Self::ShrInt2Addr(ins) => ins.__str__(),
Self::UshrInt2Addr(ins) => ins.__str__(),
Self::AddLong2Addr(ins) => ins.__str__(),
Self::SubLong2Addr(ins) => ins.__str__(),
Self::MulLong2Addr(ins) => ins.__str__(),
Self::DivLong2Addr(ins) => ins.__str__(),
Self::RemLong2Addr(ins) => ins.__str__(),
Self::AndLong2Addr(ins) => ins.__str__(),
Self::OrLong2Addr(ins) => ins.__str__(),
Self::XorLong2Addr(ins) => ins.__str__(),
Self::ShlLong2Addr(ins) => ins.__str__(),
Self::ShrLong2Addr(ins) => ins.__str__(),
Self::UshrLong2Addr(ins) => ins.__str__(),
Self::AddFloat2Addr(ins) => ins.__str__(),
Self::SubFloat2Addr(ins) => ins.__str__(),
Self::MulFloat2Addr(ins) => ins.__str__(),
Self::DivFloat2Addr(ins) => ins.__str__(),
Self::RemFloat2Addr(ins) => ins.__str__(),
Self::AddDouble2Addr(ins) => ins.__str__(),
Self::SubDouble2Addr(ins) => ins.__str__(),
Self::MulDouble2Addr(ins) => ins.__str__(),
Self::DivDouble2Addr(ins) => ins.__str__(),
Self::RemDouble2Addr(ins) => ins.__str__(),
Self::AddIntLit(ins) => ins.__str__(),
Self::RsubIntLit(ins) => ins.__str__(),
Self::MulIntLit(ins) => ins.__str__(),
Self::DivIntLit(ins) => ins.__str__(),
Self::RemIntLit(ins) => ins.__str__(),
Self::AndIntLit(ins) => ins.__str__(),
Self::OrIntLit(ins) => ins.__str__(),
Self::XorIntLit(ins) => ins.__str__(),
Self::ShlIntLit(ins) => ins.__str__(),
Self::ShrIntLit(ins) => ins.__str__(),
Self::UshrIntLit(ins) => ins.__str__(),
Self::InvokePolymorphic(ins) => ins.__str__(),
Self::InvokeCustom(ins) => ins.__str__(),
Self::ConstMethodHandle(ins) => ins.__str__(),
Self::ConstMethodType(ins) => ins.__str__(),
Self::Try(ins) => ins.__str__(),
Self::Label(ins) => ins.__str__(),
}
}
pub fn __repr__(&self) -> String {
match self {
Self::Nop(ins) => ins.__repr__(),
Self::Move(ins) => ins.__repr__(),
Self::MoveWide(ins) => ins.__repr__(),
Self::MoveObject(ins) => ins.__repr__(),
Self::MoveResult(ins) => ins.__repr__(),
Self::MoveResultWide(ins) => ins.__repr__(),
Self::MoveException(ins) => ins.__repr__(),
Self::MoveResultObject(ins) => ins.__repr__(),
Self::ReturnVoid(ins) => ins.__repr__(),
Self::Return(ins) => ins.__repr__(),
Self::ReturnWide(ins) => ins.__repr__(),
Self::ReturnObject(ins) => ins.__repr__(),
Self::Const(ins) => ins.__repr__(),
Self::ConstWide(ins) => ins.__repr__(),
Self::ConstString(ins) => ins.__repr__(),
Self::ConstClass(ins) => ins.__repr__(),
Self::MonitorEnter(ins) => ins.__repr__(),
Self::MonitorExit(ins) => ins.__repr__(),
Self::CheckCast(ins) => ins.__repr__(),
Self::InstanceOf(ins) => ins.__repr__(),
Self::ArrayLength(ins) => ins.__repr__(),
Self::NewInstance(ins) => ins.__repr__(),
Self::NewArray(ins) => ins.__repr__(),
Self::FilledNewArray(ins) => ins.__repr__(),
Self::FillArrayData(ins) => ins.__repr__(),
Self::Throw(ins) => ins.__repr__(),
Self::Goto(ins) => ins.__repr__(),
Self::Switch(ins) => ins.__repr__(),
Self::CmpLFloat(ins) => ins.__repr__(),
Self::CmpGFloat(ins) => ins.__repr__(),
Self::CmpLDouble(ins) => ins.__repr__(),
Self::CmpGDouble(ins) => ins.__repr__(),
Self::CmpLong(ins) => ins.__repr__(),
Self::IfEq(ins) => ins.__repr__(),
Self::IfNe(ins) => ins.__repr__(),
Self::IfLt(ins) => ins.__repr__(),
Self::IfGe(ins) => ins.__repr__(),
Self::IfGt(ins) => ins.__repr__(),
Self::IfLe(ins) => ins.__repr__(),
Self::IfEqZ(ins) => ins.__repr__(),
Self::IfNeZ(ins) => ins.__repr__(),
Self::IfLtZ(ins) => ins.__repr__(),
Self::IfGeZ(ins) => ins.__repr__(),
Self::IfGtZ(ins) => ins.__repr__(),
Self::IfLeZ(ins) => ins.__repr__(),
Self::AGet(ins) => ins.__repr__(),
Self::AGetWide(ins) => ins.__repr__(),
Self::AGetObject(ins) => ins.__repr__(),
Self::AGetBoolean(ins) => ins.__repr__(),
Self::AGetByte(ins) => ins.__repr__(),
Self::AGetChar(ins) => ins.__repr__(),
Self::AGetShort(ins) => ins.__repr__(),
Self::APut(ins) => ins.__repr__(),
Self::APutWide(ins) => ins.__repr__(),
Self::APutObject(ins) => ins.__repr__(),
Self::APutBoolean(ins) => ins.__repr__(),
Self::APutByte(ins) => ins.__repr__(),
Self::APutChar(ins) => ins.__repr__(),
Self::APutShort(ins) => ins.__repr__(),
Self::IGet(ins) => ins.__repr__(),
Self::IGetWide(ins) => ins.__repr__(),
Self::IGetObject(ins) => ins.__repr__(),
Self::IGetBoolean(ins) => ins.__repr__(),
Self::IGetByte(ins) => ins.__repr__(),
Self::IGetChar(ins) => ins.__repr__(),
Self::IGetShort(ins) => ins.__repr__(),
Self::IPut(ins) => ins.__repr__(),
Self::IPutWide(ins) => ins.__repr__(),
Self::IPutObject(ins) => ins.__repr__(),
Self::IPutBoolean(ins) => ins.__repr__(),
Self::IPutByte(ins) => ins.__repr__(),
Self::IPutChar(ins) => ins.__repr__(),
Self::IPutShort(ins) => ins.__repr__(),
Self::SGet(ins) => ins.__repr__(),
Self::SGetWide(ins) => ins.__repr__(),
Self::SGetObject(ins) => ins.__repr__(),
Self::SGetBoolean(ins) => ins.__repr__(),
Self::SGetByte(ins) => ins.__repr__(),
Self::SGetChar(ins) => ins.__repr__(),
Self::SGetShort(ins) => ins.__repr__(),
Self::SPut(ins) => ins.__repr__(),
Self::SPutWide(ins) => ins.__repr__(),
Self::SPutObject(ins) => ins.__repr__(),
Self::SPutBoolean(ins) => ins.__repr__(),
Self::SPutByte(ins) => ins.__repr__(),
Self::SPutChar(ins) => ins.__repr__(),
Self::SPutShort(ins) => ins.__repr__(),
Self::InvokeVirtual(ins) => ins.__repr__(),
Self::InvokeSuper(ins) => ins.__repr__(),
Self::InvokeDirect(ins) => ins.__repr__(),
Self::InvokeStatic(ins) => ins.__repr__(),
Self::InvokeInterface(ins) => ins.__repr__(),
Self::NegInt(ins) => ins.__repr__(),
Self::NotInt(ins) => ins.__repr__(),
Self::NegLong(ins) => ins.__repr__(),
Self::NotLong(ins) => ins.__repr__(),
Self::NegFloat(ins) => ins.__repr__(),
Self::NegDouble(ins) => ins.__repr__(),
Self::IntToLong(ins) => ins.__repr__(),
Self::IntToFloat(ins) => ins.__repr__(),
Self::IntToDouble(ins) => ins.__repr__(),
Self::LongToInt(ins) => ins.__repr__(),
Self::LongToFloat(ins) => ins.__repr__(),
Self::LongToDouble(ins) => ins.__repr__(),
Self::FloatToInt(ins) => ins.__repr__(),
Self::FloatToLong(ins) => ins.__repr__(),
Self::FloatToDouble(ins) => ins.__repr__(),
Self::DoubleToInt(ins) => ins.__repr__(),
Self::DoubleToLong(ins) => ins.__repr__(),
Self::DoubleToFloat(ins) => ins.__repr__(),
Self::IntToByte(ins) => ins.__repr__(),
Self::IntToChar(ins) => ins.__repr__(),
Self::IntToShort(ins) => ins.__repr__(),
Self::AddInt(ins) => ins.__repr__(),
Self::SubInt(ins) => ins.__repr__(),
Self::MulInt(ins) => ins.__repr__(),
Self::DivInt(ins) => ins.__repr__(),
Self::RemInt(ins) => ins.__repr__(),
Self::AndInt(ins) => ins.__repr__(),
Self::OrInt(ins) => ins.__repr__(),
Self::XorInt(ins) => ins.__repr__(),
Self::ShlInt(ins) => ins.__repr__(),
Self::ShrInt(ins) => ins.__repr__(),
Self::UshrInt(ins) => ins.__repr__(),
Self::AddLong(ins) => ins.__repr__(),
Self::SubLong(ins) => ins.__repr__(),
Self::MulLong(ins) => ins.__repr__(),
Self::DivLong(ins) => ins.__repr__(),
Self::RemLong(ins) => ins.__repr__(),
Self::AndLong(ins) => ins.__repr__(),
Self::OrLong(ins) => ins.__repr__(),
Self::XorLong(ins) => ins.__repr__(),
Self::ShlLong(ins) => ins.__repr__(),
Self::ShrLong(ins) => ins.__repr__(),
Self::UshrLong(ins) => ins.__repr__(),
Self::AddFloat(ins) => ins.__repr__(),
Self::SubFloat(ins) => ins.__repr__(),
Self::MulFloat(ins) => ins.__repr__(),
Self::DivFloat(ins) => ins.__repr__(),
Self::RemFloat(ins) => ins.__repr__(),
Self::AddDouble(ins) => ins.__repr__(),
Self::SubDouble(ins) => ins.__repr__(),
Self::MulDouble(ins) => ins.__repr__(),
Self::DivDouble(ins) => ins.__repr__(),
Self::RemDouble(ins) => ins.__repr__(),
Self::AddInt2Addr(ins) => ins.__repr__(),
Self::SubInt2Addr(ins) => ins.__repr__(),
Self::MulInt2Addr(ins) => ins.__repr__(),
Self::DivInt2Addr(ins) => ins.__repr__(),
Self::RemInt2Addr(ins) => ins.__repr__(),
Self::AndInt2Addr(ins) => ins.__repr__(),
Self::OrInt2Addr(ins) => ins.__repr__(),
Self::XorInt2Addr(ins) => ins.__repr__(),
Self::ShlInt2Addr(ins) => ins.__repr__(),
Self::ShrInt2Addr(ins) => ins.__repr__(),
Self::UshrInt2Addr(ins) => ins.__repr__(),
Self::AddLong2Addr(ins) => ins.__repr__(),
Self::SubLong2Addr(ins) => ins.__repr__(),
Self::MulLong2Addr(ins) => ins.__repr__(),
Self::DivLong2Addr(ins) => ins.__repr__(),
Self::RemLong2Addr(ins) => ins.__repr__(),
Self::AndLong2Addr(ins) => ins.__repr__(),
Self::OrLong2Addr(ins) => ins.__repr__(),
Self::XorLong2Addr(ins) => ins.__repr__(),
Self::ShlLong2Addr(ins) => ins.__repr__(),
Self::ShrLong2Addr(ins) => ins.__repr__(),
Self::UshrLong2Addr(ins) => ins.__repr__(),
Self::AddFloat2Addr(ins) => ins.__repr__(),
Self::SubFloat2Addr(ins) => ins.__repr__(),
Self::MulFloat2Addr(ins) => ins.__repr__(),
Self::DivFloat2Addr(ins) => ins.__repr__(),
Self::RemFloat2Addr(ins) => ins.__repr__(),
Self::AddDouble2Addr(ins) => ins.__repr__(),
Self::SubDouble2Addr(ins) => ins.__repr__(),
Self::MulDouble2Addr(ins) => ins.__repr__(),
Self::DivDouble2Addr(ins) => ins.__repr__(),
Self::RemDouble2Addr(ins) => ins.__repr__(),
Self::AddIntLit(ins) => ins.__repr__(),
Self::RsubIntLit(ins) => ins.__repr__(),
Self::MulIntLit(ins) => ins.__repr__(),
Self::DivIntLit(ins) => ins.__repr__(),
Self::RemIntLit(ins) => ins.__repr__(),
Self::AndIntLit(ins) => ins.__repr__(),
Self::OrIntLit(ins) => ins.__repr__(),
Self::XorIntLit(ins) => ins.__repr__(),
Self::ShlIntLit(ins) => ins.__repr__(),
Self::ShrIntLit(ins) => ins.__repr__(),
Self::UshrIntLit(ins) => ins.__repr__(),
Self::InvokePolymorphic(ins) => ins.__repr__(),
Self::InvokeCustom(ins) => ins.__repr__(),
Self::ConstMethodHandle(ins) => ins.__repr__(),
Self::ConstMethodType(ins) => ins.__repr__(),
Self::Try(ins) => ins.__repr__(),
Self::Label(ins) => ins.__repr__(),
}
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
match self {
Self::Nop(ins) => ins.min_ins_size(),
Self::Move(ins) => ins.min_ins_size(),
Self::MoveWide(ins) => ins.min_ins_size(),
Self::MoveObject(ins) => ins.min_ins_size(),
Self::MoveResult(ins) => ins.min_ins_size(),
Self::MoveResultWide(ins) => ins.min_ins_size(),
Self::MoveException(ins) => ins.min_ins_size(),
Self::MoveResultObject(ins) => ins.min_ins_size(),
Self::ReturnVoid(ins) => ins.min_ins_size(),
Self::Return(ins) => ins.min_ins_size(),
Self::ReturnWide(ins) => ins.min_ins_size(),
Self::ReturnObject(ins) => ins.min_ins_size(),
Self::Const(ins) => ins.min_ins_size(),
Self::ConstWide(ins) => ins.min_ins_size(),
Self::ConstString(ins) => ins.min_ins_size(),
Self::ConstClass(ins) => ins.min_ins_size(),
Self::MonitorEnter(ins) => ins.min_ins_size(),
Self::MonitorExit(ins) => ins.min_ins_size(),
Self::CheckCast(ins) => ins.min_ins_size(),
Self::InstanceOf(ins) => ins.min_ins_size(),
Self::ArrayLength(ins) => ins.min_ins_size(),
Self::NewInstance(ins) => ins.min_ins_size(),
Self::NewArray(ins) => ins.min_ins_size(),
Self::FilledNewArray(ins) => ins.min_ins_size(),
Self::FillArrayData(ins) => ins.min_ins_size(),
Self::Throw(ins) => ins.min_ins_size(),
Self::Goto(ins) => ins.min_ins_size(),
Self::Switch(ins) => ins.min_ins_size(),
Self::CmpLFloat(ins) => ins.min_ins_size(),
Self::CmpGFloat(ins) => ins.min_ins_size(),
Self::CmpLDouble(ins) => ins.min_ins_size(),
Self::CmpGDouble(ins) => ins.min_ins_size(),
Self::CmpLong(ins) => ins.min_ins_size(),
Self::IfEq(ins) => ins.min_ins_size(),
Self::IfNe(ins) => ins.min_ins_size(),
Self::IfLt(ins) => ins.min_ins_size(),
Self::IfGe(ins) => ins.min_ins_size(),
Self::IfGt(ins) => ins.min_ins_size(),
Self::IfLe(ins) => ins.min_ins_size(),
Self::IfEqZ(ins) => ins.min_ins_size(),
Self::IfNeZ(ins) => ins.min_ins_size(),
Self::IfLtZ(ins) => ins.min_ins_size(),
Self::IfGeZ(ins) => ins.min_ins_size(),
Self::IfGtZ(ins) => ins.min_ins_size(),
Self::IfLeZ(ins) => ins.min_ins_size(),
Self::AGet(ins) => ins.min_ins_size(),
Self::AGetWide(ins) => ins.min_ins_size(),
Self::AGetObject(ins) => ins.min_ins_size(),
Self::AGetBoolean(ins) => ins.min_ins_size(),
Self::AGetByte(ins) => ins.min_ins_size(),
Self::AGetChar(ins) => ins.min_ins_size(),
Self::AGetShort(ins) => ins.min_ins_size(),
Self::APut(ins) => ins.min_ins_size(),
Self::APutWide(ins) => ins.min_ins_size(),
Self::APutObject(ins) => ins.min_ins_size(),
Self::APutBoolean(ins) => ins.min_ins_size(),
Self::APutByte(ins) => ins.min_ins_size(),
Self::APutChar(ins) => ins.min_ins_size(),
Self::APutShort(ins) => ins.min_ins_size(),
Self::IGet(ins) => ins.min_ins_size(),
Self::IGetWide(ins) => ins.min_ins_size(),
Self::IGetObject(ins) => ins.min_ins_size(),
Self::IGetBoolean(ins) => ins.min_ins_size(),
Self::IGetByte(ins) => ins.min_ins_size(),
Self::IGetChar(ins) => ins.min_ins_size(),
Self::IGetShort(ins) => ins.min_ins_size(),
Self::IPut(ins) => ins.min_ins_size(),
Self::IPutWide(ins) => ins.min_ins_size(),
Self::IPutObject(ins) => ins.min_ins_size(),
Self::IPutBoolean(ins) => ins.min_ins_size(),
Self::IPutByte(ins) => ins.min_ins_size(),
Self::IPutChar(ins) => ins.min_ins_size(),
Self::IPutShort(ins) => ins.min_ins_size(),
Self::SGet(ins) => ins.min_ins_size(),
Self::SGetWide(ins) => ins.min_ins_size(),
Self::SGetObject(ins) => ins.min_ins_size(),
Self::SGetBoolean(ins) => ins.min_ins_size(),
Self::SGetByte(ins) => ins.min_ins_size(),
Self::SGetChar(ins) => ins.min_ins_size(),
Self::SGetShort(ins) => ins.min_ins_size(),
Self::SPut(ins) => ins.min_ins_size(),
Self::SPutWide(ins) => ins.min_ins_size(),
Self::SPutObject(ins) => ins.min_ins_size(),
Self::SPutBoolean(ins) => ins.min_ins_size(),
Self::SPutByte(ins) => ins.min_ins_size(),
Self::SPutChar(ins) => ins.min_ins_size(),
Self::SPutShort(ins) => ins.min_ins_size(),
Self::InvokeVirtual(ins) => ins.min_ins_size(),
Self::InvokeSuper(ins) => ins.min_ins_size(),
Self::InvokeDirect(ins) => ins.min_ins_size(),
Self::InvokeStatic(ins) => ins.min_ins_size(),
Self::InvokeInterface(ins) => ins.min_ins_size(),
Self::NegInt(ins) => ins.min_ins_size(),
Self::NotInt(ins) => ins.min_ins_size(),
Self::NegLong(ins) => ins.min_ins_size(),
Self::NotLong(ins) => ins.min_ins_size(),
Self::NegFloat(ins) => ins.min_ins_size(),
Self::NegDouble(ins) => ins.min_ins_size(),
Self::IntToLong(ins) => ins.min_ins_size(),
Self::IntToFloat(ins) => ins.min_ins_size(),
Self::IntToDouble(ins) => ins.min_ins_size(),
Self::LongToInt(ins) => ins.min_ins_size(),
Self::LongToFloat(ins) => ins.min_ins_size(),
Self::LongToDouble(ins) => ins.min_ins_size(),
Self::FloatToInt(ins) => ins.min_ins_size(),
Self::FloatToLong(ins) => ins.min_ins_size(),
Self::FloatToDouble(ins) => ins.min_ins_size(),
Self::DoubleToInt(ins) => ins.min_ins_size(),
Self::DoubleToLong(ins) => ins.min_ins_size(),
Self::DoubleToFloat(ins) => ins.min_ins_size(),
Self::IntToByte(ins) => ins.min_ins_size(),
Self::IntToChar(ins) => ins.min_ins_size(),
Self::IntToShort(ins) => ins.min_ins_size(),
Self::AddInt(ins) => ins.min_ins_size(),
Self::SubInt(ins) => ins.min_ins_size(),
Self::MulInt(ins) => ins.min_ins_size(),
Self::DivInt(ins) => ins.min_ins_size(),
Self::RemInt(ins) => ins.min_ins_size(),
Self::AndInt(ins) => ins.min_ins_size(),
Self::OrInt(ins) => ins.min_ins_size(),
Self::XorInt(ins) => ins.min_ins_size(),
Self::ShlInt(ins) => ins.min_ins_size(),
Self::ShrInt(ins) => ins.min_ins_size(),
Self::UshrInt(ins) => ins.min_ins_size(),
Self::AddLong(ins) => ins.min_ins_size(),
Self::SubLong(ins) => ins.min_ins_size(),
Self::MulLong(ins) => ins.min_ins_size(),
Self::DivLong(ins) => ins.min_ins_size(),
Self::RemLong(ins) => ins.min_ins_size(),
Self::AndLong(ins) => ins.min_ins_size(),
Self::OrLong(ins) => ins.min_ins_size(),
Self::XorLong(ins) => ins.min_ins_size(),
Self::ShlLong(ins) => ins.min_ins_size(),
Self::ShrLong(ins) => ins.min_ins_size(),
Self::UshrLong(ins) => ins.min_ins_size(),
Self::AddFloat(ins) => ins.min_ins_size(),
Self::SubFloat(ins) => ins.min_ins_size(),
Self::MulFloat(ins) => ins.min_ins_size(),
Self::DivFloat(ins) => ins.min_ins_size(),
Self::RemFloat(ins) => ins.min_ins_size(),
Self::AddDouble(ins) => ins.min_ins_size(),
Self::SubDouble(ins) => ins.min_ins_size(),
Self::MulDouble(ins) => ins.min_ins_size(),
Self::DivDouble(ins) => ins.min_ins_size(),
Self::RemDouble(ins) => ins.min_ins_size(),
Self::AddInt2Addr(ins) => ins.min_ins_size(),
Self::SubInt2Addr(ins) => ins.min_ins_size(),
Self::MulInt2Addr(ins) => ins.min_ins_size(),
Self::DivInt2Addr(ins) => ins.min_ins_size(),
Self::RemInt2Addr(ins) => ins.min_ins_size(),
Self::AndInt2Addr(ins) => ins.min_ins_size(),
Self::OrInt2Addr(ins) => ins.min_ins_size(),
Self::XorInt2Addr(ins) => ins.min_ins_size(),
Self::ShlInt2Addr(ins) => ins.min_ins_size(),
Self::ShrInt2Addr(ins) => ins.min_ins_size(),
Self::UshrInt2Addr(ins) => ins.min_ins_size(),
Self::AddLong2Addr(ins) => ins.min_ins_size(),
Self::SubLong2Addr(ins) => ins.min_ins_size(),
Self::MulLong2Addr(ins) => ins.min_ins_size(),
Self::DivLong2Addr(ins) => ins.min_ins_size(),
Self::RemLong2Addr(ins) => ins.min_ins_size(),
Self::AndLong2Addr(ins) => ins.min_ins_size(),
Self::OrLong2Addr(ins) => ins.min_ins_size(),
Self::XorLong2Addr(ins) => ins.min_ins_size(),
Self::ShlLong2Addr(ins) => ins.min_ins_size(),
Self::ShrLong2Addr(ins) => ins.min_ins_size(),
Self::UshrLong2Addr(ins) => ins.min_ins_size(),
Self::AddFloat2Addr(ins) => ins.min_ins_size(),
Self::SubFloat2Addr(ins) => ins.min_ins_size(),
Self::MulFloat2Addr(ins) => ins.min_ins_size(),
Self::DivFloat2Addr(ins) => ins.min_ins_size(),
Self::RemFloat2Addr(ins) => ins.min_ins_size(),
Self::AddDouble2Addr(ins) => ins.min_ins_size(),
Self::SubDouble2Addr(ins) => ins.min_ins_size(),
Self::MulDouble2Addr(ins) => ins.min_ins_size(),
Self::DivDouble2Addr(ins) => ins.min_ins_size(),
Self::RemDouble2Addr(ins) => ins.min_ins_size(),
Self::AddIntLit(ins) => ins.min_ins_size(),
Self::RsubIntLit(ins) => ins.min_ins_size(),
Self::MulIntLit(ins) => ins.min_ins_size(),
Self::DivIntLit(ins) => ins.min_ins_size(),
Self::RemIntLit(ins) => ins.min_ins_size(),
Self::AndIntLit(ins) => ins.min_ins_size(),
Self::OrIntLit(ins) => ins.min_ins_size(),
Self::XorIntLit(ins) => ins.min_ins_size(),
Self::ShlIntLit(ins) => ins.min_ins_size(),
Self::ShrIntLit(ins) => ins.min_ins_size(),
Self::UshrIntLit(ins) => ins.min_ins_size(),
Self::InvokePolymorphic(ins) => ins.min_ins_size(),
Self::InvokeCustom(ins) => ins.min_ins_size(),
Self::ConstMethodHandle(ins) => ins.min_ins_size(),
Self::ConstMethodType(ins) => ins.min_ins_size(),
Self::Try(ins) => ins.min_ins_size(),
Self::Label(ins) => ins.min_ins_size(),
}
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
match self {
Self::Nop(ins) => ins.max_ins_size(),
Self::Move(ins) => ins.max_ins_size(),
Self::MoveWide(ins) => ins.max_ins_size(),
Self::MoveObject(ins) => ins.max_ins_size(),
Self::MoveResult(ins) => ins.max_ins_size(),
Self::MoveResultWide(ins) => ins.max_ins_size(),
Self::MoveException(ins) => ins.max_ins_size(),
Self::MoveResultObject(ins) => ins.max_ins_size(),
Self::ReturnVoid(ins) => ins.max_ins_size(),
Self::Return(ins) => ins.max_ins_size(),
Self::ReturnWide(ins) => ins.max_ins_size(),
Self::ReturnObject(ins) => ins.max_ins_size(),
Self::Const(ins) => ins.max_ins_size(),
Self::ConstWide(ins) => ins.max_ins_size(),
Self::ConstString(ins) => ins.max_ins_size(),
Self::ConstClass(ins) => ins.max_ins_size(),
Self::MonitorEnter(ins) => ins.max_ins_size(),
Self::MonitorExit(ins) => ins.max_ins_size(),
Self::CheckCast(ins) => ins.max_ins_size(),
Self::InstanceOf(ins) => ins.max_ins_size(),
Self::ArrayLength(ins) => ins.max_ins_size(),
Self::NewInstance(ins) => ins.max_ins_size(),
Self::NewArray(ins) => ins.max_ins_size(),
Self::FilledNewArray(ins) => ins.max_ins_size(),
Self::FillArrayData(ins) => ins.max_ins_size(),
Self::Throw(ins) => ins.max_ins_size(),
Self::Goto(ins) => ins.max_ins_size(),
Self::Switch(ins) => ins.max_ins_size(),
Self::CmpLFloat(ins) => ins.max_ins_size(),
Self::CmpGFloat(ins) => ins.max_ins_size(),
Self::CmpLDouble(ins) => ins.max_ins_size(),
Self::CmpGDouble(ins) => ins.max_ins_size(),
Self::CmpLong(ins) => ins.max_ins_size(),
Self::IfEq(ins) => ins.max_ins_size(),
Self::IfNe(ins) => ins.max_ins_size(),
Self::IfLt(ins) => ins.max_ins_size(),
Self::IfGe(ins) => ins.max_ins_size(),
Self::IfGt(ins) => ins.max_ins_size(),
Self::IfLe(ins) => ins.max_ins_size(),
Self::IfEqZ(ins) => ins.max_ins_size(),
Self::IfNeZ(ins) => ins.max_ins_size(),
Self::IfLtZ(ins) => ins.max_ins_size(),
Self::IfGeZ(ins) => ins.max_ins_size(),
Self::IfGtZ(ins) => ins.max_ins_size(),
Self::IfLeZ(ins) => ins.max_ins_size(),
Self::AGet(ins) => ins.max_ins_size(),
Self::AGetWide(ins) => ins.max_ins_size(),
Self::AGetObject(ins) => ins.max_ins_size(),
Self::AGetBoolean(ins) => ins.max_ins_size(),
Self::AGetByte(ins) => ins.max_ins_size(),
Self::AGetChar(ins) => ins.max_ins_size(),
Self::AGetShort(ins) => ins.max_ins_size(),
Self::APut(ins) => ins.max_ins_size(),
Self::APutWide(ins) => ins.max_ins_size(),
Self::APutObject(ins) => ins.max_ins_size(),
Self::APutBoolean(ins) => ins.max_ins_size(),
Self::APutByte(ins) => ins.max_ins_size(),
Self::APutChar(ins) => ins.max_ins_size(),
Self::APutShort(ins) => ins.max_ins_size(),
Self::IGet(ins) => ins.max_ins_size(),
Self::IGetWide(ins) => ins.max_ins_size(),
Self::IGetObject(ins) => ins.max_ins_size(),
Self::IGetBoolean(ins) => ins.max_ins_size(),
Self::IGetByte(ins) => ins.max_ins_size(),
Self::IGetChar(ins) => ins.max_ins_size(),
Self::IGetShort(ins) => ins.max_ins_size(),
Self::IPut(ins) => ins.max_ins_size(),
Self::IPutWide(ins) => ins.max_ins_size(),
Self::IPutObject(ins) => ins.max_ins_size(),
Self::IPutBoolean(ins) => ins.max_ins_size(),
Self::IPutByte(ins) => ins.max_ins_size(),
Self::IPutChar(ins) => ins.max_ins_size(),
Self::IPutShort(ins) => ins.max_ins_size(),
Self::SGet(ins) => ins.max_ins_size(),
Self::SGetWide(ins) => ins.max_ins_size(),
Self::SGetObject(ins) => ins.max_ins_size(),
Self::SGetBoolean(ins) => ins.max_ins_size(),
Self::SGetByte(ins) => ins.max_ins_size(),
Self::SGetChar(ins) => ins.max_ins_size(),
Self::SGetShort(ins) => ins.max_ins_size(),
Self::SPut(ins) => ins.max_ins_size(),
Self::SPutWide(ins) => ins.max_ins_size(),
Self::SPutObject(ins) => ins.max_ins_size(),
Self::SPutBoolean(ins) => ins.max_ins_size(),
Self::SPutByte(ins) => ins.max_ins_size(),
Self::SPutChar(ins) => ins.max_ins_size(),
Self::SPutShort(ins) => ins.max_ins_size(),
Self::InvokeVirtual(ins) => ins.max_ins_size(),
Self::InvokeSuper(ins) => ins.max_ins_size(),
Self::InvokeDirect(ins) => ins.max_ins_size(),
Self::InvokeStatic(ins) => ins.max_ins_size(),
Self::InvokeInterface(ins) => ins.max_ins_size(),
Self::NegInt(ins) => ins.max_ins_size(),
Self::NotInt(ins) => ins.max_ins_size(),
Self::NegLong(ins) => ins.max_ins_size(),
Self::NotLong(ins) => ins.max_ins_size(),
Self::NegFloat(ins) => ins.max_ins_size(),
Self::NegDouble(ins) => ins.max_ins_size(),
Self::IntToLong(ins) => ins.max_ins_size(),
Self::IntToFloat(ins) => ins.max_ins_size(),
Self::IntToDouble(ins) => ins.max_ins_size(),
Self::LongToInt(ins) => ins.max_ins_size(),
Self::LongToFloat(ins) => ins.max_ins_size(),
Self::LongToDouble(ins) => ins.max_ins_size(),
Self::FloatToInt(ins) => ins.max_ins_size(),
Self::FloatToLong(ins) => ins.max_ins_size(),
Self::FloatToDouble(ins) => ins.max_ins_size(),
Self::DoubleToInt(ins) => ins.max_ins_size(),
Self::DoubleToLong(ins) => ins.max_ins_size(),
Self::DoubleToFloat(ins) => ins.max_ins_size(),
Self::IntToByte(ins) => ins.max_ins_size(),
Self::IntToChar(ins) => ins.max_ins_size(),
Self::IntToShort(ins) => ins.max_ins_size(),
Self::AddInt(ins) => ins.max_ins_size(),
Self::SubInt(ins) => ins.max_ins_size(),
Self::MulInt(ins) => ins.max_ins_size(),
Self::DivInt(ins) => ins.max_ins_size(),
Self::RemInt(ins) => ins.max_ins_size(),
Self::AndInt(ins) => ins.max_ins_size(),
Self::OrInt(ins) => ins.max_ins_size(),
Self::XorInt(ins) => ins.max_ins_size(),
Self::ShlInt(ins) => ins.max_ins_size(),
Self::ShrInt(ins) => ins.max_ins_size(),
Self::UshrInt(ins) => ins.max_ins_size(),
Self::AddLong(ins) => ins.max_ins_size(),
Self::SubLong(ins) => ins.max_ins_size(),
Self::MulLong(ins) => ins.max_ins_size(),
Self::DivLong(ins) => ins.max_ins_size(),
Self::RemLong(ins) => ins.max_ins_size(),
Self::AndLong(ins) => ins.max_ins_size(),
Self::OrLong(ins) => ins.max_ins_size(),
Self::XorLong(ins) => ins.max_ins_size(),
Self::ShlLong(ins) => ins.max_ins_size(),
Self::ShrLong(ins) => ins.max_ins_size(),
Self::UshrLong(ins) => ins.max_ins_size(),
Self::AddFloat(ins) => ins.max_ins_size(),
Self::SubFloat(ins) => ins.max_ins_size(),
Self::MulFloat(ins) => ins.max_ins_size(),
Self::DivFloat(ins) => ins.max_ins_size(),
Self::RemFloat(ins) => ins.max_ins_size(),
Self::AddDouble(ins) => ins.max_ins_size(),
Self::SubDouble(ins) => ins.max_ins_size(),
Self::MulDouble(ins) => ins.max_ins_size(),
Self::DivDouble(ins) => ins.max_ins_size(),
Self::RemDouble(ins) => ins.max_ins_size(),
Self::AddInt2Addr(ins) => ins.max_ins_size(),
Self::SubInt2Addr(ins) => ins.max_ins_size(),
Self::MulInt2Addr(ins) => ins.max_ins_size(),
Self::DivInt2Addr(ins) => ins.max_ins_size(),
Self::RemInt2Addr(ins) => ins.max_ins_size(),
Self::AndInt2Addr(ins) => ins.max_ins_size(),
Self::OrInt2Addr(ins) => ins.max_ins_size(),
Self::XorInt2Addr(ins) => ins.max_ins_size(),
Self::ShlInt2Addr(ins) => ins.max_ins_size(),
Self::ShrInt2Addr(ins) => ins.max_ins_size(),
Self::UshrInt2Addr(ins) => ins.max_ins_size(),
Self::AddLong2Addr(ins) => ins.max_ins_size(),
Self::SubLong2Addr(ins) => ins.max_ins_size(),
Self::MulLong2Addr(ins) => ins.max_ins_size(),
Self::DivLong2Addr(ins) => ins.max_ins_size(),
Self::RemLong2Addr(ins) => ins.max_ins_size(),
Self::AndLong2Addr(ins) => ins.max_ins_size(),
Self::OrLong2Addr(ins) => ins.max_ins_size(),
Self::XorLong2Addr(ins) => ins.max_ins_size(),
Self::ShlLong2Addr(ins) => ins.max_ins_size(),
Self::ShrLong2Addr(ins) => ins.max_ins_size(),
Self::UshrLong2Addr(ins) => ins.max_ins_size(),
Self::AddFloat2Addr(ins) => ins.max_ins_size(),
Self::SubFloat2Addr(ins) => ins.max_ins_size(),
Self::MulFloat2Addr(ins) => ins.max_ins_size(),
Self::DivFloat2Addr(ins) => ins.max_ins_size(),
Self::RemFloat2Addr(ins) => ins.max_ins_size(),
Self::AddDouble2Addr(ins) => ins.max_ins_size(),
Self::SubDouble2Addr(ins) => ins.max_ins_size(),
Self::MulDouble2Addr(ins) => ins.max_ins_size(),
Self::DivDouble2Addr(ins) => ins.max_ins_size(),
Self::RemDouble2Addr(ins) => ins.max_ins_size(),
Self::AddIntLit(ins) => ins.max_ins_size(),
Self::RsubIntLit(ins) => ins.max_ins_size(),
Self::MulIntLit(ins) => ins.max_ins_size(),
Self::DivIntLit(ins) => ins.max_ins_size(),
Self::RemIntLit(ins) => ins.max_ins_size(),
Self::AndIntLit(ins) => ins.max_ins_size(),
Self::OrIntLit(ins) => ins.max_ins_size(),
Self::XorIntLit(ins) => ins.max_ins_size(),
Self::ShlIntLit(ins) => ins.max_ins_size(),
Self::ShrIntLit(ins) => ins.max_ins_size(),
Self::UshrIntLit(ins) => ins.max_ins_size(),
Self::InvokePolymorphic(ins) => ins.max_ins_size(),
Self::InvokeCustom(ins) => ins.max_ins_size(),
Self::ConstMethodHandle(ins) => ins.max_ins_size(),
Self::ConstMethodType(ins) => ins.max_ins_size(),
Self::Try(ins) => ins.max_ins_size(),
Self::Label(ins) => ins.max_ins_size(),
}
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> Result<usize> {
match self {
Self::Nop(ins) => Ok(ins.ins_size()),
Self::Move(ins) => Ok(ins.ins_size()),
Self::MoveWide(ins) => Ok(ins.ins_size()),
Self::MoveObject(ins) => Ok(ins.ins_size()),
Self::MoveResult(ins) => Ok(ins.ins_size()),
Self::MoveResultWide(ins) => Ok(ins.ins_size()),
Self::MoveException(ins) => Ok(ins.ins_size()),
Self::MoveResultObject(ins) => Ok(ins.ins_size()),
Self::ReturnVoid(ins) => Ok(ins.ins_size()),
Self::Return(ins) => Ok(ins.ins_size()),
Self::ReturnWide(ins) => Ok(ins.ins_size()),
Self::ReturnObject(ins) => Ok(ins.ins_size()),
Self::Const(ins) => Ok(ins.ins_size()),
Self::ConstWide(ins) => Ok(ins.ins_size()),
Self::ConstString(_) => Err(anyhow!(
"Cannot get the size of a const-string size without knowing the string idx"
)),
Self::ConstClass(ins) => Ok(ins.ins_size()),
Self::MonitorEnter(ins) => Ok(ins.ins_size()),
Self::MonitorExit(ins) => Ok(ins.ins_size()),
Self::CheckCast(ins) => Ok(ins.ins_size()),
Self::InstanceOf(ins) => Ok(ins.ins_size()),
Self::ArrayLength(ins) => Ok(ins.ins_size()),
Self::NewInstance(ins) => Ok(ins.ins_size()),
Self::NewArray(ins) => Ok(ins.ins_size()),
Self::FilledNewArray(ins) => Ok(ins.ins_size()),
Self::FillArrayData(ins) => Ok(ins.ins_size()),
Self::Throw(ins) => Ok(ins.ins_size()),
Self::Goto(_) => Err(anyhow!(
"Cannot get the size of a goto without knowing the branch offset"
)),
Self::Switch(ins) => Ok(ins.ins_size()),
Self::CmpLFloat(ins) => Ok(ins.ins_size()),
Self::CmpGFloat(ins) => Ok(ins.ins_size()),
Self::CmpLDouble(ins) => Ok(ins.ins_size()),
Self::CmpGDouble(ins) => Ok(ins.ins_size()),
Self::CmpLong(ins) => Ok(ins.ins_size()),
Self::IfEq(ins) => Ok(ins.ins_size()),
Self::IfNe(ins) => Ok(ins.ins_size()),
Self::IfLt(ins) => Ok(ins.ins_size()),
Self::IfGe(ins) => Ok(ins.ins_size()),
Self::IfGt(ins) => Ok(ins.ins_size()),
Self::IfLe(ins) => Ok(ins.ins_size()),
Self::IfEqZ(ins) => Ok(ins.ins_size()),
Self::IfNeZ(ins) => Ok(ins.ins_size()),
Self::IfLtZ(ins) => Ok(ins.ins_size()),
Self::IfGeZ(ins) => Ok(ins.ins_size()),
Self::IfGtZ(ins) => Ok(ins.ins_size()),
Self::IfLeZ(ins) => Ok(ins.ins_size()),
Self::AGet(ins) => Ok(ins.ins_size()),
Self::AGetWide(ins) => Ok(ins.ins_size()),
Self::AGetObject(ins) => Ok(ins.ins_size()),
Self::AGetBoolean(ins) => Ok(ins.ins_size()),
Self::AGetByte(ins) => Ok(ins.ins_size()),
Self::AGetChar(ins) => Ok(ins.ins_size()),
Self::AGetShort(ins) => Ok(ins.ins_size()),
Self::APut(ins) => Ok(ins.ins_size()),
Self::APutWide(ins) => Ok(ins.ins_size()),
Self::APutObject(ins) => Ok(ins.ins_size()),
Self::APutBoolean(ins) => Ok(ins.ins_size()),
Self::APutByte(ins) => Ok(ins.ins_size()),
Self::APutChar(ins) => Ok(ins.ins_size()),
Self::APutShort(ins) => Ok(ins.ins_size()),
Self::IGet(ins) => Ok(ins.ins_size()),
Self::IGetWide(ins) => Ok(ins.ins_size()),
Self::IGetObject(ins) => Ok(ins.ins_size()),
Self::IGetBoolean(ins) => Ok(ins.ins_size()),
Self::IGetByte(ins) => Ok(ins.ins_size()),
Self::IGetChar(ins) => Ok(ins.ins_size()),
Self::IGetShort(ins) => Ok(ins.ins_size()),
Self::IPut(ins) => Ok(ins.ins_size()),
Self::IPutWide(ins) => Ok(ins.ins_size()),
Self::IPutObject(ins) => Ok(ins.ins_size()),
Self::IPutBoolean(ins) => Ok(ins.ins_size()),
Self::IPutByte(ins) => Ok(ins.ins_size()),
Self::IPutChar(ins) => Ok(ins.ins_size()),
Self::IPutShort(ins) => Ok(ins.ins_size()),
Self::SGet(ins) => Ok(ins.ins_size()),
Self::SGetWide(ins) => Ok(ins.ins_size()),
Self::SGetObject(ins) => Ok(ins.ins_size()),
Self::SGetBoolean(ins) => Ok(ins.ins_size()),
Self::SGetByte(ins) => Ok(ins.ins_size()),
Self::SGetChar(ins) => Ok(ins.ins_size()),
Self::SGetShort(ins) => Ok(ins.ins_size()),
Self::SPut(ins) => Ok(ins.ins_size()),
Self::SPutWide(ins) => Ok(ins.ins_size()),
Self::SPutObject(ins) => Ok(ins.ins_size()),
Self::SPutBoolean(ins) => Ok(ins.ins_size()),
Self::SPutByte(ins) => Ok(ins.ins_size()),
Self::SPutChar(ins) => Ok(ins.ins_size()),
Self::SPutShort(ins) => Ok(ins.ins_size()),
Self::InvokeVirtual(ins) => Ok(ins.ins_size()),
Self::InvokeSuper(ins) => Ok(ins.ins_size()),
Self::InvokeDirect(ins) => Ok(ins.ins_size()),
Self::InvokeStatic(ins) => Ok(ins.ins_size()),
Self::InvokeInterface(ins) => Ok(ins.ins_size()),
Self::NegInt(ins) => Ok(ins.ins_size()),
Self::NotInt(ins) => Ok(ins.ins_size()),
Self::NegLong(ins) => Ok(ins.ins_size()),
Self::NotLong(ins) => Ok(ins.ins_size()),
Self::NegFloat(ins) => Ok(ins.ins_size()),
Self::NegDouble(ins) => Ok(ins.ins_size()),
Self::IntToLong(ins) => Ok(ins.ins_size()),
Self::IntToFloat(ins) => Ok(ins.ins_size()),
Self::IntToDouble(ins) => Ok(ins.ins_size()),
Self::LongToInt(ins) => Ok(ins.ins_size()),
Self::LongToFloat(ins) => Ok(ins.ins_size()),
Self::LongToDouble(ins) => Ok(ins.ins_size()),
Self::FloatToInt(ins) => Ok(ins.ins_size()),
Self::FloatToLong(ins) => Ok(ins.ins_size()),
Self::FloatToDouble(ins) => Ok(ins.ins_size()),
Self::DoubleToInt(ins) => Ok(ins.ins_size()),
Self::DoubleToLong(ins) => Ok(ins.ins_size()),
Self::DoubleToFloat(ins) => Ok(ins.ins_size()),
Self::IntToByte(ins) => Ok(ins.ins_size()),
Self::IntToChar(ins) => Ok(ins.ins_size()),
Self::IntToShort(ins) => Ok(ins.ins_size()),
Self::AddInt(ins) => Ok(ins.ins_size()),
Self::SubInt(ins) => Ok(ins.ins_size()),
Self::MulInt(ins) => Ok(ins.ins_size()),
Self::DivInt(ins) => Ok(ins.ins_size()),
Self::RemInt(ins) => Ok(ins.ins_size()),
Self::AndInt(ins) => Ok(ins.ins_size()),
Self::OrInt(ins) => Ok(ins.ins_size()),
Self::XorInt(ins) => Ok(ins.ins_size()),
Self::ShlInt(ins) => Ok(ins.ins_size()),
Self::ShrInt(ins) => Ok(ins.ins_size()),
Self::UshrInt(ins) => Ok(ins.ins_size()),
Self::AddLong(ins) => Ok(ins.ins_size()),
Self::SubLong(ins) => Ok(ins.ins_size()),
Self::MulLong(ins) => Ok(ins.ins_size()),
Self::DivLong(ins) => Ok(ins.ins_size()),
Self::RemLong(ins) => Ok(ins.ins_size()),
Self::AndLong(ins) => Ok(ins.ins_size()),
Self::OrLong(ins) => Ok(ins.ins_size()),
Self::XorLong(ins) => Ok(ins.ins_size()),
Self::ShlLong(ins) => Ok(ins.ins_size()),
Self::ShrLong(ins) => Ok(ins.ins_size()),
Self::UshrLong(ins) => Ok(ins.ins_size()),
Self::AddFloat(ins) => Ok(ins.ins_size()),
Self::SubFloat(ins) => Ok(ins.ins_size()),
Self::MulFloat(ins) => Ok(ins.ins_size()),
Self::DivFloat(ins) => Ok(ins.ins_size()),
Self::RemFloat(ins) => Ok(ins.ins_size()),
Self::AddDouble(ins) => Ok(ins.ins_size()),
Self::SubDouble(ins) => Ok(ins.ins_size()),
Self::MulDouble(ins) => Ok(ins.ins_size()),
Self::DivDouble(ins) => Ok(ins.ins_size()),
Self::RemDouble(ins) => Ok(ins.ins_size()),
Self::AddInt2Addr(ins) => Ok(ins.ins_size()),
Self::SubInt2Addr(ins) => Ok(ins.ins_size()),
Self::MulInt2Addr(ins) => Ok(ins.ins_size()),
Self::DivInt2Addr(ins) => Ok(ins.ins_size()),
Self::RemInt2Addr(ins) => Ok(ins.ins_size()),
Self::AndInt2Addr(ins) => Ok(ins.ins_size()),
Self::OrInt2Addr(ins) => Ok(ins.ins_size()),
Self::XorInt2Addr(ins) => Ok(ins.ins_size()),
Self::ShlInt2Addr(ins) => Ok(ins.ins_size()),
Self::ShrInt2Addr(ins) => Ok(ins.ins_size()),
Self::UshrInt2Addr(ins) => Ok(ins.ins_size()),
Self::AddLong2Addr(ins) => Ok(ins.ins_size()),
Self::SubLong2Addr(ins) => Ok(ins.ins_size()),
Self::MulLong2Addr(ins) => Ok(ins.ins_size()),
Self::DivLong2Addr(ins) => Ok(ins.ins_size()),
Self::RemLong2Addr(ins) => Ok(ins.ins_size()),
Self::AndLong2Addr(ins) => Ok(ins.ins_size()),
Self::OrLong2Addr(ins) => Ok(ins.ins_size()),
Self::XorLong2Addr(ins) => Ok(ins.ins_size()),
Self::ShlLong2Addr(ins) => Ok(ins.ins_size()),
Self::ShrLong2Addr(ins) => Ok(ins.ins_size()),
Self::UshrLong2Addr(ins) => Ok(ins.ins_size()),
Self::AddFloat2Addr(ins) => Ok(ins.ins_size()),
Self::SubFloat2Addr(ins) => Ok(ins.ins_size()),
Self::MulFloat2Addr(ins) => Ok(ins.ins_size()),
Self::DivFloat2Addr(ins) => Ok(ins.ins_size()),
Self::RemFloat2Addr(ins) => Ok(ins.ins_size()),
Self::AddDouble2Addr(ins) => Ok(ins.ins_size()),
Self::SubDouble2Addr(ins) => Ok(ins.ins_size()),
Self::MulDouble2Addr(ins) => Ok(ins.ins_size()),
Self::DivDouble2Addr(ins) => Ok(ins.ins_size()),
Self::RemDouble2Addr(ins) => Ok(ins.ins_size()),
Self::AddIntLit(ins) => Ok(ins.ins_size()),
Self::RsubIntLit(ins) => Ok(ins.ins_size()),
Self::MulIntLit(ins) => Ok(ins.ins_size()),
Self::DivIntLit(ins) => Ok(ins.ins_size()),
Self::RemIntLit(ins) => Ok(ins.ins_size()),
Self::AndIntLit(ins) => Ok(ins.ins_size()),
Self::OrIntLit(ins) => Ok(ins.ins_size()),
Self::XorIntLit(ins) => Ok(ins.ins_size()),
Self::ShlIntLit(ins) => Ok(ins.ins_size()),
Self::ShrIntLit(ins) => Ok(ins.ins_size()),
Self::UshrIntLit(ins) => Ok(ins.ins_size()),
Self::InvokePolymorphic(ins) => Ok(ins.ins_size()),
Self::InvokeCustom(ins) => Ok(ins.ins_size()),
Self::ConstMethodHandle(ins) => Ok(ins.ins_size()),
Self::ConstMethodType(ins) => Ok(ins.ins_size()),
Self::Try(ins) => Ok(ins.ins_size()),
Self::Label(ins) => Ok(ins.ins_size()),
}
}
/// Return the raw instruction ([`InsFormat`]) when it does not need additionnal data.
///
/// # Warning
///
/// Some instruction require additionnal data, or do not have associated instruction format.
/// This method will return an error for thos instruction.
///
/// This method should be used in a match statetement in the default branch, for brevity.
///
/// # Variants that do not implement this method:
///
/// - `ConstString`
/// - `ConstClass`
/// - `CheckCast`
/// - `InstanceOf`
/// - `NewInstance`
/// - `NewArray`
/// - `FilledNewArray`
/// - `FillArrayData`
/// - `Goto`
/// - `Switch`
/// - `IfEq`
/// - `IfNe`
/// - `IfLt`
/// - `IfGe`
/// - `IfGt`
/// - `IfLe`
/// - `IfEqZ`
/// - `IfNeZ`
/// - `IfLtZ`
/// - `IfGeZ`
/// - `IfGtZ`
/// - `IfLeZ`
/// - `IGet`
/// - `IGetWide`
/// - `IGetObject`
/// - `IGetBoolean`
/// - `IGetByte`
/// - `IGetChar`
/// - `IGetShort`
/// - `IPut`
/// - `IPutWide`
/// - `IPutObject`
/// - `IPutBoolean`
/// - `IPutByte`
/// - `IPutChar`
/// - `IPutShort`
/// - `SGet`
/// - `SGetWide`
/// - `SGetObject`
/// - `SGetBoolean`
/// - `SGetByte`
/// - `SGetChar`
/// - `SGetShort`
/// - `SPut`
/// - `SPutWide`
/// - `SPutObject`
/// - `SPutBoolean`
/// - `SPutByte`
/// - `SPutChar`
/// - `SPutShort`
/// - `InvokeVirtual`
/// - `InvokeSuper`
/// - `InvokeDirect`
/// - `InvokeStatic`
/// - `InvokeInterface`
/// - `InvokePolymorphic`
/// - `InvokeCustom`
/// - `ConstMethodHandle`
/// - `ConstMethodType`
/// - `Try`
/// - `Label`
pub fn get_raw_ins(&self) -> Result<InsFormat> {
match self {
Self::Nop(ins) => Ok(ins.get_raw_ins()),
Self::Move(ins) => Ok(ins.get_raw_ins()),
Self::MoveWide(ins) => Ok(ins.get_raw_ins()),
Self::MoveObject(ins) => Ok(ins.get_raw_ins()),
Self::MoveResult(ins) => Ok(ins.get_raw_ins()),
Self::MoveResultWide(ins) => Ok(ins.get_raw_ins()),
Self::MoveException(ins) => Ok(ins.get_raw_ins()),
Self::MoveResultObject(ins) => Ok(ins.get_raw_ins()),
Self::ReturnVoid(ins) => Ok(ins.get_raw_ins()),
Self::Return(ins) => Ok(ins.get_raw_ins()),
Self::ReturnWide(ins) => Ok(ins.get_raw_ins()),
Self::ReturnObject(ins) => Ok(ins.get_raw_ins()),
Self::Const(ins) => Ok(ins.get_raw_ins()),
Self::ConstWide(ins) => Ok(ins.get_raw_ins()),
Self::ConstString(_) => Err(anyhow!(
"Cannot get the raw instruction of a const-string without knowing the string idx"
)),
Self::ConstClass(_) => Err(anyhow!(
"Cannot get the raw instruction of a const-class without knowing the class idx"
)),
Self::MonitorEnter(ins) => Ok(ins.get_raw_ins()),
Self::MonitorExit(ins) => Ok(ins.get_raw_ins()),
Self::CheckCast(_) => Err(anyhow!(
"Cannot get the raw instruction of a check-cast without knowing the type idx"
)),
Self::InstanceOf(_) => Err(anyhow!(
"Cannot get the raw instruction of a instance-of without knowing the type idx"
)),
Self::ArrayLength(ins) => Ok(ins.get_raw_ins()),
Self::NewInstance(_) => Err(anyhow!(
"Cannot get the raw instruction of a new-instance without knowing the class idx"
)),
Self::NewArray(_) => Err(anyhow!(
"Cannot get the raw instruction of a new-array without knowing the type idx"
)),
Self::FilledNewArray(_) => Err(anyhow!(
"Cannot get the raw instruction of a filled-new-array without knowing the type idx"
)),
Self::FillArrayData(_) => Err(anyhow!(
"Cannot get the raw instruction of a fill-array-data without knowing the offset \
to the -fill-array-data-payload"
)),
Self::Throw(ins) => Ok(ins.get_raw_ins()),
Self::Goto(_) => Err(anyhow!(
"Cannot get the size of a goto without knowing the branch offset"
)),
Self::Switch(_) => Err(anyhow!(
"Cannot get the raw instruction of a switch without knowing the offset \
to the packed/sparse-switch-payload"
)),
Self::CmpLFloat(ins) => Ok(ins.get_raw_ins()),
Self::CmpGFloat(ins) => Ok(ins.get_raw_ins()),
Self::CmpLDouble(ins) => Ok(ins.get_raw_ins()),
Self::CmpGDouble(ins) => Ok(ins.get_raw_ins()),
Self::CmpLong(ins) => Ok(ins.get_raw_ins()),
Self::IfEq(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-eq without knowing \
the offset to the branch"
)),
Self::IfNe(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-ne without knowing \
the offset to the branch"
)),
Self::IfLt(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-lt without knowing \
the offset to the branch"
)),
Self::IfGe(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-ge without knowing \
the offset to the branch"
)),
Self::IfGt(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-gt without knowing \
the offset to the branch"
)),
Self::IfLe(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-le without knowing \
the offset to the branch"
)),
Self::IfEqZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-eqz without knowing \
the offset to the branch"
)),
Self::IfNeZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-nez without knowing \
the offset to the branch"
)),
Self::IfLtZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-ltz without knowing \
the offset to the branch"
)),
Self::IfGeZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-gez without knowing \
the offset to the branch"
)),
Self::IfGtZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-gtz without knowing \
the offset to the branch"
)),
Self::IfLeZ(_) => Err(anyhow!(
"Cannot get the raw instruction of a if-lez without knowing \
the offset to the branch"
)),
Self::AGet(ins) => Ok(ins.get_raw_ins()),
Self::AGetWide(ins) => Ok(ins.get_raw_ins()),
Self::AGetObject(ins) => Ok(ins.get_raw_ins()),
Self::AGetBoolean(ins) => Ok(ins.get_raw_ins()),
Self::AGetByte(ins) => Ok(ins.get_raw_ins()),
Self::AGetChar(ins) => Ok(ins.get_raw_ins()),
Self::AGetShort(ins) => Ok(ins.get_raw_ins()),
Self::APut(ins) => Ok(ins.get_raw_ins()),
Self::APutWide(ins) => Ok(ins.get_raw_ins()),
Self::APutObject(ins) => Ok(ins.get_raw_ins()),
Self::APutBoolean(ins) => Ok(ins.get_raw_ins()),
Self::APutByte(ins) => Ok(ins.get_raw_ins()),
Self::APutChar(ins) => Ok(ins.get_raw_ins()),
Self::APutShort(ins) => Ok(ins.get_raw_ins()),
Self::IGet(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget without knowing the field idx"
)),
Self::IGetWide(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-wide without knowing the field idx"
)),
Self::IGetObject(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-object without knowing the field idx"
)),
Self::IGetBoolean(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-boolean without knowing the field idx"
)),
Self::IGetByte(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-byte without knowing the field idx"
)),
Self::IGetChar(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-char without knowing the field idx"
)),
Self::IGetShort(_) => Err(anyhow!(
"Cannot get the raw instruction of a iget-short without knowing the field idx"
)),
Self::IPut(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput without knowing the field idx"
)),
Self::IPutWide(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-wide without knowing the field idx"
)),
Self::IPutObject(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-object without knowing the field idx"
)),
Self::IPutBoolean(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-boolean without knowing the field idx"
)),
Self::IPutByte(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-byte without knowing the field idx"
)),
Self::IPutChar(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-char without knowing the field idx"
)),
Self::IPutShort(_) => Err(anyhow!(
"Cannot get the raw instruction of a iput-short without knowing the field idx"
)),
Self::SGet(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget without knowing the field idx"
)),
Self::SGetWide(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-wide without knowing the field idx"
)),
Self::SGetObject(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-object without knowing the field idx"
)),
Self::SGetBoolean(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-boolean without knowing the field idx"
)),
Self::SGetByte(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-byte without knowing the field idx"
)),
Self::SGetChar(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-char without knowing the field idx"
)),
Self::SGetShort(_) => Err(anyhow!(
"Cannot get the raw instruction of a sget-short without knowing the field idx"
)),
Self::SPut(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput without knowing the field idx"
)),
Self::SPutWide(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-wide without knowing the field idx"
)),
Self::SPutObject(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-object without knowing the field idx"
)),
Self::SPutBoolean(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-boolean without knowing the field idx"
)),
Self::SPutByte(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-byte without knowing the field idx"
)),
Self::SPutChar(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-char without knowing the field idx"
)),
Self::SPutShort(_) => Err(anyhow!(
"Cannot get the raw instruction of a sput-short without knowing the field idx"
)),
Self::InvokeVirtual(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-virtual without knowing \
the method idx"
)),
Self::InvokeSuper(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-super without knowing \
the method idx"
)),
Self::InvokeDirect(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-direct without knowing \
the method idx"
)),
Self::InvokeStatic(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-static without knowing \
the method idx"
)),
Self::InvokeInterface(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-interface without knowing \
the method idx"
)),
Self::NegInt(ins) => Ok(ins.get_raw_ins()),
Self::NotInt(ins) => Ok(ins.get_raw_ins()),
Self::NegLong(ins) => Ok(ins.get_raw_ins()),
Self::NotLong(ins) => Ok(ins.get_raw_ins()),
Self::NegFloat(ins) => Ok(ins.get_raw_ins()),
Self::NegDouble(ins) => Ok(ins.get_raw_ins()),
Self::IntToLong(ins) => Ok(ins.get_raw_ins()),
Self::IntToFloat(ins) => Ok(ins.get_raw_ins()),
Self::IntToDouble(ins) => Ok(ins.get_raw_ins()),
Self::LongToInt(ins) => Ok(ins.get_raw_ins()),
Self::LongToFloat(ins) => Ok(ins.get_raw_ins()),
Self::LongToDouble(ins) => Ok(ins.get_raw_ins()),
Self::FloatToInt(ins) => Ok(ins.get_raw_ins()),
Self::FloatToLong(ins) => Ok(ins.get_raw_ins()),
Self::FloatToDouble(ins) => Ok(ins.get_raw_ins()),
Self::DoubleToInt(ins) => Ok(ins.get_raw_ins()),
Self::DoubleToLong(ins) => Ok(ins.get_raw_ins()),
Self::DoubleToFloat(ins) => Ok(ins.get_raw_ins()),
Self::IntToByte(ins) => Ok(ins.get_raw_ins()),
Self::IntToChar(ins) => Ok(ins.get_raw_ins()),
Self::IntToShort(ins) => Ok(ins.get_raw_ins()),
Self::AddInt(ins) => Ok(ins.get_raw_ins()),
Self::SubInt(ins) => Ok(ins.get_raw_ins()),
Self::MulInt(ins) => Ok(ins.get_raw_ins()),
Self::DivInt(ins) => Ok(ins.get_raw_ins()),
Self::RemInt(ins) => Ok(ins.get_raw_ins()),
Self::AndInt(ins) => Ok(ins.get_raw_ins()),
Self::OrInt(ins) => Ok(ins.get_raw_ins()),
Self::XorInt(ins) => Ok(ins.get_raw_ins()),
Self::ShlInt(ins) => Ok(ins.get_raw_ins()),
Self::ShrInt(ins) => Ok(ins.get_raw_ins()),
Self::UshrInt(ins) => Ok(ins.get_raw_ins()),
Self::AddLong(ins) => Ok(ins.get_raw_ins()),
Self::SubLong(ins) => Ok(ins.get_raw_ins()),
Self::MulLong(ins) => Ok(ins.get_raw_ins()),
Self::DivLong(ins) => Ok(ins.get_raw_ins()),
Self::RemLong(ins) => Ok(ins.get_raw_ins()),
Self::AndLong(ins) => Ok(ins.get_raw_ins()),
Self::OrLong(ins) => Ok(ins.get_raw_ins()),
Self::XorLong(ins) => Ok(ins.get_raw_ins()),
Self::ShlLong(ins) => Ok(ins.get_raw_ins()),
Self::ShrLong(ins) => Ok(ins.get_raw_ins()),
Self::UshrLong(ins) => Ok(ins.get_raw_ins()),
Self::AddFloat(ins) => Ok(ins.get_raw_ins()),
Self::SubFloat(ins) => Ok(ins.get_raw_ins()),
Self::MulFloat(ins) => Ok(ins.get_raw_ins()),
Self::DivFloat(ins) => Ok(ins.get_raw_ins()),
Self::RemFloat(ins) => Ok(ins.get_raw_ins()),
Self::AddDouble(ins) => Ok(ins.get_raw_ins()),
Self::SubDouble(ins) => Ok(ins.get_raw_ins()),
Self::MulDouble(ins) => Ok(ins.get_raw_ins()),
Self::DivDouble(ins) => Ok(ins.get_raw_ins()),
Self::RemDouble(ins) => Ok(ins.get_raw_ins()),
Self::AddInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::SubInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::MulInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::DivInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::RemInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AndInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::OrInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::XorInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::ShlInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::ShrInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::UshrInt2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AddLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::SubLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::MulLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::DivLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::RemLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AndLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::OrLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::XorLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::ShlLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::ShrLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::UshrLong2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AddFloat2Addr(ins) => Ok(ins.get_raw_ins()),
Self::SubFloat2Addr(ins) => Ok(ins.get_raw_ins()),
Self::MulFloat2Addr(ins) => Ok(ins.get_raw_ins()),
Self::DivFloat2Addr(ins) => Ok(ins.get_raw_ins()),
Self::RemFloat2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AddDouble2Addr(ins) => Ok(ins.get_raw_ins()),
Self::SubDouble2Addr(ins) => Ok(ins.get_raw_ins()),
Self::MulDouble2Addr(ins) => Ok(ins.get_raw_ins()),
Self::DivDouble2Addr(ins) => Ok(ins.get_raw_ins()),
Self::RemDouble2Addr(ins) => Ok(ins.get_raw_ins()),
Self::AddIntLit(ins) => Ok(ins.get_raw_ins()),
Self::RsubIntLit(ins) => Ok(ins.get_raw_ins()),
Self::MulIntLit(ins) => Ok(ins.get_raw_ins()),
Self::DivIntLit(ins) => Ok(ins.get_raw_ins()),
Self::RemIntLit(ins) => Ok(ins.get_raw_ins()),
Self::AndIntLit(ins) => Ok(ins.get_raw_ins()),
Self::OrIntLit(ins) => Ok(ins.get_raw_ins()),
Self::XorIntLit(ins) => Ok(ins.get_raw_ins()),
Self::ShlIntLit(ins) => Ok(ins.get_raw_ins()),
Self::ShrIntLit(ins) => Ok(ins.get_raw_ins()),
Self::UshrIntLit(ins) => Ok(ins.get_raw_ins()),
Self::InvokePolymorphic(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-polymorphic without knowing \
the method idx and proto idx"
)),
Self::InvokeCustom(_) => Err(anyhow!(
"Cannot get the raw instruction of a invoke-custom without knowing the \
call site idx"
)),
Self::ConstMethodHandle(_) => Err(anyhow!(
"Cannot get the raw instruction of a const-method-handle \
without knowing the method handle idx"
)),
Self::ConstMethodType(_) => Err(anyhow!(
"Cannot get the raw instruction of a const-method-type \
without knowing the proto idx"
)),
Self::Try(_) => Err(anyhow!(
"Try instruction cannot be converted to raw instruction"
)),
Self::Label(_) => Err(anyhow!("Label cannot be convertedto raw instruction")),
}
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
match self {
Self::Nop(ins) => ins.get_all_strings(),
Self::Move(ins) => ins.get_all_strings(),
Self::MoveWide(ins) => ins.get_all_strings(),
Self::MoveObject(ins) => ins.get_all_strings(),
Self::MoveResult(ins) => ins.get_all_strings(),
Self::MoveResultWide(ins) => ins.get_all_strings(),
Self::MoveException(ins) => ins.get_all_strings(),
Self::MoveResultObject(ins) => ins.get_all_strings(),
Self::ReturnVoid(ins) => ins.get_all_strings(),
Self::Return(ins) => ins.get_all_strings(),
Self::ReturnWide(ins) => ins.get_all_strings(),
Self::ReturnObject(ins) => ins.get_all_strings(),
Self::Const(ins) => ins.get_all_strings(),
Self::ConstWide(ins) => ins.get_all_strings(),
Self::ConstString(ins) => ins.get_all_strings(),
Self::ConstClass(ins) => ins.get_all_strings(),
Self::MonitorEnter(ins) => ins.get_all_strings(),
Self::MonitorExit(ins) => ins.get_all_strings(),
Self::CheckCast(ins) => ins.get_all_strings(),
Self::InstanceOf(ins) => ins.get_all_strings(),
Self::ArrayLength(ins) => ins.get_all_strings(),
Self::NewInstance(ins) => ins.get_all_strings(),
Self::NewArray(ins) => ins.get_all_strings(),
Self::FilledNewArray(ins) => ins.get_all_strings(),
Self::FillArrayData(ins) => ins.get_all_strings(),
Self::Throw(ins) => ins.get_all_strings(),
Self::Goto(ins) => ins.get_all_strings(),
Self::Switch(ins) => ins.get_all_strings(),
Self::CmpLFloat(ins) => ins.get_all_strings(),
Self::CmpGFloat(ins) => ins.get_all_strings(),
Self::CmpLDouble(ins) => ins.get_all_strings(),
Self::CmpGDouble(ins) => ins.get_all_strings(),
Self::CmpLong(ins) => ins.get_all_strings(),
Self::IfEq(ins) => ins.get_all_strings(),
Self::IfNe(ins) => ins.get_all_strings(),
Self::IfLt(ins) => ins.get_all_strings(),
Self::IfGe(ins) => ins.get_all_strings(),
Self::IfGt(ins) => ins.get_all_strings(),
Self::IfLe(ins) => ins.get_all_strings(),
Self::IfEqZ(ins) => ins.get_all_strings(),
Self::IfNeZ(ins) => ins.get_all_strings(),
Self::IfLtZ(ins) => ins.get_all_strings(),
Self::IfGeZ(ins) => ins.get_all_strings(),
Self::IfGtZ(ins) => ins.get_all_strings(),
Self::IfLeZ(ins) => ins.get_all_strings(),
Self::AGet(ins) => ins.get_all_strings(),
Self::AGetWide(ins) => ins.get_all_strings(),
Self::AGetObject(ins) => ins.get_all_strings(),
Self::AGetBoolean(ins) => ins.get_all_strings(),
Self::AGetByte(ins) => ins.get_all_strings(),
Self::AGetChar(ins) => ins.get_all_strings(),
Self::AGetShort(ins) => ins.get_all_strings(),
Self::APut(ins) => ins.get_all_strings(),
Self::APutWide(ins) => ins.get_all_strings(),
Self::APutObject(ins) => ins.get_all_strings(),
Self::APutBoolean(ins) => ins.get_all_strings(),
Self::APutByte(ins) => ins.get_all_strings(),
Self::APutChar(ins) => ins.get_all_strings(),
Self::APutShort(ins) => ins.get_all_strings(),
Self::IGet(ins) => ins.get_all_strings(),
Self::IGetWide(ins) => ins.get_all_strings(),
Self::IGetObject(ins) => ins.get_all_strings(),
Self::IGetBoolean(ins) => ins.get_all_strings(),
Self::IGetByte(ins) => ins.get_all_strings(),
Self::IGetChar(ins) => ins.get_all_strings(),
Self::IGetShort(ins) => ins.get_all_strings(),
Self::IPut(ins) => ins.get_all_strings(),
Self::IPutWide(ins) => ins.get_all_strings(),
Self::IPutObject(ins) => ins.get_all_strings(),
Self::IPutBoolean(ins) => ins.get_all_strings(),
Self::IPutByte(ins) => ins.get_all_strings(),
Self::IPutChar(ins) => ins.get_all_strings(),
Self::IPutShort(ins) => ins.get_all_strings(),
Self::SGet(ins) => ins.get_all_strings(),
Self::SGetWide(ins) => ins.get_all_strings(),
Self::SGetObject(ins) => ins.get_all_strings(),
Self::SGetBoolean(ins) => ins.get_all_strings(),
Self::SGetByte(ins) => ins.get_all_strings(),
Self::SGetChar(ins) => ins.get_all_strings(),
Self::SGetShort(ins) => ins.get_all_strings(),
Self::SPut(ins) => ins.get_all_strings(),
Self::SPutWide(ins) => ins.get_all_strings(),
Self::SPutObject(ins) => ins.get_all_strings(),
Self::SPutBoolean(ins) => ins.get_all_strings(),
Self::SPutByte(ins) => ins.get_all_strings(),
Self::SPutChar(ins) => ins.get_all_strings(),
Self::SPutShort(ins) => ins.get_all_strings(),
Self::InvokeVirtual(ins) => ins.get_all_strings(),
Self::InvokeSuper(ins) => ins.get_all_strings(),
Self::InvokeDirect(ins) => ins.get_all_strings(),
Self::InvokeStatic(ins) => ins.get_all_strings(),
Self::InvokeInterface(ins) => ins.get_all_strings(),
Self::NegInt(ins) => ins.get_all_strings(),
Self::NotInt(ins) => ins.get_all_strings(),
Self::NegLong(ins) => ins.get_all_strings(),
Self::NotLong(ins) => ins.get_all_strings(),
Self::NegFloat(ins) => ins.get_all_strings(),
Self::NegDouble(ins) => ins.get_all_strings(),
Self::IntToLong(ins) => ins.get_all_strings(),
Self::IntToFloat(ins) => ins.get_all_strings(),
Self::IntToDouble(ins) => ins.get_all_strings(),
Self::LongToInt(ins) => ins.get_all_strings(),
Self::LongToFloat(ins) => ins.get_all_strings(),
Self::LongToDouble(ins) => ins.get_all_strings(),
Self::FloatToInt(ins) => ins.get_all_strings(),
Self::FloatToLong(ins) => ins.get_all_strings(),
Self::FloatToDouble(ins) => ins.get_all_strings(),
Self::DoubleToInt(ins) => ins.get_all_strings(),
Self::DoubleToLong(ins) => ins.get_all_strings(),
Self::DoubleToFloat(ins) => ins.get_all_strings(),
Self::IntToByte(ins) => ins.get_all_strings(),
Self::IntToChar(ins) => ins.get_all_strings(),
Self::IntToShort(ins) => ins.get_all_strings(),
Self::AddInt(ins) => ins.get_all_strings(),
Self::SubInt(ins) => ins.get_all_strings(),
Self::MulInt(ins) => ins.get_all_strings(),
Self::DivInt(ins) => ins.get_all_strings(),
Self::RemInt(ins) => ins.get_all_strings(),
Self::AndInt(ins) => ins.get_all_strings(),
Self::OrInt(ins) => ins.get_all_strings(),
Self::XorInt(ins) => ins.get_all_strings(),
Self::ShlInt(ins) => ins.get_all_strings(),
Self::ShrInt(ins) => ins.get_all_strings(),
Self::UshrInt(ins) => ins.get_all_strings(),
Self::AddLong(ins) => ins.get_all_strings(),
Self::SubLong(ins) => ins.get_all_strings(),
Self::MulLong(ins) => ins.get_all_strings(),
Self::DivLong(ins) => ins.get_all_strings(),
Self::RemLong(ins) => ins.get_all_strings(),
Self::AndLong(ins) => ins.get_all_strings(),
Self::OrLong(ins) => ins.get_all_strings(),
Self::XorLong(ins) => ins.get_all_strings(),
Self::ShlLong(ins) => ins.get_all_strings(),
Self::ShrLong(ins) => ins.get_all_strings(),
Self::UshrLong(ins) => ins.get_all_strings(),
Self::AddFloat(ins) => ins.get_all_strings(),
Self::SubFloat(ins) => ins.get_all_strings(),
Self::MulFloat(ins) => ins.get_all_strings(),
Self::DivFloat(ins) => ins.get_all_strings(),
Self::RemFloat(ins) => ins.get_all_strings(),
Self::AddDouble(ins) => ins.get_all_strings(),
Self::SubDouble(ins) => ins.get_all_strings(),
Self::MulDouble(ins) => ins.get_all_strings(),
Self::DivDouble(ins) => ins.get_all_strings(),
Self::RemDouble(ins) => ins.get_all_strings(),
Self::AddInt2Addr(ins) => ins.get_all_strings(),
Self::SubInt2Addr(ins) => ins.get_all_strings(),
Self::MulInt2Addr(ins) => ins.get_all_strings(),
Self::DivInt2Addr(ins) => ins.get_all_strings(),
Self::RemInt2Addr(ins) => ins.get_all_strings(),
Self::AndInt2Addr(ins) => ins.get_all_strings(),
Self::OrInt2Addr(ins) => ins.get_all_strings(),
Self::XorInt2Addr(ins) => ins.get_all_strings(),
Self::ShlInt2Addr(ins) => ins.get_all_strings(),
Self::ShrInt2Addr(ins) => ins.get_all_strings(),
Self::UshrInt2Addr(ins) => ins.get_all_strings(),
Self::AddLong2Addr(ins) => ins.get_all_strings(),
Self::SubLong2Addr(ins) => ins.get_all_strings(),
Self::MulLong2Addr(ins) => ins.get_all_strings(),
Self::DivLong2Addr(ins) => ins.get_all_strings(),
Self::RemLong2Addr(ins) => ins.get_all_strings(),
Self::AndLong2Addr(ins) => ins.get_all_strings(),
Self::OrLong2Addr(ins) => ins.get_all_strings(),
Self::XorLong2Addr(ins) => ins.get_all_strings(),
Self::ShlLong2Addr(ins) => ins.get_all_strings(),
Self::ShrLong2Addr(ins) => ins.get_all_strings(),
Self::UshrLong2Addr(ins) => ins.get_all_strings(),
Self::AddFloat2Addr(ins) => ins.get_all_strings(),
Self::SubFloat2Addr(ins) => ins.get_all_strings(),
Self::MulFloat2Addr(ins) => ins.get_all_strings(),
Self::DivFloat2Addr(ins) => ins.get_all_strings(),
Self::RemFloat2Addr(ins) => ins.get_all_strings(),
Self::AddDouble2Addr(ins) => ins.get_all_strings(),
Self::SubDouble2Addr(ins) => ins.get_all_strings(),
Self::MulDouble2Addr(ins) => ins.get_all_strings(),
Self::DivDouble2Addr(ins) => ins.get_all_strings(),
Self::RemDouble2Addr(ins) => ins.get_all_strings(),
Self::AddIntLit(ins) => ins.get_all_strings(),
Self::RsubIntLit(ins) => ins.get_all_strings(),
Self::MulIntLit(ins) => ins.get_all_strings(),
Self::DivIntLit(ins) => ins.get_all_strings(),
Self::RemIntLit(ins) => ins.get_all_strings(),
Self::AndIntLit(ins) => ins.get_all_strings(),
Self::OrIntLit(ins) => ins.get_all_strings(),
Self::XorIntLit(ins) => ins.get_all_strings(),
Self::ShlIntLit(ins) => ins.get_all_strings(),
Self::ShrIntLit(ins) => ins.get_all_strings(),
Self::UshrIntLit(ins) => ins.get_all_strings(),
Self::InvokePolymorphic(ins) => ins.get_all_strings(),
Self::InvokeCustom(ins) => ins.get_all_strings(),
Self::ConstMethodHandle(ins) => ins.get_all_strings(),
Self::ConstMethodType(ins) => ins.get_all_strings(),
Self::Try(ins) => ins.get_all_strings(),
Self::Label(ins) => ins.get_all_strings(),
}
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
match self {
Self::Nop(ins) => ins.get_all_types(),
Self::Move(ins) => ins.get_all_types(),
Self::MoveWide(ins) => ins.get_all_types(),
Self::MoveObject(ins) => ins.get_all_types(),
Self::MoveResult(ins) => ins.get_all_types(),
Self::MoveResultWide(ins) => ins.get_all_types(),
Self::MoveException(ins) => ins.get_all_types(),
Self::MoveResultObject(ins) => ins.get_all_types(),
Self::ReturnVoid(ins) => ins.get_all_types(),
Self::Return(ins) => ins.get_all_types(),
Self::ReturnWide(ins) => ins.get_all_types(),
Self::ReturnObject(ins) => ins.get_all_types(),
Self::Const(ins) => ins.get_all_types(),
Self::ConstWide(ins) => ins.get_all_types(),
Self::ConstString(ins) => ins.get_all_types(),
Self::ConstClass(ins) => ins.get_all_types(),
Self::MonitorEnter(ins) => ins.get_all_types(),
Self::MonitorExit(ins) => ins.get_all_types(),
Self::CheckCast(ins) => ins.get_all_types(),
Self::InstanceOf(ins) => ins.get_all_types(),
Self::ArrayLength(ins) => ins.get_all_types(),
Self::NewInstance(ins) => ins.get_all_types(),
Self::NewArray(ins) => ins.get_all_types(),
Self::FilledNewArray(ins) => ins.get_all_types(),
Self::FillArrayData(ins) => ins.get_all_types(),
Self::Throw(ins) => ins.get_all_types(),
Self::Goto(ins) => ins.get_all_types(),
Self::Switch(ins) => ins.get_all_types(),
Self::CmpLFloat(ins) => ins.get_all_types(),
Self::CmpGFloat(ins) => ins.get_all_types(),
Self::CmpLDouble(ins) => ins.get_all_types(),
Self::CmpGDouble(ins) => ins.get_all_types(),
Self::CmpLong(ins) => ins.get_all_types(),
Self::IfEq(ins) => ins.get_all_types(),
Self::IfNe(ins) => ins.get_all_types(),
Self::IfLt(ins) => ins.get_all_types(),
Self::IfGe(ins) => ins.get_all_types(),
Self::IfGt(ins) => ins.get_all_types(),
Self::IfLe(ins) => ins.get_all_types(),
Self::IfEqZ(ins) => ins.get_all_types(),
Self::IfNeZ(ins) => ins.get_all_types(),
Self::IfLtZ(ins) => ins.get_all_types(),
Self::IfGeZ(ins) => ins.get_all_types(),
Self::IfGtZ(ins) => ins.get_all_types(),
Self::IfLeZ(ins) => ins.get_all_types(),
Self::AGet(ins) => ins.get_all_types(),
Self::AGetWide(ins) => ins.get_all_types(),
Self::AGetObject(ins) => ins.get_all_types(),
Self::AGetBoolean(ins) => ins.get_all_types(),
Self::AGetByte(ins) => ins.get_all_types(),
Self::AGetChar(ins) => ins.get_all_types(),
Self::AGetShort(ins) => ins.get_all_types(),
Self::APut(ins) => ins.get_all_types(),
Self::APutWide(ins) => ins.get_all_types(),
Self::APutObject(ins) => ins.get_all_types(),
Self::APutBoolean(ins) => ins.get_all_types(),
Self::APutByte(ins) => ins.get_all_types(),
Self::APutChar(ins) => ins.get_all_types(),
Self::APutShort(ins) => ins.get_all_types(),
Self::IGet(ins) => ins.get_all_types(),
Self::IGetWide(ins) => ins.get_all_types(),
Self::IGetObject(ins) => ins.get_all_types(),
Self::IGetBoolean(ins) => ins.get_all_types(),
Self::IGetByte(ins) => ins.get_all_types(),
Self::IGetChar(ins) => ins.get_all_types(),
Self::IGetShort(ins) => ins.get_all_types(),
Self::IPut(ins) => ins.get_all_types(),
Self::IPutWide(ins) => ins.get_all_types(),
Self::IPutObject(ins) => ins.get_all_types(),
Self::IPutBoolean(ins) => ins.get_all_types(),
Self::IPutByte(ins) => ins.get_all_types(),
Self::IPutChar(ins) => ins.get_all_types(),
Self::IPutShort(ins) => ins.get_all_types(),
Self::SGet(ins) => ins.get_all_types(),
Self::SGetWide(ins) => ins.get_all_types(),
Self::SGetObject(ins) => ins.get_all_types(),
Self::SGetBoolean(ins) => ins.get_all_types(),
Self::SGetByte(ins) => ins.get_all_types(),
Self::SGetChar(ins) => ins.get_all_types(),
Self::SGetShort(ins) => ins.get_all_types(),
Self::SPut(ins) => ins.get_all_types(),
Self::SPutWide(ins) => ins.get_all_types(),
Self::SPutObject(ins) => ins.get_all_types(),
Self::SPutBoolean(ins) => ins.get_all_types(),
Self::SPutByte(ins) => ins.get_all_types(),
Self::SPutChar(ins) => ins.get_all_types(),
Self::SPutShort(ins) => ins.get_all_types(),
Self::InvokeVirtual(ins) => ins.get_all_types(),
Self::InvokeSuper(ins) => ins.get_all_types(),
Self::InvokeDirect(ins) => ins.get_all_types(),
Self::InvokeStatic(ins) => ins.get_all_types(),
Self::InvokeInterface(ins) => ins.get_all_types(),
Self::NegInt(ins) => ins.get_all_types(),
Self::NotInt(ins) => ins.get_all_types(),
Self::NegLong(ins) => ins.get_all_types(),
Self::NotLong(ins) => ins.get_all_types(),
Self::NegFloat(ins) => ins.get_all_types(),
Self::NegDouble(ins) => ins.get_all_types(),
Self::IntToLong(ins) => ins.get_all_types(),
Self::IntToFloat(ins) => ins.get_all_types(),
Self::IntToDouble(ins) => ins.get_all_types(),
Self::LongToInt(ins) => ins.get_all_types(),
Self::LongToFloat(ins) => ins.get_all_types(),
Self::LongToDouble(ins) => ins.get_all_types(),
Self::FloatToInt(ins) => ins.get_all_types(),
Self::FloatToLong(ins) => ins.get_all_types(),
Self::FloatToDouble(ins) => ins.get_all_types(),
Self::DoubleToInt(ins) => ins.get_all_types(),
Self::DoubleToLong(ins) => ins.get_all_types(),
Self::DoubleToFloat(ins) => ins.get_all_types(),
Self::IntToByte(ins) => ins.get_all_types(),
Self::IntToChar(ins) => ins.get_all_types(),
Self::IntToShort(ins) => ins.get_all_types(),
Self::AddInt(ins) => ins.get_all_types(),
Self::SubInt(ins) => ins.get_all_types(),
Self::MulInt(ins) => ins.get_all_types(),
Self::DivInt(ins) => ins.get_all_types(),
Self::RemInt(ins) => ins.get_all_types(),
Self::AndInt(ins) => ins.get_all_types(),
Self::OrInt(ins) => ins.get_all_types(),
Self::XorInt(ins) => ins.get_all_types(),
Self::ShlInt(ins) => ins.get_all_types(),
Self::ShrInt(ins) => ins.get_all_types(),
Self::UshrInt(ins) => ins.get_all_types(),
Self::AddLong(ins) => ins.get_all_types(),
Self::SubLong(ins) => ins.get_all_types(),
Self::MulLong(ins) => ins.get_all_types(),
Self::DivLong(ins) => ins.get_all_types(),
Self::RemLong(ins) => ins.get_all_types(),
Self::AndLong(ins) => ins.get_all_types(),
Self::OrLong(ins) => ins.get_all_types(),
Self::XorLong(ins) => ins.get_all_types(),
Self::ShlLong(ins) => ins.get_all_types(),
Self::ShrLong(ins) => ins.get_all_types(),
Self::UshrLong(ins) => ins.get_all_types(),
Self::AddFloat(ins) => ins.get_all_types(),
Self::SubFloat(ins) => ins.get_all_types(),
Self::MulFloat(ins) => ins.get_all_types(),
Self::DivFloat(ins) => ins.get_all_types(),
Self::RemFloat(ins) => ins.get_all_types(),
Self::AddDouble(ins) => ins.get_all_types(),
Self::SubDouble(ins) => ins.get_all_types(),
Self::MulDouble(ins) => ins.get_all_types(),
Self::DivDouble(ins) => ins.get_all_types(),
Self::RemDouble(ins) => ins.get_all_types(),
Self::AddInt2Addr(ins) => ins.get_all_types(),
Self::SubInt2Addr(ins) => ins.get_all_types(),
Self::MulInt2Addr(ins) => ins.get_all_types(),
Self::DivInt2Addr(ins) => ins.get_all_types(),
Self::RemInt2Addr(ins) => ins.get_all_types(),
Self::AndInt2Addr(ins) => ins.get_all_types(),
Self::OrInt2Addr(ins) => ins.get_all_types(),
Self::XorInt2Addr(ins) => ins.get_all_types(),
Self::ShlInt2Addr(ins) => ins.get_all_types(),
Self::ShrInt2Addr(ins) => ins.get_all_types(),
Self::UshrInt2Addr(ins) => ins.get_all_types(),
Self::AddLong2Addr(ins) => ins.get_all_types(),
Self::SubLong2Addr(ins) => ins.get_all_types(),
Self::MulLong2Addr(ins) => ins.get_all_types(),
Self::DivLong2Addr(ins) => ins.get_all_types(),
Self::RemLong2Addr(ins) => ins.get_all_types(),
Self::AndLong2Addr(ins) => ins.get_all_types(),
Self::OrLong2Addr(ins) => ins.get_all_types(),
Self::XorLong2Addr(ins) => ins.get_all_types(),
Self::ShlLong2Addr(ins) => ins.get_all_types(),
Self::ShrLong2Addr(ins) => ins.get_all_types(),
Self::UshrLong2Addr(ins) => ins.get_all_types(),
Self::AddFloat2Addr(ins) => ins.get_all_types(),
Self::SubFloat2Addr(ins) => ins.get_all_types(),
Self::MulFloat2Addr(ins) => ins.get_all_types(),
Self::DivFloat2Addr(ins) => ins.get_all_types(),
Self::RemFloat2Addr(ins) => ins.get_all_types(),
Self::AddDouble2Addr(ins) => ins.get_all_types(),
Self::SubDouble2Addr(ins) => ins.get_all_types(),
Self::MulDouble2Addr(ins) => ins.get_all_types(),
Self::DivDouble2Addr(ins) => ins.get_all_types(),
Self::RemDouble2Addr(ins) => ins.get_all_types(),
Self::AddIntLit(ins) => ins.get_all_types(),
Self::RsubIntLit(ins) => ins.get_all_types(),
Self::MulIntLit(ins) => ins.get_all_types(),
Self::DivIntLit(ins) => ins.get_all_types(),
Self::RemIntLit(ins) => ins.get_all_types(),
Self::AndIntLit(ins) => ins.get_all_types(),
Self::OrIntLit(ins) => ins.get_all_types(),
Self::XorIntLit(ins) => ins.get_all_types(),
Self::ShlIntLit(ins) => ins.get_all_types(),
Self::ShrIntLit(ins) => ins.get_all_types(),
Self::UshrIntLit(ins) => ins.get_all_types(),
Self::InvokePolymorphic(ins) => ins.get_all_types(),
Self::InvokeCustom(ins) => ins.get_all_types(),
Self::ConstMethodHandle(ins) => ins.get_all_types(),
Self::ConstMethodType(ins) => ins.get_all_types(),
Self::Try(ins) => ins.get_all_types(),
Self::Label(ins) => ins.get_all_types(),
}
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
match self {
Self::Nop(ins) => ins.get_all_protos(),
Self::Move(ins) => ins.get_all_protos(),
Self::MoveWide(ins) => ins.get_all_protos(),
Self::MoveObject(ins) => ins.get_all_protos(),
Self::MoveResult(ins) => ins.get_all_protos(),
Self::MoveResultWide(ins) => ins.get_all_protos(),
Self::MoveException(ins) => ins.get_all_protos(),
Self::MoveResultObject(ins) => ins.get_all_protos(),
Self::ReturnVoid(ins) => ins.get_all_protos(),
Self::Return(ins) => ins.get_all_protos(),
Self::ReturnWide(ins) => ins.get_all_protos(),
Self::ReturnObject(ins) => ins.get_all_protos(),
Self::Const(ins) => ins.get_all_protos(),
Self::ConstWide(ins) => ins.get_all_protos(),
Self::ConstString(ins) => ins.get_all_protos(),
Self::ConstClass(ins) => ins.get_all_protos(),
Self::MonitorEnter(ins) => ins.get_all_protos(),
Self::MonitorExit(ins) => ins.get_all_protos(),
Self::CheckCast(ins) => ins.get_all_protos(),
Self::InstanceOf(ins) => ins.get_all_protos(),
Self::ArrayLength(ins) => ins.get_all_protos(),
Self::NewInstance(ins) => ins.get_all_protos(),
Self::NewArray(ins) => ins.get_all_protos(),
Self::FilledNewArray(ins) => ins.get_all_protos(),
Self::FillArrayData(ins) => ins.get_all_protos(),
Self::Throw(ins) => ins.get_all_protos(),
Self::Goto(ins) => ins.get_all_protos(),
Self::Switch(ins) => ins.get_all_protos(),
Self::CmpLFloat(ins) => ins.get_all_protos(),
Self::CmpGFloat(ins) => ins.get_all_protos(),
Self::CmpLDouble(ins) => ins.get_all_protos(),
Self::CmpGDouble(ins) => ins.get_all_protos(),
Self::CmpLong(ins) => ins.get_all_protos(),
Self::IfEq(ins) => ins.get_all_protos(),
Self::IfNe(ins) => ins.get_all_protos(),
Self::IfLt(ins) => ins.get_all_protos(),
Self::IfGe(ins) => ins.get_all_protos(),
Self::IfGt(ins) => ins.get_all_protos(),
Self::IfLe(ins) => ins.get_all_protos(),
Self::IfEqZ(ins) => ins.get_all_protos(),
Self::IfNeZ(ins) => ins.get_all_protos(),
Self::IfLtZ(ins) => ins.get_all_protos(),
Self::IfGeZ(ins) => ins.get_all_protos(),
Self::IfGtZ(ins) => ins.get_all_protos(),
Self::IfLeZ(ins) => ins.get_all_protos(),
Self::AGet(ins) => ins.get_all_protos(),
Self::AGetWide(ins) => ins.get_all_protos(),
Self::AGetObject(ins) => ins.get_all_protos(),
Self::AGetBoolean(ins) => ins.get_all_protos(),
Self::AGetByte(ins) => ins.get_all_protos(),
Self::AGetChar(ins) => ins.get_all_protos(),
Self::AGetShort(ins) => ins.get_all_protos(),
Self::APut(ins) => ins.get_all_protos(),
Self::APutWide(ins) => ins.get_all_protos(),
Self::APutObject(ins) => ins.get_all_protos(),
Self::APutBoolean(ins) => ins.get_all_protos(),
Self::APutByte(ins) => ins.get_all_protos(),
Self::APutChar(ins) => ins.get_all_protos(),
Self::APutShort(ins) => ins.get_all_protos(),
Self::IGet(ins) => ins.get_all_protos(),
Self::IGetWide(ins) => ins.get_all_protos(),
Self::IGetObject(ins) => ins.get_all_protos(),
Self::IGetBoolean(ins) => ins.get_all_protos(),
Self::IGetByte(ins) => ins.get_all_protos(),
Self::IGetChar(ins) => ins.get_all_protos(),
Self::IGetShort(ins) => ins.get_all_protos(),
Self::IPut(ins) => ins.get_all_protos(),
Self::IPutWide(ins) => ins.get_all_protos(),
Self::IPutObject(ins) => ins.get_all_protos(),
Self::IPutBoolean(ins) => ins.get_all_protos(),
Self::IPutByte(ins) => ins.get_all_protos(),
Self::IPutChar(ins) => ins.get_all_protos(),
Self::IPutShort(ins) => ins.get_all_protos(),
Self::SGet(ins) => ins.get_all_protos(),
Self::SGetWide(ins) => ins.get_all_protos(),
Self::SGetObject(ins) => ins.get_all_protos(),
Self::SGetBoolean(ins) => ins.get_all_protos(),
Self::SGetByte(ins) => ins.get_all_protos(),
Self::SGetChar(ins) => ins.get_all_protos(),
Self::SGetShort(ins) => ins.get_all_protos(),
Self::SPut(ins) => ins.get_all_protos(),
Self::SPutWide(ins) => ins.get_all_protos(),
Self::SPutObject(ins) => ins.get_all_protos(),
Self::SPutBoolean(ins) => ins.get_all_protos(),
Self::SPutByte(ins) => ins.get_all_protos(),
Self::SPutChar(ins) => ins.get_all_protos(),
Self::SPutShort(ins) => ins.get_all_protos(),
Self::InvokeVirtual(ins) => ins.get_all_protos(),
Self::InvokeSuper(ins) => ins.get_all_protos(),
Self::InvokeDirect(ins) => ins.get_all_protos(),
Self::InvokeStatic(ins) => ins.get_all_protos(),
Self::InvokeInterface(ins) => ins.get_all_protos(),
Self::NegInt(ins) => ins.get_all_protos(),
Self::NotInt(ins) => ins.get_all_protos(),
Self::NegLong(ins) => ins.get_all_protos(),
Self::NotLong(ins) => ins.get_all_protos(),
Self::NegFloat(ins) => ins.get_all_protos(),
Self::NegDouble(ins) => ins.get_all_protos(),
Self::IntToLong(ins) => ins.get_all_protos(),
Self::IntToFloat(ins) => ins.get_all_protos(),
Self::IntToDouble(ins) => ins.get_all_protos(),
Self::LongToInt(ins) => ins.get_all_protos(),
Self::LongToFloat(ins) => ins.get_all_protos(),
Self::LongToDouble(ins) => ins.get_all_protos(),
Self::FloatToInt(ins) => ins.get_all_protos(),
Self::FloatToLong(ins) => ins.get_all_protos(),
Self::FloatToDouble(ins) => ins.get_all_protos(),
Self::DoubleToInt(ins) => ins.get_all_protos(),
Self::DoubleToLong(ins) => ins.get_all_protos(),
Self::DoubleToFloat(ins) => ins.get_all_protos(),
Self::IntToByte(ins) => ins.get_all_protos(),
Self::IntToChar(ins) => ins.get_all_protos(),
Self::IntToShort(ins) => ins.get_all_protos(),
Self::AddInt(ins) => ins.get_all_protos(),
Self::SubInt(ins) => ins.get_all_protos(),
Self::MulInt(ins) => ins.get_all_protos(),
Self::DivInt(ins) => ins.get_all_protos(),
Self::RemInt(ins) => ins.get_all_protos(),
Self::AndInt(ins) => ins.get_all_protos(),
Self::OrInt(ins) => ins.get_all_protos(),
Self::XorInt(ins) => ins.get_all_protos(),
Self::ShlInt(ins) => ins.get_all_protos(),
Self::ShrInt(ins) => ins.get_all_protos(),
Self::UshrInt(ins) => ins.get_all_protos(),
Self::AddLong(ins) => ins.get_all_protos(),
Self::SubLong(ins) => ins.get_all_protos(),
Self::MulLong(ins) => ins.get_all_protos(),
Self::DivLong(ins) => ins.get_all_protos(),
Self::RemLong(ins) => ins.get_all_protos(),
Self::AndLong(ins) => ins.get_all_protos(),
Self::OrLong(ins) => ins.get_all_protos(),
Self::XorLong(ins) => ins.get_all_protos(),
Self::ShlLong(ins) => ins.get_all_protos(),
Self::ShrLong(ins) => ins.get_all_protos(),
Self::UshrLong(ins) => ins.get_all_protos(),
Self::AddFloat(ins) => ins.get_all_protos(),
Self::SubFloat(ins) => ins.get_all_protos(),
Self::MulFloat(ins) => ins.get_all_protos(),
Self::DivFloat(ins) => ins.get_all_protos(),
Self::RemFloat(ins) => ins.get_all_protos(),
Self::AddDouble(ins) => ins.get_all_protos(),
Self::SubDouble(ins) => ins.get_all_protos(),
Self::MulDouble(ins) => ins.get_all_protos(),
Self::DivDouble(ins) => ins.get_all_protos(),
Self::RemDouble(ins) => ins.get_all_protos(),
Self::AddInt2Addr(ins) => ins.get_all_protos(),
Self::SubInt2Addr(ins) => ins.get_all_protos(),
Self::MulInt2Addr(ins) => ins.get_all_protos(),
Self::DivInt2Addr(ins) => ins.get_all_protos(),
Self::RemInt2Addr(ins) => ins.get_all_protos(),
Self::AndInt2Addr(ins) => ins.get_all_protos(),
Self::OrInt2Addr(ins) => ins.get_all_protos(),
Self::XorInt2Addr(ins) => ins.get_all_protos(),
Self::ShlInt2Addr(ins) => ins.get_all_protos(),
Self::ShrInt2Addr(ins) => ins.get_all_protos(),
Self::UshrInt2Addr(ins) => ins.get_all_protos(),
Self::AddLong2Addr(ins) => ins.get_all_protos(),
Self::SubLong2Addr(ins) => ins.get_all_protos(),
Self::MulLong2Addr(ins) => ins.get_all_protos(),
Self::DivLong2Addr(ins) => ins.get_all_protos(),
Self::RemLong2Addr(ins) => ins.get_all_protos(),
Self::AndLong2Addr(ins) => ins.get_all_protos(),
Self::OrLong2Addr(ins) => ins.get_all_protos(),
Self::XorLong2Addr(ins) => ins.get_all_protos(),
Self::ShlLong2Addr(ins) => ins.get_all_protos(),
Self::ShrLong2Addr(ins) => ins.get_all_protos(),
Self::UshrLong2Addr(ins) => ins.get_all_protos(),
Self::AddFloat2Addr(ins) => ins.get_all_protos(),
Self::SubFloat2Addr(ins) => ins.get_all_protos(),
Self::MulFloat2Addr(ins) => ins.get_all_protos(),
Self::DivFloat2Addr(ins) => ins.get_all_protos(),
Self::RemFloat2Addr(ins) => ins.get_all_protos(),
Self::AddDouble2Addr(ins) => ins.get_all_protos(),
Self::SubDouble2Addr(ins) => ins.get_all_protos(),
Self::MulDouble2Addr(ins) => ins.get_all_protos(),
Self::DivDouble2Addr(ins) => ins.get_all_protos(),
Self::RemDouble2Addr(ins) => ins.get_all_protos(),
Self::AddIntLit(ins) => ins.get_all_protos(),
Self::RsubIntLit(ins) => ins.get_all_protos(),
Self::MulIntLit(ins) => ins.get_all_protos(),
Self::DivIntLit(ins) => ins.get_all_protos(),
Self::RemIntLit(ins) => ins.get_all_protos(),
Self::AndIntLit(ins) => ins.get_all_protos(),
Self::OrIntLit(ins) => ins.get_all_protos(),
Self::XorIntLit(ins) => ins.get_all_protos(),
Self::ShlIntLit(ins) => ins.get_all_protos(),
Self::ShrIntLit(ins) => ins.get_all_protos(),
Self::UshrIntLit(ins) => ins.get_all_protos(),
Self::InvokePolymorphic(ins) => ins.get_all_protos(),
Self::InvokeCustom(ins) => ins.get_all_protos(),
Self::ConstMethodHandle(ins) => ins.get_all_protos(),
Self::ConstMethodType(ins) => ins.get_all_protos(),
Self::Try(ins) => ins.get_all_protos(),
Self::Label(ins) => ins.get_all_protos(),
}
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
match self {
Self::Nop(ins) => ins.get_all_field_ids(),
Self::Move(ins) => ins.get_all_field_ids(),
Self::MoveWide(ins) => ins.get_all_field_ids(),
Self::MoveObject(ins) => ins.get_all_field_ids(),
Self::MoveResult(ins) => ins.get_all_field_ids(),
Self::MoveResultWide(ins) => ins.get_all_field_ids(),
Self::MoveException(ins) => ins.get_all_field_ids(),
Self::MoveResultObject(ins) => ins.get_all_field_ids(),
Self::ReturnVoid(ins) => ins.get_all_field_ids(),
Self::Return(ins) => ins.get_all_field_ids(),
Self::ReturnWide(ins) => ins.get_all_field_ids(),
Self::ReturnObject(ins) => ins.get_all_field_ids(),
Self::Const(ins) => ins.get_all_field_ids(),
Self::ConstWide(ins) => ins.get_all_field_ids(),
Self::ConstString(ins) => ins.get_all_field_ids(),
Self::ConstClass(ins) => ins.get_all_field_ids(),
Self::MonitorEnter(ins) => ins.get_all_field_ids(),
Self::MonitorExit(ins) => ins.get_all_field_ids(),
Self::CheckCast(ins) => ins.get_all_field_ids(),
Self::InstanceOf(ins) => ins.get_all_field_ids(),
Self::ArrayLength(ins) => ins.get_all_field_ids(),
Self::NewInstance(ins) => ins.get_all_field_ids(),
Self::NewArray(ins) => ins.get_all_field_ids(),
Self::FilledNewArray(ins) => ins.get_all_field_ids(),
Self::FillArrayData(ins) => ins.get_all_field_ids(),
Self::Throw(ins) => ins.get_all_field_ids(),
Self::Goto(ins) => ins.get_all_field_ids(),
Self::Switch(ins) => ins.get_all_field_ids(),
Self::CmpLFloat(ins) => ins.get_all_field_ids(),
Self::CmpGFloat(ins) => ins.get_all_field_ids(),
Self::CmpLDouble(ins) => ins.get_all_field_ids(),
Self::CmpGDouble(ins) => ins.get_all_field_ids(),
Self::CmpLong(ins) => ins.get_all_field_ids(),
Self::IfEq(ins) => ins.get_all_field_ids(),
Self::IfNe(ins) => ins.get_all_field_ids(),
Self::IfLt(ins) => ins.get_all_field_ids(),
Self::IfGe(ins) => ins.get_all_field_ids(),
Self::IfGt(ins) => ins.get_all_field_ids(),
Self::IfLe(ins) => ins.get_all_field_ids(),
Self::IfEqZ(ins) => ins.get_all_field_ids(),
Self::IfNeZ(ins) => ins.get_all_field_ids(),
Self::IfLtZ(ins) => ins.get_all_field_ids(),
Self::IfGeZ(ins) => ins.get_all_field_ids(),
Self::IfGtZ(ins) => ins.get_all_field_ids(),
Self::IfLeZ(ins) => ins.get_all_field_ids(),
Self::AGet(ins) => ins.get_all_field_ids(),
Self::AGetWide(ins) => ins.get_all_field_ids(),
Self::AGetObject(ins) => ins.get_all_field_ids(),
Self::AGetBoolean(ins) => ins.get_all_field_ids(),
Self::AGetByte(ins) => ins.get_all_field_ids(),
Self::AGetChar(ins) => ins.get_all_field_ids(),
Self::AGetShort(ins) => ins.get_all_field_ids(),
Self::APut(ins) => ins.get_all_field_ids(),
Self::APutWide(ins) => ins.get_all_field_ids(),
Self::APutObject(ins) => ins.get_all_field_ids(),
Self::APutBoolean(ins) => ins.get_all_field_ids(),
Self::APutByte(ins) => ins.get_all_field_ids(),
Self::APutChar(ins) => ins.get_all_field_ids(),
Self::APutShort(ins) => ins.get_all_field_ids(),
Self::IGet(ins) => ins.get_all_field_ids(),
Self::IGetWide(ins) => ins.get_all_field_ids(),
Self::IGetObject(ins) => ins.get_all_field_ids(),
Self::IGetBoolean(ins) => ins.get_all_field_ids(),
Self::IGetByte(ins) => ins.get_all_field_ids(),
Self::IGetChar(ins) => ins.get_all_field_ids(),
Self::IGetShort(ins) => ins.get_all_field_ids(),
Self::IPut(ins) => ins.get_all_field_ids(),
Self::IPutWide(ins) => ins.get_all_field_ids(),
Self::IPutObject(ins) => ins.get_all_field_ids(),
Self::IPutBoolean(ins) => ins.get_all_field_ids(),
Self::IPutByte(ins) => ins.get_all_field_ids(),
Self::IPutChar(ins) => ins.get_all_field_ids(),
Self::IPutShort(ins) => ins.get_all_field_ids(),
Self::SGet(ins) => ins.get_all_field_ids(),
Self::SGetWide(ins) => ins.get_all_field_ids(),
Self::SGetObject(ins) => ins.get_all_field_ids(),
Self::SGetBoolean(ins) => ins.get_all_field_ids(),
Self::SGetByte(ins) => ins.get_all_field_ids(),
Self::SGetChar(ins) => ins.get_all_field_ids(),
Self::SGetShort(ins) => ins.get_all_field_ids(),
Self::SPut(ins) => ins.get_all_field_ids(),
Self::SPutWide(ins) => ins.get_all_field_ids(),
Self::SPutObject(ins) => ins.get_all_field_ids(),
Self::SPutBoolean(ins) => ins.get_all_field_ids(),
Self::SPutByte(ins) => ins.get_all_field_ids(),
Self::SPutChar(ins) => ins.get_all_field_ids(),
Self::SPutShort(ins) => ins.get_all_field_ids(),
Self::InvokeVirtual(ins) => ins.get_all_field_ids(),
Self::InvokeSuper(ins) => ins.get_all_field_ids(),
Self::InvokeDirect(ins) => ins.get_all_field_ids(),
Self::InvokeStatic(ins) => ins.get_all_field_ids(),
Self::InvokeInterface(ins) => ins.get_all_field_ids(),
Self::NegInt(ins) => ins.get_all_field_ids(),
Self::NotInt(ins) => ins.get_all_field_ids(),
Self::NegLong(ins) => ins.get_all_field_ids(),
Self::NotLong(ins) => ins.get_all_field_ids(),
Self::NegFloat(ins) => ins.get_all_field_ids(),
Self::NegDouble(ins) => ins.get_all_field_ids(),
Self::IntToLong(ins) => ins.get_all_field_ids(),
Self::IntToFloat(ins) => ins.get_all_field_ids(),
Self::IntToDouble(ins) => ins.get_all_field_ids(),
Self::LongToInt(ins) => ins.get_all_field_ids(),
Self::LongToFloat(ins) => ins.get_all_field_ids(),
Self::LongToDouble(ins) => ins.get_all_field_ids(),
Self::FloatToInt(ins) => ins.get_all_field_ids(),
Self::FloatToLong(ins) => ins.get_all_field_ids(),
Self::FloatToDouble(ins) => ins.get_all_field_ids(),
Self::DoubleToInt(ins) => ins.get_all_field_ids(),
Self::DoubleToLong(ins) => ins.get_all_field_ids(),
Self::DoubleToFloat(ins) => ins.get_all_field_ids(),
Self::IntToByte(ins) => ins.get_all_field_ids(),
Self::IntToChar(ins) => ins.get_all_field_ids(),
Self::IntToShort(ins) => ins.get_all_field_ids(),
Self::AddInt(ins) => ins.get_all_field_ids(),
Self::SubInt(ins) => ins.get_all_field_ids(),
Self::MulInt(ins) => ins.get_all_field_ids(),
Self::DivInt(ins) => ins.get_all_field_ids(),
Self::RemInt(ins) => ins.get_all_field_ids(),
Self::AndInt(ins) => ins.get_all_field_ids(),
Self::OrInt(ins) => ins.get_all_field_ids(),
Self::XorInt(ins) => ins.get_all_field_ids(),
Self::ShlInt(ins) => ins.get_all_field_ids(),
Self::ShrInt(ins) => ins.get_all_field_ids(),
Self::UshrInt(ins) => ins.get_all_field_ids(),
Self::AddLong(ins) => ins.get_all_field_ids(),
Self::SubLong(ins) => ins.get_all_field_ids(),
Self::MulLong(ins) => ins.get_all_field_ids(),
Self::DivLong(ins) => ins.get_all_field_ids(),
Self::RemLong(ins) => ins.get_all_field_ids(),
Self::AndLong(ins) => ins.get_all_field_ids(),
Self::OrLong(ins) => ins.get_all_field_ids(),
Self::XorLong(ins) => ins.get_all_field_ids(),
Self::ShlLong(ins) => ins.get_all_field_ids(),
Self::ShrLong(ins) => ins.get_all_field_ids(),
Self::UshrLong(ins) => ins.get_all_field_ids(),
Self::AddFloat(ins) => ins.get_all_field_ids(),
Self::SubFloat(ins) => ins.get_all_field_ids(),
Self::MulFloat(ins) => ins.get_all_field_ids(),
Self::DivFloat(ins) => ins.get_all_field_ids(),
Self::RemFloat(ins) => ins.get_all_field_ids(),
Self::AddDouble(ins) => ins.get_all_field_ids(),
Self::SubDouble(ins) => ins.get_all_field_ids(),
Self::MulDouble(ins) => ins.get_all_field_ids(),
Self::DivDouble(ins) => ins.get_all_field_ids(),
Self::RemDouble(ins) => ins.get_all_field_ids(),
Self::AddInt2Addr(ins) => ins.get_all_field_ids(),
Self::SubInt2Addr(ins) => ins.get_all_field_ids(),
Self::MulInt2Addr(ins) => ins.get_all_field_ids(),
Self::DivInt2Addr(ins) => ins.get_all_field_ids(),
Self::RemInt2Addr(ins) => ins.get_all_field_ids(),
Self::AndInt2Addr(ins) => ins.get_all_field_ids(),
Self::OrInt2Addr(ins) => ins.get_all_field_ids(),
Self::XorInt2Addr(ins) => ins.get_all_field_ids(),
Self::ShlInt2Addr(ins) => ins.get_all_field_ids(),
Self::ShrInt2Addr(ins) => ins.get_all_field_ids(),
Self::UshrInt2Addr(ins) => ins.get_all_field_ids(),
Self::AddLong2Addr(ins) => ins.get_all_field_ids(),
Self::SubLong2Addr(ins) => ins.get_all_field_ids(),
Self::MulLong2Addr(ins) => ins.get_all_field_ids(),
Self::DivLong2Addr(ins) => ins.get_all_field_ids(),
Self::RemLong2Addr(ins) => ins.get_all_field_ids(),
Self::AndLong2Addr(ins) => ins.get_all_field_ids(),
Self::OrLong2Addr(ins) => ins.get_all_field_ids(),
Self::XorLong2Addr(ins) => ins.get_all_field_ids(),
Self::ShlLong2Addr(ins) => ins.get_all_field_ids(),
Self::ShrLong2Addr(ins) => ins.get_all_field_ids(),
Self::UshrLong2Addr(ins) => ins.get_all_field_ids(),
Self::AddFloat2Addr(ins) => ins.get_all_field_ids(),
Self::SubFloat2Addr(ins) => ins.get_all_field_ids(),
Self::MulFloat2Addr(ins) => ins.get_all_field_ids(),
Self::DivFloat2Addr(ins) => ins.get_all_field_ids(),
Self::RemFloat2Addr(ins) => ins.get_all_field_ids(),
Self::AddDouble2Addr(ins) => ins.get_all_field_ids(),
Self::SubDouble2Addr(ins) => ins.get_all_field_ids(),
Self::MulDouble2Addr(ins) => ins.get_all_field_ids(),
Self::DivDouble2Addr(ins) => ins.get_all_field_ids(),
Self::RemDouble2Addr(ins) => ins.get_all_field_ids(),
Self::AddIntLit(ins) => ins.get_all_field_ids(),
Self::RsubIntLit(ins) => ins.get_all_field_ids(),
Self::MulIntLit(ins) => ins.get_all_field_ids(),
Self::DivIntLit(ins) => ins.get_all_field_ids(),
Self::RemIntLit(ins) => ins.get_all_field_ids(),
Self::AndIntLit(ins) => ins.get_all_field_ids(),
Self::OrIntLit(ins) => ins.get_all_field_ids(),
Self::XorIntLit(ins) => ins.get_all_field_ids(),
Self::ShlIntLit(ins) => ins.get_all_field_ids(),
Self::ShrIntLit(ins) => ins.get_all_field_ids(),
Self::UshrIntLit(ins) => ins.get_all_field_ids(),
Self::InvokePolymorphic(ins) => ins.get_all_field_ids(),
Self::InvokeCustom(ins) => ins.get_all_field_ids(),
Self::ConstMethodHandle(ins) => ins.get_all_field_ids(),
Self::ConstMethodType(ins) => ins.get_all_field_ids(),
Self::Try(ins) => ins.get_all_field_ids(),
Self::Label(ins) => ins.get_all_field_ids(),
}
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
match self {
Self::Nop(ins) => ins.get_all_method_ids(),
Self::Move(ins) => ins.get_all_method_ids(),
Self::MoveWide(ins) => ins.get_all_method_ids(),
Self::MoveObject(ins) => ins.get_all_method_ids(),
Self::MoveResult(ins) => ins.get_all_method_ids(),
Self::MoveResultWide(ins) => ins.get_all_method_ids(),
Self::MoveException(ins) => ins.get_all_method_ids(),
Self::MoveResultObject(ins) => ins.get_all_method_ids(),
Self::ReturnVoid(ins) => ins.get_all_method_ids(),
Self::Return(ins) => ins.get_all_method_ids(),
Self::ReturnWide(ins) => ins.get_all_method_ids(),
Self::ReturnObject(ins) => ins.get_all_method_ids(),
Self::Const(ins) => ins.get_all_method_ids(),
Self::ConstWide(ins) => ins.get_all_method_ids(),
Self::ConstString(ins) => ins.get_all_method_ids(),
Self::ConstClass(ins) => ins.get_all_method_ids(),
Self::MonitorEnter(ins) => ins.get_all_method_ids(),
Self::MonitorExit(ins) => ins.get_all_method_ids(),
Self::CheckCast(ins) => ins.get_all_method_ids(),
Self::InstanceOf(ins) => ins.get_all_method_ids(),
Self::ArrayLength(ins) => ins.get_all_method_ids(),
Self::NewInstance(ins) => ins.get_all_method_ids(),
Self::NewArray(ins) => ins.get_all_method_ids(),
Self::FilledNewArray(ins) => ins.get_all_method_ids(),
Self::FillArrayData(ins) => ins.get_all_method_ids(),
Self::Throw(ins) => ins.get_all_method_ids(),
Self::Goto(ins) => ins.get_all_method_ids(),
Self::Switch(ins) => ins.get_all_method_ids(),
Self::CmpLFloat(ins) => ins.get_all_method_ids(),
Self::CmpGFloat(ins) => ins.get_all_method_ids(),
Self::CmpLDouble(ins) => ins.get_all_method_ids(),
Self::CmpGDouble(ins) => ins.get_all_method_ids(),
Self::CmpLong(ins) => ins.get_all_method_ids(),
Self::IfEq(ins) => ins.get_all_method_ids(),
Self::IfNe(ins) => ins.get_all_method_ids(),
Self::IfLt(ins) => ins.get_all_method_ids(),
Self::IfGe(ins) => ins.get_all_method_ids(),
Self::IfGt(ins) => ins.get_all_method_ids(),
Self::IfLe(ins) => ins.get_all_method_ids(),
Self::IfEqZ(ins) => ins.get_all_method_ids(),
Self::IfNeZ(ins) => ins.get_all_method_ids(),
Self::IfLtZ(ins) => ins.get_all_method_ids(),
Self::IfGeZ(ins) => ins.get_all_method_ids(),
Self::IfGtZ(ins) => ins.get_all_method_ids(),
Self::IfLeZ(ins) => ins.get_all_method_ids(),
Self::AGet(ins) => ins.get_all_method_ids(),
Self::AGetWide(ins) => ins.get_all_method_ids(),
Self::AGetObject(ins) => ins.get_all_method_ids(),
Self::AGetBoolean(ins) => ins.get_all_method_ids(),
Self::AGetByte(ins) => ins.get_all_method_ids(),
Self::AGetChar(ins) => ins.get_all_method_ids(),
Self::AGetShort(ins) => ins.get_all_method_ids(),
Self::APut(ins) => ins.get_all_method_ids(),
Self::APutWide(ins) => ins.get_all_method_ids(),
Self::APutObject(ins) => ins.get_all_method_ids(),
Self::APutBoolean(ins) => ins.get_all_method_ids(),
Self::APutByte(ins) => ins.get_all_method_ids(),
Self::APutChar(ins) => ins.get_all_method_ids(),
Self::APutShort(ins) => ins.get_all_method_ids(),
Self::IGet(ins) => ins.get_all_method_ids(),
Self::IGetWide(ins) => ins.get_all_method_ids(),
Self::IGetObject(ins) => ins.get_all_method_ids(),
Self::IGetBoolean(ins) => ins.get_all_method_ids(),
Self::IGetByte(ins) => ins.get_all_method_ids(),
Self::IGetChar(ins) => ins.get_all_method_ids(),
Self::IGetShort(ins) => ins.get_all_method_ids(),
Self::IPut(ins) => ins.get_all_method_ids(),
Self::IPutWide(ins) => ins.get_all_method_ids(),
Self::IPutObject(ins) => ins.get_all_method_ids(),
Self::IPutBoolean(ins) => ins.get_all_method_ids(),
Self::IPutByte(ins) => ins.get_all_method_ids(),
Self::IPutChar(ins) => ins.get_all_method_ids(),
Self::IPutShort(ins) => ins.get_all_method_ids(),
Self::SGet(ins) => ins.get_all_method_ids(),
Self::SGetWide(ins) => ins.get_all_method_ids(),
Self::SGetObject(ins) => ins.get_all_method_ids(),
Self::SGetBoolean(ins) => ins.get_all_method_ids(),
Self::SGetByte(ins) => ins.get_all_method_ids(),
Self::SGetChar(ins) => ins.get_all_method_ids(),
Self::SGetShort(ins) => ins.get_all_method_ids(),
Self::SPut(ins) => ins.get_all_method_ids(),
Self::SPutWide(ins) => ins.get_all_method_ids(),
Self::SPutObject(ins) => ins.get_all_method_ids(),
Self::SPutBoolean(ins) => ins.get_all_method_ids(),
Self::SPutByte(ins) => ins.get_all_method_ids(),
Self::SPutChar(ins) => ins.get_all_method_ids(),
Self::SPutShort(ins) => ins.get_all_method_ids(),
Self::InvokeVirtual(ins) => ins.get_all_method_ids(),
Self::InvokeSuper(ins) => ins.get_all_method_ids(),
Self::InvokeDirect(ins) => ins.get_all_method_ids(),
Self::InvokeStatic(ins) => ins.get_all_method_ids(),
Self::InvokeInterface(ins) => ins.get_all_method_ids(),
Self::NegInt(ins) => ins.get_all_method_ids(),
Self::NotInt(ins) => ins.get_all_method_ids(),
Self::NegLong(ins) => ins.get_all_method_ids(),
Self::NotLong(ins) => ins.get_all_method_ids(),
Self::NegFloat(ins) => ins.get_all_method_ids(),
Self::NegDouble(ins) => ins.get_all_method_ids(),
Self::IntToLong(ins) => ins.get_all_method_ids(),
Self::IntToFloat(ins) => ins.get_all_method_ids(),
Self::IntToDouble(ins) => ins.get_all_method_ids(),
Self::LongToInt(ins) => ins.get_all_method_ids(),
Self::LongToFloat(ins) => ins.get_all_method_ids(),
Self::LongToDouble(ins) => ins.get_all_method_ids(),
Self::FloatToInt(ins) => ins.get_all_method_ids(),
Self::FloatToLong(ins) => ins.get_all_method_ids(),
Self::FloatToDouble(ins) => ins.get_all_method_ids(),
Self::DoubleToInt(ins) => ins.get_all_method_ids(),
Self::DoubleToLong(ins) => ins.get_all_method_ids(),
Self::DoubleToFloat(ins) => ins.get_all_method_ids(),
Self::IntToByte(ins) => ins.get_all_method_ids(),
Self::IntToChar(ins) => ins.get_all_method_ids(),
Self::IntToShort(ins) => ins.get_all_method_ids(),
Self::AddInt(ins) => ins.get_all_method_ids(),
Self::SubInt(ins) => ins.get_all_method_ids(),
Self::MulInt(ins) => ins.get_all_method_ids(),
Self::DivInt(ins) => ins.get_all_method_ids(),
Self::RemInt(ins) => ins.get_all_method_ids(),
Self::AndInt(ins) => ins.get_all_method_ids(),
Self::OrInt(ins) => ins.get_all_method_ids(),
Self::XorInt(ins) => ins.get_all_method_ids(),
Self::ShlInt(ins) => ins.get_all_method_ids(),
Self::ShrInt(ins) => ins.get_all_method_ids(),
Self::UshrInt(ins) => ins.get_all_method_ids(),
Self::AddLong(ins) => ins.get_all_method_ids(),
Self::SubLong(ins) => ins.get_all_method_ids(),
Self::MulLong(ins) => ins.get_all_method_ids(),
Self::DivLong(ins) => ins.get_all_method_ids(),
Self::RemLong(ins) => ins.get_all_method_ids(),
Self::AndLong(ins) => ins.get_all_method_ids(),
Self::OrLong(ins) => ins.get_all_method_ids(),
Self::XorLong(ins) => ins.get_all_method_ids(),
Self::ShlLong(ins) => ins.get_all_method_ids(),
Self::ShrLong(ins) => ins.get_all_method_ids(),
Self::UshrLong(ins) => ins.get_all_method_ids(),
Self::AddFloat(ins) => ins.get_all_method_ids(),
Self::SubFloat(ins) => ins.get_all_method_ids(),
Self::MulFloat(ins) => ins.get_all_method_ids(),
Self::DivFloat(ins) => ins.get_all_method_ids(),
Self::RemFloat(ins) => ins.get_all_method_ids(),
Self::AddDouble(ins) => ins.get_all_method_ids(),
Self::SubDouble(ins) => ins.get_all_method_ids(),
Self::MulDouble(ins) => ins.get_all_method_ids(),
Self::DivDouble(ins) => ins.get_all_method_ids(),
Self::RemDouble(ins) => ins.get_all_method_ids(),
Self::AddInt2Addr(ins) => ins.get_all_method_ids(),
Self::SubInt2Addr(ins) => ins.get_all_method_ids(),
Self::MulInt2Addr(ins) => ins.get_all_method_ids(),
Self::DivInt2Addr(ins) => ins.get_all_method_ids(),
Self::RemInt2Addr(ins) => ins.get_all_method_ids(),
Self::AndInt2Addr(ins) => ins.get_all_method_ids(),
Self::OrInt2Addr(ins) => ins.get_all_method_ids(),
Self::XorInt2Addr(ins) => ins.get_all_method_ids(),
Self::ShlInt2Addr(ins) => ins.get_all_method_ids(),
Self::ShrInt2Addr(ins) => ins.get_all_method_ids(),
Self::UshrInt2Addr(ins) => ins.get_all_method_ids(),
Self::AddLong2Addr(ins) => ins.get_all_method_ids(),
Self::SubLong2Addr(ins) => ins.get_all_method_ids(),
Self::MulLong2Addr(ins) => ins.get_all_method_ids(),
Self::DivLong2Addr(ins) => ins.get_all_method_ids(),
Self::RemLong2Addr(ins) => ins.get_all_method_ids(),
Self::AndLong2Addr(ins) => ins.get_all_method_ids(),
Self::OrLong2Addr(ins) => ins.get_all_method_ids(),
Self::XorLong2Addr(ins) => ins.get_all_method_ids(),
Self::ShlLong2Addr(ins) => ins.get_all_method_ids(),
Self::ShrLong2Addr(ins) => ins.get_all_method_ids(),
Self::UshrLong2Addr(ins) => ins.get_all_method_ids(),
Self::AddFloat2Addr(ins) => ins.get_all_method_ids(),
Self::SubFloat2Addr(ins) => ins.get_all_method_ids(),
Self::MulFloat2Addr(ins) => ins.get_all_method_ids(),
Self::DivFloat2Addr(ins) => ins.get_all_method_ids(),
Self::RemFloat2Addr(ins) => ins.get_all_method_ids(),
Self::AddDouble2Addr(ins) => ins.get_all_method_ids(),
Self::SubDouble2Addr(ins) => ins.get_all_method_ids(),
Self::MulDouble2Addr(ins) => ins.get_all_method_ids(),
Self::DivDouble2Addr(ins) => ins.get_all_method_ids(),
Self::RemDouble2Addr(ins) => ins.get_all_method_ids(),
Self::AddIntLit(ins) => ins.get_all_method_ids(),
Self::RsubIntLit(ins) => ins.get_all_method_ids(),
Self::MulIntLit(ins) => ins.get_all_method_ids(),
Self::DivIntLit(ins) => ins.get_all_method_ids(),
Self::RemIntLit(ins) => ins.get_all_method_ids(),
Self::AndIntLit(ins) => ins.get_all_method_ids(),
Self::OrIntLit(ins) => ins.get_all_method_ids(),
Self::XorIntLit(ins) => ins.get_all_method_ids(),
Self::ShlIntLit(ins) => ins.get_all_method_ids(),
Self::ShrIntLit(ins) => ins.get_all_method_ids(),
Self::UshrIntLit(ins) => ins.get_all_method_ids(),
Self::InvokePolymorphic(ins) => ins.get_all_method_ids(),
Self::InvokeCustom(ins) => ins.get_all_method_ids(),
Self::ConstMethodHandle(ins) => ins.get_all_method_ids(),
Self::ConstMethodType(ins) => ins.get_all_method_ids(),
Self::Try(ins) => ins.get_all_method_ids(),
Self::Label(ins) => ins.get_all_method_ids(),
}
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
match self {
Self::Nop(ins) => ins.get_all_method_handles(),
Self::Move(ins) => ins.get_all_method_handles(),
Self::MoveWide(ins) => ins.get_all_method_handles(),
Self::MoveObject(ins) => ins.get_all_method_handles(),
Self::MoveResult(ins) => ins.get_all_method_handles(),
Self::MoveResultWide(ins) => ins.get_all_method_handles(),
Self::MoveException(ins) => ins.get_all_method_handles(),
Self::MoveResultObject(ins) => ins.get_all_method_handles(),
Self::ReturnVoid(ins) => ins.get_all_method_handles(),
Self::Return(ins) => ins.get_all_method_handles(),
Self::ReturnWide(ins) => ins.get_all_method_handles(),
Self::ReturnObject(ins) => ins.get_all_method_handles(),
Self::Const(ins) => ins.get_all_method_handles(),
Self::ConstWide(ins) => ins.get_all_method_handles(),
Self::ConstString(ins) => ins.get_all_method_handles(),
Self::ConstClass(ins) => ins.get_all_method_handles(),
Self::MonitorEnter(ins) => ins.get_all_method_handles(),
Self::MonitorExit(ins) => ins.get_all_method_handles(),
Self::CheckCast(ins) => ins.get_all_method_handles(),
Self::InstanceOf(ins) => ins.get_all_method_handles(),
Self::ArrayLength(ins) => ins.get_all_method_handles(),
Self::NewInstance(ins) => ins.get_all_method_handles(),
Self::NewArray(ins) => ins.get_all_method_handles(),
Self::FilledNewArray(ins) => ins.get_all_method_handles(),
Self::FillArrayData(ins) => ins.get_all_method_handles(),
Self::Throw(ins) => ins.get_all_method_handles(),
Self::Goto(ins) => ins.get_all_method_handles(),
Self::Switch(ins) => ins.get_all_method_handles(),
Self::CmpLFloat(ins) => ins.get_all_method_handles(),
Self::CmpGFloat(ins) => ins.get_all_method_handles(),
Self::CmpLDouble(ins) => ins.get_all_method_handles(),
Self::CmpGDouble(ins) => ins.get_all_method_handles(),
Self::CmpLong(ins) => ins.get_all_method_handles(),
Self::IfEq(ins) => ins.get_all_method_handles(),
Self::IfNe(ins) => ins.get_all_method_handles(),
Self::IfLt(ins) => ins.get_all_method_handles(),
Self::IfGe(ins) => ins.get_all_method_handles(),
Self::IfGt(ins) => ins.get_all_method_handles(),
Self::IfLe(ins) => ins.get_all_method_handles(),
Self::IfEqZ(ins) => ins.get_all_method_handles(),
Self::IfNeZ(ins) => ins.get_all_method_handles(),
Self::IfLtZ(ins) => ins.get_all_method_handles(),
Self::IfGeZ(ins) => ins.get_all_method_handles(),
Self::IfGtZ(ins) => ins.get_all_method_handles(),
Self::IfLeZ(ins) => ins.get_all_method_handles(),
Self::AGet(ins) => ins.get_all_method_handles(),
Self::AGetWide(ins) => ins.get_all_method_handles(),
Self::AGetObject(ins) => ins.get_all_method_handles(),
Self::AGetBoolean(ins) => ins.get_all_method_handles(),
Self::AGetByte(ins) => ins.get_all_method_handles(),
Self::AGetChar(ins) => ins.get_all_method_handles(),
Self::AGetShort(ins) => ins.get_all_method_handles(),
Self::APut(ins) => ins.get_all_method_handles(),
Self::APutWide(ins) => ins.get_all_method_handles(),
Self::APutObject(ins) => ins.get_all_method_handles(),
Self::APutBoolean(ins) => ins.get_all_method_handles(),
Self::APutByte(ins) => ins.get_all_method_handles(),
Self::APutChar(ins) => ins.get_all_method_handles(),
Self::APutShort(ins) => ins.get_all_method_handles(),
Self::IGet(ins) => ins.get_all_method_handles(),
Self::IGetWide(ins) => ins.get_all_method_handles(),
Self::IGetObject(ins) => ins.get_all_method_handles(),
Self::IGetBoolean(ins) => ins.get_all_method_handles(),
Self::IGetByte(ins) => ins.get_all_method_handles(),
Self::IGetChar(ins) => ins.get_all_method_handles(),
Self::IGetShort(ins) => ins.get_all_method_handles(),
Self::IPut(ins) => ins.get_all_method_handles(),
Self::IPutWide(ins) => ins.get_all_method_handles(),
Self::IPutObject(ins) => ins.get_all_method_handles(),
Self::IPutBoolean(ins) => ins.get_all_method_handles(),
Self::IPutByte(ins) => ins.get_all_method_handles(),
Self::IPutChar(ins) => ins.get_all_method_handles(),
Self::IPutShort(ins) => ins.get_all_method_handles(),
Self::SGet(ins) => ins.get_all_method_handles(),
Self::SGetWide(ins) => ins.get_all_method_handles(),
Self::SGetObject(ins) => ins.get_all_method_handles(),
Self::SGetBoolean(ins) => ins.get_all_method_handles(),
Self::SGetByte(ins) => ins.get_all_method_handles(),
Self::SGetChar(ins) => ins.get_all_method_handles(),
Self::SGetShort(ins) => ins.get_all_method_handles(),
Self::SPut(ins) => ins.get_all_method_handles(),
Self::SPutWide(ins) => ins.get_all_method_handles(),
Self::SPutObject(ins) => ins.get_all_method_handles(),
Self::SPutBoolean(ins) => ins.get_all_method_handles(),
Self::SPutByte(ins) => ins.get_all_method_handles(),
Self::SPutChar(ins) => ins.get_all_method_handles(),
Self::SPutShort(ins) => ins.get_all_method_handles(),
Self::InvokeVirtual(ins) => ins.get_all_method_handles(),
Self::InvokeSuper(ins) => ins.get_all_method_handles(),
Self::InvokeDirect(ins) => ins.get_all_method_handles(),
Self::InvokeStatic(ins) => ins.get_all_method_handles(),
Self::InvokeInterface(ins) => ins.get_all_method_handles(),
Self::NegInt(ins) => ins.get_all_method_handles(),
Self::NotInt(ins) => ins.get_all_method_handles(),
Self::NegLong(ins) => ins.get_all_method_handles(),
Self::NotLong(ins) => ins.get_all_method_handles(),
Self::NegFloat(ins) => ins.get_all_method_handles(),
Self::NegDouble(ins) => ins.get_all_method_handles(),
Self::IntToLong(ins) => ins.get_all_method_handles(),
Self::IntToFloat(ins) => ins.get_all_method_handles(),
Self::IntToDouble(ins) => ins.get_all_method_handles(),
Self::LongToInt(ins) => ins.get_all_method_handles(),
Self::LongToFloat(ins) => ins.get_all_method_handles(),
Self::LongToDouble(ins) => ins.get_all_method_handles(),
Self::FloatToInt(ins) => ins.get_all_method_handles(),
Self::FloatToLong(ins) => ins.get_all_method_handles(),
Self::FloatToDouble(ins) => ins.get_all_method_handles(),
Self::DoubleToInt(ins) => ins.get_all_method_handles(),
Self::DoubleToLong(ins) => ins.get_all_method_handles(),
Self::DoubleToFloat(ins) => ins.get_all_method_handles(),
Self::IntToByte(ins) => ins.get_all_method_handles(),
Self::IntToChar(ins) => ins.get_all_method_handles(),
Self::IntToShort(ins) => ins.get_all_method_handles(),
Self::AddInt(ins) => ins.get_all_method_handles(),
Self::SubInt(ins) => ins.get_all_method_handles(),
Self::MulInt(ins) => ins.get_all_method_handles(),
Self::DivInt(ins) => ins.get_all_method_handles(),
Self::RemInt(ins) => ins.get_all_method_handles(),
Self::AndInt(ins) => ins.get_all_method_handles(),
Self::OrInt(ins) => ins.get_all_method_handles(),
Self::XorInt(ins) => ins.get_all_method_handles(),
Self::ShlInt(ins) => ins.get_all_method_handles(),
Self::ShrInt(ins) => ins.get_all_method_handles(),
Self::UshrInt(ins) => ins.get_all_method_handles(),
Self::AddLong(ins) => ins.get_all_method_handles(),
Self::SubLong(ins) => ins.get_all_method_handles(),
Self::MulLong(ins) => ins.get_all_method_handles(),
Self::DivLong(ins) => ins.get_all_method_handles(),
Self::RemLong(ins) => ins.get_all_method_handles(),
Self::AndLong(ins) => ins.get_all_method_handles(),
Self::OrLong(ins) => ins.get_all_method_handles(),
Self::XorLong(ins) => ins.get_all_method_handles(),
Self::ShlLong(ins) => ins.get_all_method_handles(),
Self::ShrLong(ins) => ins.get_all_method_handles(),
Self::UshrLong(ins) => ins.get_all_method_handles(),
Self::AddFloat(ins) => ins.get_all_method_handles(),
Self::SubFloat(ins) => ins.get_all_method_handles(),
Self::MulFloat(ins) => ins.get_all_method_handles(),
Self::DivFloat(ins) => ins.get_all_method_handles(),
Self::RemFloat(ins) => ins.get_all_method_handles(),
Self::AddDouble(ins) => ins.get_all_method_handles(),
Self::SubDouble(ins) => ins.get_all_method_handles(),
Self::MulDouble(ins) => ins.get_all_method_handles(),
Self::DivDouble(ins) => ins.get_all_method_handles(),
Self::RemDouble(ins) => ins.get_all_method_handles(),
Self::AddInt2Addr(ins) => ins.get_all_method_handles(),
Self::SubInt2Addr(ins) => ins.get_all_method_handles(),
Self::MulInt2Addr(ins) => ins.get_all_method_handles(),
Self::DivInt2Addr(ins) => ins.get_all_method_handles(),
Self::RemInt2Addr(ins) => ins.get_all_method_handles(),
Self::AndInt2Addr(ins) => ins.get_all_method_handles(),
Self::OrInt2Addr(ins) => ins.get_all_method_handles(),
Self::XorInt2Addr(ins) => ins.get_all_method_handles(),
Self::ShlInt2Addr(ins) => ins.get_all_method_handles(),
Self::ShrInt2Addr(ins) => ins.get_all_method_handles(),
Self::UshrInt2Addr(ins) => ins.get_all_method_handles(),
Self::AddLong2Addr(ins) => ins.get_all_method_handles(),
Self::SubLong2Addr(ins) => ins.get_all_method_handles(),
Self::MulLong2Addr(ins) => ins.get_all_method_handles(),
Self::DivLong2Addr(ins) => ins.get_all_method_handles(),
Self::RemLong2Addr(ins) => ins.get_all_method_handles(),
Self::AndLong2Addr(ins) => ins.get_all_method_handles(),
Self::OrLong2Addr(ins) => ins.get_all_method_handles(),
Self::XorLong2Addr(ins) => ins.get_all_method_handles(),
Self::ShlLong2Addr(ins) => ins.get_all_method_handles(),
Self::ShrLong2Addr(ins) => ins.get_all_method_handles(),
Self::UshrLong2Addr(ins) => ins.get_all_method_handles(),
Self::AddFloat2Addr(ins) => ins.get_all_method_handles(),
Self::SubFloat2Addr(ins) => ins.get_all_method_handles(),
Self::MulFloat2Addr(ins) => ins.get_all_method_handles(),
Self::DivFloat2Addr(ins) => ins.get_all_method_handles(),
Self::RemFloat2Addr(ins) => ins.get_all_method_handles(),
Self::AddDouble2Addr(ins) => ins.get_all_method_handles(),
Self::SubDouble2Addr(ins) => ins.get_all_method_handles(),
Self::MulDouble2Addr(ins) => ins.get_all_method_handles(),
Self::DivDouble2Addr(ins) => ins.get_all_method_handles(),
Self::RemDouble2Addr(ins) => ins.get_all_method_handles(),
Self::AddIntLit(ins) => ins.get_all_method_handles(),
Self::RsubIntLit(ins) => ins.get_all_method_handles(),
Self::MulIntLit(ins) => ins.get_all_method_handles(),
Self::DivIntLit(ins) => ins.get_all_method_handles(),
Self::RemIntLit(ins) => ins.get_all_method_handles(),
Self::AndIntLit(ins) => ins.get_all_method_handles(),
Self::OrIntLit(ins) => ins.get_all_method_handles(),
Self::XorIntLit(ins) => ins.get_all_method_handles(),
Self::ShlIntLit(ins) => ins.get_all_method_handles(),
Self::ShrIntLit(ins) => ins.get_all_method_handles(),
Self::UshrIntLit(ins) => ins.get_all_method_handles(),
Self::InvokePolymorphic(ins) => ins.get_all_method_handles(),
Self::InvokeCustom(ins) => ins.get_all_method_handles(),
Self::ConstMethodHandle(ins) => ins.get_all_method_handles(),
Self::ConstMethodType(ins) => ins.get_all_method_handles(),
Self::Try(ins) => ins.get_all_method_handles(),
Self::Label(ins) => ins.get_all_method_handles(),
}
}
}
impl<'source> FromPyObject<'source> for Instruction {
fn extract(ob: &'source PyAny) -> PyResult<Self> {
if let Ok(ins) = Nop::extract(ob) {
Ok(Self::Nop(ins))
} else if let Ok(ins) = Move::extract(ob) {
Ok(Self::Move(ins))
} else if let Ok(ins) = MoveWide::extract(ob) {
Ok(Self::MoveWide(ins))
} else if let Ok(ins) = MoveObject::extract(ob) {
Ok(Self::MoveObject(ins))
} else if let Ok(ins) = MoveResult::extract(ob) {
Ok(Self::MoveResult(ins))
} else if let Ok(ins) = MoveResultWide::extract(ob) {
Ok(Self::MoveResultWide(ins))
} else if let Ok(ins) = MoveException::extract(ob) {
Ok(Self::MoveException(ins))
} else if let Ok(ins) = MoveResultObject::extract(ob) {
Ok(Self::MoveResultObject(ins))
} else if let Ok(ins) = ReturnVoid::extract(ob) {
Ok(Self::ReturnVoid(ins))
} else if let Ok(ins) = Return::extract(ob) {
Ok(Self::Return(ins))
} else if let Ok(ins) = ReturnWide::extract(ob) {
Ok(Self::ReturnWide(ins))
} else if let Ok(ins) = ReturnObject::extract(ob) {
Ok(Self::ReturnObject(ins))
} else if let Ok(ins) = Const::extract(ob) {
Ok(Self::Const(ins))
} else if let Ok(ins) = ConstWide::extract(ob) {
Ok(Self::ConstWide(ins))
} else if let Ok(ins) = ConstString::extract(ob) {
Ok(Self::ConstString(ins))
} else if let Ok(ins) = ConstClass::extract(ob) {
Ok(Self::ConstClass(ins))
} else if let Ok(ins) = MonitorEnter::extract(ob) {
Ok(Self::MonitorEnter(ins))
} else if let Ok(ins) = MonitorExit::extract(ob) {
Ok(Self::MonitorExit(ins))
} else if let Ok(ins) = CheckCast::extract(ob) {
Ok(Self::CheckCast(ins))
} else if let Ok(ins) = InstanceOf::extract(ob) {
Ok(Self::InstanceOf(ins))
} else if let Ok(ins) = ArrayLength::extract(ob) {
Ok(Self::ArrayLength(ins))
} else if let Ok(ins) = NewInstance::extract(ob) {
Ok(Self::NewInstance(ins))
} else if let Ok(ins) = NewArray::extract(ob) {
Ok(Self::NewArray(ins))
} else if let Ok(ins) = FilledNewArray::extract(ob) {
Ok(Self::FilledNewArray(ins))
} else if let Ok(ins) = FillArrayData::extract(ob) {
Ok(Self::FillArrayData(ins))
} else if let Ok(ins) = Throw::extract(ob) {
Ok(Self::Throw(ins))
} else if let Ok(ins) = Goto::extract(ob) {
Ok(Self::Goto(ins))
} else if let Ok(ins) = Switch::extract(ob) {
Ok(Self::Switch(ins))
} else if let Ok(ins) = CmpLFloat::extract(ob) {
Ok(Self::CmpLFloat(ins))
} else if let Ok(ins) = CmpGFloat::extract(ob) {
Ok(Self::CmpGFloat(ins))
} else if let Ok(ins) = CmpLDouble::extract(ob) {
Ok(Self::CmpLDouble(ins))
} else if let Ok(ins) = CmpGDouble::extract(ob) {
Ok(Self::CmpGDouble(ins))
} else if let Ok(ins) = CmpLong::extract(ob) {
Ok(Self::CmpLong(ins))
} else if let Ok(ins) = IfEq::extract(ob) {
Ok(Self::IfEq(ins))
} else if let Ok(ins) = IfNe::extract(ob) {
Ok(Self::IfNe(ins))
} else if let Ok(ins) = IfLt::extract(ob) {
Ok(Self::IfLt(ins))
} else if let Ok(ins) = IfGe::extract(ob) {
Ok(Self::IfGe(ins))
} else if let Ok(ins) = IfGt::extract(ob) {
Ok(Self::IfGt(ins))
} else if let Ok(ins) = IfLe::extract(ob) {
Ok(Self::IfLe(ins))
} else if let Ok(ins) = IfEqZ::extract(ob) {
Ok(Self::IfEqZ(ins))
} else if let Ok(ins) = IfNeZ::extract(ob) {
Ok(Self::IfNeZ(ins))
} else if let Ok(ins) = IfLtZ::extract(ob) {
Ok(Self::IfLtZ(ins))
} else if let Ok(ins) = IfGeZ::extract(ob) {
Ok(Self::IfGeZ(ins))
} else if let Ok(ins) = IfGtZ::extract(ob) {
Ok(Self::IfGtZ(ins))
} else if let Ok(ins) = IfLeZ::extract(ob) {
Ok(Self::IfLeZ(ins))
} else if let Ok(ins) = AGet::extract(ob) {
Ok(Self::AGet(ins))
} else if let Ok(ins) = AGetWide::extract(ob) {
Ok(Self::AGetWide(ins))
} else if let Ok(ins) = AGetObject::extract(ob) {
Ok(Self::AGetObject(ins))
} else if let Ok(ins) = AGetBoolean::extract(ob) {
Ok(Self::AGetBoolean(ins))
} else if let Ok(ins) = AGetByte::extract(ob) {
Ok(Self::AGetByte(ins))
} else if let Ok(ins) = AGetChar::extract(ob) {
Ok(Self::AGetChar(ins))
} else if let Ok(ins) = AGetShort::extract(ob) {
Ok(Self::AGetShort(ins))
} else if let Ok(ins) = APut::extract(ob) {
Ok(Self::APut(ins))
} else if let Ok(ins) = APutWide::extract(ob) {
Ok(Self::APutWide(ins))
} else if let Ok(ins) = APutObject::extract(ob) {
Ok(Self::APutObject(ins))
} else if let Ok(ins) = APutBoolean::extract(ob) {
Ok(Self::APutBoolean(ins))
} else if let Ok(ins) = APutByte::extract(ob) {
Ok(Self::APutByte(ins))
} else if let Ok(ins) = APutChar::extract(ob) {
Ok(Self::APutChar(ins))
} else if let Ok(ins) = APutShort::extract(ob) {
Ok(Self::APutShort(ins))
} else if let Ok(ins) = IGet::extract(ob) {
Ok(Self::IGet(ins))
} else if let Ok(ins) = IGetWide::extract(ob) {
Ok(Self::IGetWide(ins))
} else if let Ok(ins) = IGetObject::extract(ob) {
Ok(Self::IGetObject(ins))
} else if let Ok(ins) = IGetBoolean::extract(ob) {
Ok(Self::IGetBoolean(ins))
} else if let Ok(ins) = IGetByte::extract(ob) {
Ok(Self::IGetByte(ins))
} else if let Ok(ins) = IGetChar::extract(ob) {
Ok(Self::IGetChar(ins))
} else if let Ok(ins) = IGetShort::extract(ob) {
Ok(Self::IGetShort(ins))
} else if let Ok(ins) = IPut::extract(ob) {
Ok(Self::IPut(ins))
} else if let Ok(ins) = IPutWide::extract(ob) {
Ok(Self::IPutWide(ins))
} else if let Ok(ins) = IPutObject::extract(ob) {
Ok(Self::IPutObject(ins))
} else if let Ok(ins) = IPutBoolean::extract(ob) {
Ok(Self::IPutBoolean(ins))
} else if let Ok(ins) = IPutByte::extract(ob) {
Ok(Self::IPutByte(ins))
} else if let Ok(ins) = IPutChar::extract(ob) {
Ok(Self::IPutChar(ins))
} else if let Ok(ins) = IPutShort::extract(ob) {
Ok(Self::IPutShort(ins))
} else if let Ok(ins) = SGet::extract(ob) {
Ok(Self::SGet(ins))
} else if let Ok(ins) = SGetWide::extract(ob) {
Ok(Self::SGetWide(ins))
} else if let Ok(ins) = SGetObject::extract(ob) {
Ok(Self::SGetObject(ins))
} else if let Ok(ins) = SGetBoolean::extract(ob) {
Ok(Self::SGetBoolean(ins))
} else if let Ok(ins) = SGetByte::extract(ob) {
Ok(Self::SGetByte(ins))
} else if let Ok(ins) = SGetChar::extract(ob) {
Ok(Self::SGetChar(ins))
} else if let Ok(ins) = SGetShort::extract(ob) {
Ok(Self::SGetShort(ins))
} else if let Ok(ins) = SPut::extract(ob) {
Ok(Self::SPut(ins))
} else if let Ok(ins) = SPutWide::extract(ob) {
Ok(Self::SPutWide(ins))
} else if let Ok(ins) = SPutObject::extract(ob) {
Ok(Self::SPutObject(ins))
} else if let Ok(ins) = SPutBoolean::extract(ob) {
Ok(Self::SPutBoolean(ins))
} else if let Ok(ins) = SPutByte::extract(ob) {
Ok(Self::SPutByte(ins))
} else if let Ok(ins) = SPutChar::extract(ob) {
Ok(Self::SPutChar(ins))
} else if let Ok(ins) = SPutShort::extract(ob) {
Ok(Self::SPutShort(ins))
} else if let Ok(ins) = InvokeVirtual::extract(ob) {
Ok(Self::InvokeVirtual(ins))
} else if let Ok(ins) = InvokeSuper::extract(ob) {
Ok(Self::InvokeSuper(ins))
} else if let Ok(ins) = InvokeDirect::extract(ob) {
Ok(Self::InvokeDirect(ins))
} else if let Ok(ins) = InvokeStatic::extract(ob) {
Ok(Self::InvokeStatic(ins))
} else if let Ok(ins) = InvokeInterface::extract(ob) {
Ok(Self::InvokeInterface(ins))
} else if let Ok(ins) = NegInt::extract(ob) {
Ok(Self::NegInt(ins))
} else if let Ok(ins) = NotInt::extract(ob) {
Ok(Self::NotInt(ins))
} else if let Ok(ins) = NegLong::extract(ob) {
Ok(Self::NegLong(ins))
} else if let Ok(ins) = NotLong::extract(ob) {
Ok(Self::NotLong(ins))
} else if let Ok(ins) = NegFloat::extract(ob) {
Ok(Self::NegFloat(ins))
} else if let Ok(ins) = NegDouble::extract(ob) {
Ok(Self::NegDouble(ins))
} else if let Ok(ins) = IntToLong::extract(ob) {
Ok(Self::IntToLong(ins))
} else if let Ok(ins) = IntToFloat::extract(ob) {
Ok(Self::IntToFloat(ins))
} else if let Ok(ins) = IntToDouble::extract(ob) {
Ok(Self::IntToDouble(ins))
} else if let Ok(ins) = LongToInt::extract(ob) {
Ok(Self::LongToInt(ins))
} else if let Ok(ins) = LongToFloat::extract(ob) {
Ok(Self::LongToFloat(ins))
} else if let Ok(ins) = LongToDouble::extract(ob) {
Ok(Self::LongToDouble(ins))
} else if let Ok(ins) = FloatToInt::extract(ob) {
Ok(Self::FloatToInt(ins))
} else if let Ok(ins) = FloatToLong::extract(ob) {
Ok(Self::FloatToLong(ins))
} else if let Ok(ins) = FloatToDouble::extract(ob) {
Ok(Self::FloatToDouble(ins))
} else if let Ok(ins) = DoubleToInt::extract(ob) {
Ok(Self::DoubleToInt(ins))
} else if let Ok(ins) = DoubleToLong::extract(ob) {
Ok(Self::DoubleToLong(ins))
} else if let Ok(ins) = DoubleToFloat::extract(ob) {
Ok(Self::DoubleToFloat(ins))
} else if let Ok(ins) = IntToByte::extract(ob) {
Ok(Self::IntToByte(ins))
} else if let Ok(ins) = IntToChar::extract(ob) {
Ok(Self::IntToChar(ins))
} else if let Ok(ins) = IntToShort::extract(ob) {
Ok(Self::IntToShort(ins))
} else if let Ok(ins) = AddInt::extract(ob) {
Ok(Self::AddInt(ins))
} else if let Ok(ins) = SubInt::extract(ob) {
Ok(Self::SubInt(ins))
} else if let Ok(ins) = MulInt::extract(ob) {
Ok(Self::MulInt(ins))
} else if let Ok(ins) = DivInt::extract(ob) {
Ok(Self::DivInt(ins))
} else if let Ok(ins) = RemInt::extract(ob) {
Ok(Self::RemInt(ins))
} else if let Ok(ins) = AndInt::extract(ob) {
Ok(Self::AndInt(ins))
} else if let Ok(ins) = OrInt::extract(ob) {
Ok(Self::OrInt(ins))
} else if let Ok(ins) = XorInt::extract(ob) {
Ok(Self::XorInt(ins))
} else if let Ok(ins) = ShlInt::extract(ob) {
Ok(Self::ShlInt(ins))
} else if let Ok(ins) = ShrInt::extract(ob) {
Ok(Self::ShrInt(ins))
} else if let Ok(ins) = UshrInt::extract(ob) {
Ok(Self::UshrInt(ins))
} else if let Ok(ins) = AddLong::extract(ob) {
Ok(Self::AddLong(ins))
} else if let Ok(ins) = SubLong::extract(ob) {
Ok(Self::SubLong(ins))
} else if let Ok(ins) = MulLong::extract(ob) {
Ok(Self::MulLong(ins))
} else if let Ok(ins) = DivLong::extract(ob) {
Ok(Self::DivLong(ins))
} else if let Ok(ins) = RemLong::extract(ob) {
Ok(Self::RemLong(ins))
} else if let Ok(ins) = AndLong::extract(ob) {
Ok(Self::AndLong(ins))
} else if let Ok(ins) = OrLong::extract(ob) {
Ok(Self::OrLong(ins))
} else if let Ok(ins) = XorLong::extract(ob) {
Ok(Self::XorLong(ins))
} else if let Ok(ins) = ShlLong::extract(ob) {
Ok(Self::ShlLong(ins))
} else if let Ok(ins) = ShrLong::extract(ob) {
Ok(Self::ShrLong(ins))
} else if let Ok(ins) = UshrLong::extract(ob) {
Ok(Self::UshrLong(ins))
} else if let Ok(ins) = AddFloat::extract(ob) {
Ok(Self::AddFloat(ins))
} else if let Ok(ins) = SubFloat::extract(ob) {
Ok(Self::SubFloat(ins))
} else if let Ok(ins) = MulFloat::extract(ob) {
Ok(Self::MulFloat(ins))
} else if let Ok(ins) = DivFloat::extract(ob) {
Ok(Self::DivFloat(ins))
} else if let Ok(ins) = RemFloat::extract(ob) {
Ok(Self::RemFloat(ins))
} else if let Ok(ins) = AddDouble::extract(ob) {
Ok(Self::AddDouble(ins))
} else if let Ok(ins) = SubDouble::extract(ob) {
Ok(Self::SubDouble(ins))
} else if let Ok(ins) = MulDouble::extract(ob) {
Ok(Self::MulDouble(ins))
} else if let Ok(ins) = DivDouble::extract(ob) {
Ok(Self::DivDouble(ins))
} else if let Ok(ins) = RemDouble::extract(ob) {
Ok(Self::RemDouble(ins))
} else if let Ok(ins) = AddInt2Addr::extract(ob) {
Ok(Self::AddInt2Addr(ins))
} else if let Ok(ins) = SubInt2Addr::extract(ob) {
Ok(Self::SubInt2Addr(ins))
} else if let Ok(ins) = MulInt2Addr::extract(ob) {
Ok(Self::MulInt2Addr(ins))
} else if let Ok(ins) = DivInt2Addr::extract(ob) {
Ok(Self::DivInt2Addr(ins))
} else if let Ok(ins) = RemInt2Addr::extract(ob) {
Ok(Self::RemInt2Addr(ins))
} else if let Ok(ins) = AndInt2Addr::extract(ob) {
Ok(Self::AndInt2Addr(ins))
} else if let Ok(ins) = OrInt2Addr::extract(ob) {
Ok(Self::OrInt2Addr(ins))
} else if let Ok(ins) = XorInt2Addr::extract(ob) {
Ok(Self::XorInt2Addr(ins))
} else if let Ok(ins) = ShlInt2Addr::extract(ob) {
Ok(Self::ShlInt2Addr(ins))
} else if let Ok(ins) = ShrInt2Addr::extract(ob) {
Ok(Self::ShrInt2Addr(ins))
} else if let Ok(ins) = UshrInt2Addr::extract(ob) {
Ok(Self::UshrInt2Addr(ins))
} else if let Ok(ins) = AddLong2Addr::extract(ob) {
Ok(Self::AddLong2Addr(ins))
} else if let Ok(ins) = SubLong2Addr::extract(ob) {
Ok(Self::SubLong2Addr(ins))
} else if let Ok(ins) = MulLong2Addr::extract(ob) {
Ok(Self::MulLong2Addr(ins))
} else if let Ok(ins) = DivLong2Addr::extract(ob) {
Ok(Self::DivLong2Addr(ins))
} else if let Ok(ins) = RemLong2Addr::extract(ob) {
Ok(Self::RemLong2Addr(ins))
} else if let Ok(ins) = AndLong2Addr::extract(ob) {
Ok(Self::AndLong2Addr(ins))
} else if let Ok(ins) = OrLong2Addr::extract(ob) {
Ok(Self::OrLong2Addr(ins))
} else if let Ok(ins) = XorLong2Addr::extract(ob) {
Ok(Self::XorLong2Addr(ins))
} else if let Ok(ins) = ShlLong2Addr::extract(ob) {
Ok(Self::ShlLong2Addr(ins))
} else if let Ok(ins) = ShrLong2Addr::extract(ob) {
Ok(Self::ShrLong2Addr(ins))
} else if let Ok(ins) = UshrLong2Addr::extract(ob) {
Ok(Self::UshrLong2Addr(ins))
} else if let Ok(ins) = AddFloat2Addr::extract(ob) {
Ok(Self::AddFloat2Addr(ins))
} else if let Ok(ins) = SubFloat2Addr::extract(ob) {
Ok(Self::SubFloat2Addr(ins))
} else if let Ok(ins) = MulFloat2Addr::extract(ob) {
Ok(Self::MulFloat2Addr(ins))
} else if let Ok(ins) = DivFloat2Addr::extract(ob) {
Ok(Self::DivFloat2Addr(ins))
} else if let Ok(ins) = RemFloat2Addr::extract(ob) {
Ok(Self::RemFloat2Addr(ins))
} else if let Ok(ins) = AddDouble2Addr::extract(ob) {
Ok(Self::AddDouble2Addr(ins))
} else if let Ok(ins) = SubDouble2Addr::extract(ob) {
Ok(Self::SubDouble2Addr(ins))
} else if let Ok(ins) = MulDouble2Addr::extract(ob) {
Ok(Self::MulDouble2Addr(ins))
} else if let Ok(ins) = DivDouble2Addr::extract(ob) {
Ok(Self::DivDouble2Addr(ins))
} else if let Ok(ins) = RemDouble2Addr::extract(ob) {
Ok(Self::RemDouble2Addr(ins))
} else if let Ok(ins) = AddIntLit::extract(ob) {
Ok(Self::AddIntLit(ins))
} else if let Ok(ins) = RsubIntLit::extract(ob) {
Ok(Self::RsubIntLit(ins))
} else if let Ok(ins) = MulIntLit::extract(ob) {
Ok(Self::MulIntLit(ins))
} else if let Ok(ins) = DivIntLit::extract(ob) {
Ok(Self::DivIntLit(ins))
} else if let Ok(ins) = RemIntLit::extract(ob) {
Ok(Self::RemIntLit(ins))
} else if let Ok(ins) = AndIntLit::extract(ob) {
Ok(Self::AndIntLit(ins))
} else if let Ok(ins) = OrIntLit::extract(ob) {
Ok(Self::OrIntLit(ins))
} else if let Ok(ins) = XorIntLit::extract(ob) {
Ok(Self::XorIntLit(ins))
} else if let Ok(ins) = ShlIntLit::extract(ob) {
Ok(Self::ShlIntLit(ins))
} else if let Ok(ins) = ShrIntLit::extract(ob) {
Ok(Self::ShrIntLit(ins))
} else if let Ok(ins) = UshrIntLit::extract(ob) {
Ok(Self::UshrIntLit(ins))
} else if let Ok(ins) = InvokePolymorphic::extract(ob) {
Ok(Self::InvokePolymorphic(ins))
} else if let Ok(ins) = InvokeCustom::extract(ob) {
Ok(Self::InvokeCustom(ins))
} else if let Ok(ins) = ConstMethodHandle::extract(ob) {
Ok(Self::ConstMethodHandle(ins))
} else if let Ok(ins) = ConstMethodType::extract(ob) {
Ok(Self::ConstMethodType(ins))
} else if let Ok(ins) = Try::extract(ob) {
Ok(Self::Try(ins))
} else if let Ok(ins) = Label::extract(ob) {
Ok(Self::Label(ins))
} else {
Err(PyErr::new::<PyTypeError, _>(format!(
"{} is not a castable as an Instruction",
ob.repr()?
)))
}
}
}
impl IntoPy<PyObject> for Instruction {
fn into_py(self, py: Python<'_>) -> PyObject {
match self {
Self::Nop(ins) => ins.into_py(py),
Self::Move(ins) => ins.into_py(py),
Self::MoveWide(ins) => ins.into_py(py),
Self::MoveObject(ins) => ins.into_py(py),
Self::MoveResult(ins) => ins.into_py(py),
Self::MoveResultWide(ins) => ins.into_py(py),
Self::MoveException(ins) => ins.into_py(py),
Self::MoveResultObject(ins) => ins.into_py(py),
Self::ReturnVoid(ins) => ins.into_py(py),
Self::Return(ins) => ins.into_py(py),
Self::ReturnWide(ins) => ins.into_py(py),
Self::ReturnObject(ins) => ins.into_py(py),
Self::Const(ins) => ins.into_py(py),
Self::ConstWide(ins) => ins.into_py(py),
Self::ConstString(ins) => ins.into_py(py),
Self::ConstClass(ins) => ins.into_py(py),
Self::MonitorEnter(ins) => ins.into_py(py),
Self::MonitorExit(ins) => ins.into_py(py),
Self::CheckCast(ins) => ins.into_py(py),
Self::InstanceOf(ins) => ins.into_py(py),
Self::ArrayLength(ins) => ins.into_py(py),
Self::NewInstance(ins) => ins.into_py(py),
Self::NewArray(ins) => ins.into_py(py),
Self::FilledNewArray(ins) => ins.into_py(py),
Self::FillArrayData(ins) => ins.into_py(py),
Self::Throw(ins) => ins.into_py(py),
Self::Goto(ins) => ins.into_py(py),
Self::Switch(ins) => ins.into_py(py),
Self::CmpLFloat(ins) => ins.into_py(py),
Self::CmpGFloat(ins) => ins.into_py(py),
Self::CmpLDouble(ins) => ins.into_py(py),
Self::CmpGDouble(ins) => ins.into_py(py),
Self::CmpLong(ins) => ins.into_py(py),
Self::IfEq(ins) => ins.into_py(py),
Self::IfNe(ins) => ins.into_py(py),
Self::IfLt(ins) => ins.into_py(py),
Self::IfGe(ins) => ins.into_py(py),
Self::IfGt(ins) => ins.into_py(py),
Self::IfLe(ins) => ins.into_py(py),
Self::IfEqZ(ins) => ins.into_py(py),
Self::IfNeZ(ins) => ins.into_py(py),
Self::IfLtZ(ins) => ins.into_py(py),
Self::IfGeZ(ins) => ins.into_py(py),
Self::IfGtZ(ins) => ins.into_py(py),
Self::IfLeZ(ins) => ins.into_py(py),
Self::AGet(ins) => ins.into_py(py),
Self::AGetWide(ins) => ins.into_py(py),
Self::AGetObject(ins) => ins.into_py(py),
Self::AGetBoolean(ins) => ins.into_py(py),
Self::AGetByte(ins) => ins.into_py(py),
Self::AGetChar(ins) => ins.into_py(py),
Self::AGetShort(ins) => ins.into_py(py),
Self::APut(ins) => ins.into_py(py),
Self::APutWide(ins) => ins.into_py(py),
Self::APutObject(ins) => ins.into_py(py),
Self::APutBoolean(ins) => ins.into_py(py),
Self::APutByte(ins) => ins.into_py(py),
Self::APutChar(ins) => ins.into_py(py),
Self::APutShort(ins) => ins.into_py(py),
Self::IGet(ins) => ins.into_py(py),
Self::IGetWide(ins) => ins.into_py(py),
Self::IGetObject(ins) => ins.into_py(py),
Self::IGetBoolean(ins) => ins.into_py(py),
Self::IGetByte(ins) => ins.into_py(py),
Self::IGetChar(ins) => ins.into_py(py),
Self::IGetShort(ins) => ins.into_py(py),
Self::IPut(ins) => ins.into_py(py),
Self::IPutWide(ins) => ins.into_py(py),
Self::IPutObject(ins) => ins.into_py(py),
Self::IPutBoolean(ins) => ins.into_py(py),
Self::IPutByte(ins) => ins.into_py(py),
Self::IPutChar(ins) => ins.into_py(py),
Self::IPutShort(ins) => ins.into_py(py),
Self::SGet(ins) => ins.into_py(py),
Self::SGetWide(ins) => ins.into_py(py),
Self::SGetObject(ins) => ins.into_py(py),
Self::SGetBoolean(ins) => ins.into_py(py),
Self::SGetByte(ins) => ins.into_py(py),
Self::SGetChar(ins) => ins.into_py(py),
Self::SGetShort(ins) => ins.into_py(py),
Self::SPut(ins) => ins.into_py(py),
Self::SPutWide(ins) => ins.into_py(py),
Self::SPutObject(ins) => ins.into_py(py),
Self::SPutBoolean(ins) => ins.into_py(py),
Self::SPutByte(ins) => ins.into_py(py),
Self::SPutChar(ins) => ins.into_py(py),
Self::SPutShort(ins) => ins.into_py(py),
Self::InvokeVirtual(ins) => ins.into_py(py),
Self::InvokeSuper(ins) => ins.into_py(py),
Self::InvokeDirect(ins) => ins.into_py(py),
Self::InvokeStatic(ins) => ins.into_py(py),
Self::InvokeInterface(ins) => ins.into_py(py),
Self::NegInt(ins) => ins.into_py(py),
Self::NotInt(ins) => ins.into_py(py),
Self::NegLong(ins) => ins.into_py(py),
Self::NotLong(ins) => ins.into_py(py),
Self::NegFloat(ins) => ins.into_py(py),
Self::NegDouble(ins) => ins.into_py(py),
Self::IntToLong(ins) => ins.into_py(py),
Self::IntToFloat(ins) => ins.into_py(py),
Self::IntToDouble(ins) => ins.into_py(py),
Self::LongToInt(ins) => ins.into_py(py),
Self::LongToFloat(ins) => ins.into_py(py),
Self::LongToDouble(ins) => ins.into_py(py),
Self::FloatToInt(ins) => ins.into_py(py),
Self::FloatToLong(ins) => ins.into_py(py),
Self::FloatToDouble(ins) => ins.into_py(py),
Self::DoubleToInt(ins) => ins.into_py(py),
Self::DoubleToLong(ins) => ins.into_py(py),
Self::DoubleToFloat(ins) => ins.into_py(py),
Self::IntToByte(ins) => ins.into_py(py),
Self::IntToChar(ins) => ins.into_py(py),
Self::IntToShort(ins) => ins.into_py(py),
Self::AddInt(ins) => ins.into_py(py),
Self::SubInt(ins) => ins.into_py(py),
Self::MulInt(ins) => ins.into_py(py),
Self::DivInt(ins) => ins.into_py(py),
Self::RemInt(ins) => ins.into_py(py),
Self::AndInt(ins) => ins.into_py(py),
Self::OrInt(ins) => ins.into_py(py),
Self::XorInt(ins) => ins.into_py(py),
Self::ShlInt(ins) => ins.into_py(py),
Self::ShrInt(ins) => ins.into_py(py),
Self::UshrInt(ins) => ins.into_py(py),
Self::AddLong(ins) => ins.into_py(py),
Self::SubLong(ins) => ins.into_py(py),
Self::MulLong(ins) => ins.into_py(py),
Self::DivLong(ins) => ins.into_py(py),
Self::RemLong(ins) => ins.into_py(py),
Self::AndLong(ins) => ins.into_py(py),
Self::OrLong(ins) => ins.into_py(py),
Self::XorLong(ins) => ins.into_py(py),
Self::ShlLong(ins) => ins.into_py(py),
Self::ShrLong(ins) => ins.into_py(py),
Self::UshrLong(ins) => ins.into_py(py),
Self::AddFloat(ins) => ins.into_py(py),
Self::SubFloat(ins) => ins.into_py(py),
Self::MulFloat(ins) => ins.into_py(py),
Self::DivFloat(ins) => ins.into_py(py),
Self::RemFloat(ins) => ins.into_py(py),
Self::AddDouble(ins) => ins.into_py(py),
Self::SubDouble(ins) => ins.into_py(py),
Self::MulDouble(ins) => ins.into_py(py),
Self::DivDouble(ins) => ins.into_py(py),
Self::RemDouble(ins) => ins.into_py(py),
Self::AddInt2Addr(ins) => ins.into_py(py),
Self::SubInt2Addr(ins) => ins.into_py(py),
Self::MulInt2Addr(ins) => ins.into_py(py),
Self::DivInt2Addr(ins) => ins.into_py(py),
Self::RemInt2Addr(ins) => ins.into_py(py),
Self::AndInt2Addr(ins) => ins.into_py(py),
Self::OrInt2Addr(ins) => ins.into_py(py),
Self::XorInt2Addr(ins) => ins.into_py(py),
Self::ShlInt2Addr(ins) => ins.into_py(py),
Self::ShrInt2Addr(ins) => ins.into_py(py),
Self::UshrInt2Addr(ins) => ins.into_py(py),
Self::AddLong2Addr(ins) => ins.into_py(py),
Self::SubLong2Addr(ins) => ins.into_py(py),
Self::MulLong2Addr(ins) => ins.into_py(py),
Self::DivLong2Addr(ins) => ins.into_py(py),
Self::RemLong2Addr(ins) => ins.into_py(py),
Self::AndLong2Addr(ins) => ins.into_py(py),
Self::OrLong2Addr(ins) => ins.into_py(py),
Self::XorLong2Addr(ins) => ins.into_py(py),
Self::ShlLong2Addr(ins) => ins.into_py(py),
Self::ShrLong2Addr(ins) => ins.into_py(py),
Self::UshrLong2Addr(ins) => ins.into_py(py),
Self::AddFloat2Addr(ins) => ins.into_py(py),
Self::SubFloat2Addr(ins) => ins.into_py(py),
Self::MulFloat2Addr(ins) => ins.into_py(py),
Self::DivFloat2Addr(ins) => ins.into_py(py),
Self::RemFloat2Addr(ins) => ins.into_py(py),
Self::AddDouble2Addr(ins) => ins.into_py(py),
Self::SubDouble2Addr(ins) => ins.into_py(py),
Self::MulDouble2Addr(ins) => ins.into_py(py),
Self::DivDouble2Addr(ins) => ins.into_py(py),
Self::RemDouble2Addr(ins) => ins.into_py(py),
Self::AddIntLit(ins) => ins.into_py(py),
Self::RsubIntLit(ins) => ins.into_py(py),
Self::MulIntLit(ins) => ins.into_py(py),
Self::DivIntLit(ins) => ins.into_py(py),
Self::RemIntLit(ins) => ins.into_py(py),
Self::AndIntLit(ins) => ins.into_py(py),
Self::OrIntLit(ins) => ins.into_py(py),
Self::XorIntLit(ins) => ins.into_py(py),
Self::ShlIntLit(ins) => ins.into_py(py),
Self::ShrIntLit(ins) => ins.into_py(py),
Self::UshrIntLit(ins) => ins.into_py(py),
Self::InvokePolymorphic(ins) => ins.into_py(py),
Self::InvokeCustom(ins) => ins.into_py(py),
Self::ConstMethodHandle(ins) => ins.into_py(py),
Self::ConstMethodType(ins) => ins.into_py(py),
Self::Try(ins) => ins.into_py(py),
Self::Label(ins) => ins.into_py(py),
}
}
}
#[pyclass]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct CallSite {
#[pyo3(get)]
pub method_handle: MethodHandle,
#[pyo3(get)]
pub name: DexString,
#[pyo3(get)]
pub type_: IdMethodType,
#[pyo3(get)]
pub args: Vec<DexValue>,
}
#[pymethods]
impl CallSite {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(
method_handle: MethodHandle,
name: DexString,
type_: IdMethodType,
args: Vec<DexValue>,
) -> Self {
let args = args.to_vec();
Self {
method_handle,
name,
type_,
args,
}
}
pub fn __str__(&self) -> String {
let args = self
.args
.iter()
.map(|arg| arg.__str__())
.collect::<Vec<_>>()
.join(", ");
format!(
"call({} {} {} ({})",
self.method_handle.__str__(),
self.type_.__str__(),
self.name.__str__(),
args
)
}
pub fn __repr__(&self) -> String {
let args = self
.args
.iter()
.map(|arg| arg.__str__())
.collect::<Vec<_>>()
.join(", ");
format!(
"CallSite({}, {}, {}, [{}]",
self.method_handle.__repr__(),
self.type_.__repr__(),
self.name.__repr__(),
args
)
}
/// Return all strings referenced in the call site.
pub fn get_all_strings(&self) -> HashSet<DexString> {
let mut strings = HashSet::new();
strings.insert(self.name.clone());
strings.extend(self.method_handle.get_all_strings());
strings.extend(self.type_.get_all_strings());
for arg in &self.args {
strings.extend(arg.get_all_strings());
}
strings
}
/// Return all types referenced in the call site.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut type_ids = HashSet::new();
type_ids.extend(self.method_handle.get_all_types());
type_ids.extend(self.type_.get_all_types());
for arg in &self.args {
type_ids.extend(arg.get_all_types());
}
type_ids
}
/// Return all prototypes referenced in the call site.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
let mut protos = HashSet::new();
protos.extend(self.method_handle.get_all_protos());
protos.insert(self.type_.clone());
for arg in &self.args {
protos.extend(arg.get_all_protos());
}
protos
}
/// Return all field ids referenced in the call site.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.extend(self.method_handle.get_all_field_ids());
for arg in &self.args {
fields.extend(arg.get_all_field_ids());
}
fields
}
/// Return all method ids referenced in the call site.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.extend(self.method_handle.get_all_method_ids());
for arg in &self.args {
methods.extend(arg.get_all_method_ids());
}
methods
}
/// Return all method handles referenced in the call site.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
let mut handles = HashSet::new();
handles.insert(self.method_handle.clone());
for arg in &self.args {
handles.extend(arg.get_all_method_handles());
}
handles
}
}
/// Waste a cycle.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct Nop;
impl Default for Nop {
fn default() -> Self {
Self::new()
}
}
#[pymethods]
impl Nop {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new() -> Self {
Self
}
pub fn __str__(&self) -> String {
"nop".into()
}
pub fn __repr__(&self) -> String {
"Instruction(Nop)".into()
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Nop {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format10X { op: 0x00 }
}
}
/// Move contents of a non object register to another.
///
/// Can represent several dalvik instructions :
///
/// move vA, vB
/// move/from16 vAA, vBBBB
/// move/16 vAAAA, vBBBB
///
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct Move {
#[pyo3(get)]
pub from: u16,
#[pyo3(get)]
pub to: u16,
}
#[pymethods]
impl Move {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u16, from: u16) -> Self {
Self { from, to }
}
pub fn __str__(&self) -> String {
format!("move {} {}", self.to, self.from)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Move({}, {}))", self.to, self.from)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Move {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
match (self.to, self.from) {
(0..=0b0000_1111, 0..=0b0000_1111) => InsFormat::Format12X {
op: 0x01,
va: self.to as u8,
vb: self.from as u8,
},
(0..=0xff, _) => InsFormat::Format22X {
op: 0x02,
va: self.to as u8,
vb: self.from,
},
(_, _) => InsFormat::Format32X {
op: 0x03,
va: self.to,
vb: self.from,
},
}
}
}
/// Move contents of a register pair to another.
///
/// Can represent several dalvik instructions :
///
/// move-wide vA, vB
/// move-wide/from16 vAA, vBBBB
/// move-wide/16 vAAAA, vBBBB
///
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveWide {
#[pyo3(get)]
pub from: u16,
#[pyo3(get)]
pub to: u16,
}
#[pymethods]
impl MoveWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u16, from: u16) -> Self {
Self { from, to }
}
pub fn __str__(&self) -> String {
format!("move-wide {} {}", self.to, self.from)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveWide({}, {}))", self.to, self.from)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
match (self.to, self.from) {
(0..=0b0000_1111, 0..=0b0000_1111) => InsFormat::Format12X {
op: 0x04,
va: self.to as u8,
vb: self.from as u8,
},
(0..=0xff, _) => InsFormat::Format22X {
op: 0x05,
va: self.to as u8,
vb: self.from,
},
(_, _) => InsFormat::Format32X {
op: 0x06,
va: self.to,
vb: self.from,
},
}
}
}
/// Move contents of an object bearing register to another.
///
/// Can represent several dalvik instructions :
///
/// move-object vA, vB
/// move-object/from16 vAA, vBBBB
/// move-object/16 vAAAA, vBBBB
///
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveObject {
#[pyo3(get)]
pub from: u16,
#[pyo3(get)]
pub to: u16,
}
#[pymethods]
impl MoveObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u16, from: u16) -> Self {
Self { from, to }
}
pub fn __str__(&self) -> String {
format!("move-object {} {}", self.to, self.from)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveObject({}, {}))", self.to, self.from)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveObject {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
match (self.to, self.from) {
(0..=0b0000_1111, 0..=0b0000_1111) => InsFormat::Format12X {
op: 0x07,
va: self.to as u8,
vb: self.from as u8,
},
(0..=0xff, _) => InsFormat::Format22X {
op: 0x08,
va: self.to as u8,
vb: self.from,
},
(_, _) => InsFormat::Format32X {
op: 0x09,
va: self.to,
vb: self.from,
},
}
}
}
/// Move the single word non object result of the preciding invoke-kind into a register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveResult {
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl MoveResult {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8) -> Self {
Self { to }
}
pub fn __str__(&self) -> String {
format!("move-result {}", self.to)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveResult({}))", self.to)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveResult {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x0a,
va: self.to,
}
}
}
/// Move the double word non object result of the preciding invoke-kind into a register pair.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveResultWide {
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl MoveResultWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8) -> Self {
Self { to }
}
pub fn __str__(&self) -> String {
format!("move-result-wide {}", self.to)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveResultWide({}))", self.to)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveResultWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x0b,
va: self.to,
}
}
}
/// Move the object result of the preciding invoke-kind or filled-new-array into a register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveResultObject {
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl MoveResultObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8) -> Self {
Self { to }
}
pub fn __str__(&self) -> String {
format!("move-result-object {}", self.to)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveResultObject({}))", self.to)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveResultObject {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x0c,
va: self.to,
}
}
}
/// Move the just caught exception into a register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MoveException {
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl MoveException {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8) -> Self {
Self { to }
}
pub fn __str__(&self) -> String {
format!("move-exception {}", self.to)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MoveException({}))", self.to)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MoveException {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x0d,
va: self.to,
}
}
}
/// Return a void method
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ReturnVoid;
impl Default for ReturnVoid {
fn default() -> Self {
Self::new()
}
}
#[pymethods]
impl ReturnVoid {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new() -> Self {
Self
}
pub fn __str__(&self) -> String {
"return-void".into()
}
pub fn __repr__(&self) -> String {
"Instruction(ReturnVoid)".into()
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ReturnVoid {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format10X { op: 0x0e }
}
}
/// Return the 32 bits non object value from the method.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct Return {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl Return {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("return {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Return({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Return {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x0f,
va: self.reg,
}
}
}
/// Return the 64 bits non object value from the method.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ReturnWide {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl ReturnWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("return-wide {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ReturnWide({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ReturnWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x10,
va: self.reg,
}
}
}
/// Return the object value from the method.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ReturnObject {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl ReturnObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("return-object {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ReturnObject({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ReturnObject {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x11,
va: self.reg,
}
}
}
/// Move a literal to a register.
///
/// Can represent several dalvik instructions :
///
/// const/4 vA #+B
/// const/16 vAA #+BBBB
/// const vAA #+BBBBBBBB
/// const/high 16 vAA #+BBBB0000
///
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct Const {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: i32,
}
#[pymethods]
impl Const {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: i32) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("const {} {}", self.reg, self.lit)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Const({}, {}))", self.reg, self.lit)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Const {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
match (self.reg, self.lit) {
(0..=0b0000_1111, -8..=7) => InsFormat::Format11N {
op: 0x12,
va: self.reg,
b: self.lit as i8,
},
(_, I16_MIN_AS_I32..=I16_MAX_AS_I32) => InsFormat::Format21S {
op: 0x13,
va: self.reg,
b: self.lit as i16,
},
(_, lit) if lit % 0x1_0000 == 0 => InsFormat::Format21H {
op: 0x15,
va: self.reg,
b: (self.lit / 0x1_0000) as i16,
},
(_, _) => InsFormat::Format31I {
op: 0x14,
va: self.reg,
b: self.lit,
},
}
}
}
/// Move a literal to a register pair (64bits).
///
/// Can represent several dalvik instructions :
///
/// const-wide/16 vAA #+BBBB
/// const-wide/32 vAA #+BBBBBBBB
/// const-wide vAA #+BBBBBBBBBBBBBBBB
/// const-wide/hight 16 vAA #+BBBB000000000000
///
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ConstWide {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: i64,
}
#[pymethods]
impl ConstWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: i64) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("const-wide {} {}", self.reg, self.lit)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ConstWide({}, {}))", self.reg, self.lit)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ConstWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
match self.lit {
I16_MIN_AS_I64..=I16_MAX_AS_I64 => InsFormat::Format21S {
op: 0x16,
va: self.reg,
b: self.lit as i16,
},
I32_MIN_AS_I64..=I32_MAX_AS_I64 => InsFormat::Format31I {
op: 0x17,
va: self.reg,
b: self.lit as i32,
},
lit if lit % 0x1_0000_0000_0000 == 0 => InsFormat::Format21H {
op: 0x19,
va: self.reg,
b: (self.lit / 0x1_0000_0000_0000) as i16,
},
_ => InsFormat::Format51L {
op: 0x18,
va: self.reg,
b: self.lit,
},
}
}
}
/// Move a reference to a string in a register.
///
/// Can represent several dalvik instructions :
///
/// const-string vAA string@BBBB
/// const-string/jumbo vAA string@BBBBBBBB
///
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ConstString {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: DexString,
}
#[pymethods]
impl ConstString {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: DexString) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("const-string {} \"{}\"", self.reg, self.lit.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ConstString({}, {}))",
self.reg,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
4
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
let mut strings = HashSet::new();
strings.insert(self.lit.clone());
strings
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ConstString {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, string_idx: usize) -> InsFormat {
match string_idx {
0..=U16_MAX_AS_USIZE => InsFormat::Format21C {
op: 0x1a,
va: self.reg,
b: string_idx as u16,
},
_ => InsFormat::Format31C {
op: 0x1b,
va: self.reg,
b: string_idx as u32,
},
}
}
}
/// Move a reference to a class in a register.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ConstClass {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: IdType,
}
#[pymethods]
impl ConstClass {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: IdType) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("const-class {} \"{}\"", self.reg, self.lit.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ConstClass({}, {}))",
self.reg,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.lit.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.lit.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ConstClass {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, class_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x1c,
va: self.reg,
b: class_idx as u16,
}
}
}
/// Acquire the monitor for the object in the register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MonitorEnter {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl MonitorEnter {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("monitor-enter {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MonitorEnter({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MonitorEnter {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x1d,
va: self.reg,
}
}
}
/// Release the monitor for the object in the register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MonitorExit {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl MonitorExit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("monitor-exit {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MonitorExit({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MonitorExit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x1e,
va: self.reg,
}
}
}
/// Check if the object in the register can be cast to the type.
/// (Raise a `ClassCastException` if not)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct CheckCast {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: IdType,
}
#[pymethods]
impl CheckCast {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: IdType) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("check-cast {} {}", self.reg, self.lit.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CheckCast({}, {}))",
self.reg,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.lit.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.lit.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CheckCast {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, type_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x1f,
va: self.reg,
b: type_idx as u16,
}
}
}
/// Check if an object if an instance of a type.
/// (put 1 in the dest register if yes, else 0)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InstanceOf {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub lit: IdType,
}
#[pymethods]
impl InstanceOf {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, obj: u8, lit: IdType) -> Result<Self> {
let ins = Self { dest, obj, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of InstanceOf are indexed on 4 bits, found {}",
self.dest
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of InstanceOf are indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"instance-of {} {} {}",
self.dest,
self.obj,
self.lit.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(InstanceOf({}, {}, {}))",
self.dest,
self.obj,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.lit.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.lit.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InstanceOf {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, type_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x20,
va: self.dest,
vb: self.obj,
c: type_idx as u16,
}
}
}
/// Get the number of item in an array.
/// (put the lenght in the dest register)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ArrayLength {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
}
#[pymethods]
impl ArrayLength {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8) -> Result<Self> {
let ins = Self { dest, arr };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of ArrayLength are indexed on 4 bits, found {}",
self.dest
))
} else if self.arr & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of ArrayLength are indexed on 4 bits, found {}",
self.arr
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("array-length{} {}", self.dest, self.arr,)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ArrayLength({}, {}))", self.dest, self.arr,)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ArrayLength {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x21,
va: self.dest,
vb: self.arr,
}
}
}
/// Construct a new instance of the indicated type and store a reference to it.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct NewInstance {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub lit: IdType,
}
#[pymethods]
impl NewInstance {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, lit: IdType) -> Self {
Self { reg, lit }
}
pub fn __str__(&self) -> String {
format!("new-instance {} {}", self.reg, self.lit.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(NewInstance({}, {}))",
self.reg,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.lit.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.lit.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NewInstance {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, type_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x22,
va: self.reg,
b: type_idx as u16,
}
}
}
/// Construct a new array of the indicated type and size in size_reg and store a reference to it.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct NewArray {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
pub size_reg: u8,
#[pyo3(get)]
pub lit: IdType,
}
#[pymethods]
impl NewArray {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, size_reg: u8, lit: IdType) -> Result<Self> {
let ins = Self { reg, size_reg, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn __str__(&self) -> String {
format!(
"new-array {} {} {}",
self.reg,
self.size_reg,
self.lit.__str__()
)
}
pub fn sanity_check(&self) -> Result<()> {
if self.reg & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of NewArray are indexed on 4 bits, found {}",
self.reg
))
} else if self.size_reg & 0b1111_0000 != 0 {
Err(anyhow!(
"The registers of NewArray are indexed on 4 bits, found {}",
self.size_reg
))
} else {
Ok(())
}
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(NewArray({}, {}, {}))",
self.reg,
self.size_reg,
self.lit.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.lit.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.lit.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NewArray {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, type_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x23,
va: self.reg,
vb: self.size_reg,
c: type_idx as u16,
}
}
}
/// Construct a new array of the indicated type and size fill it with the values of the
/// given registers.
///
/// The elements of the array must fit in 32bits.
///
/// The registers must either be less to 5 and their number must fit on 4 bits each, or
/// be less than 256, their the number of the smallest must fit on 16 bits and they must
/// be sorted an directly adjascent.
///
/// The newly created array can be retreived with a move-result-object instruction.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct FilledNewArray {
#[pyo3(get)]
pub type_: IdType,
#[pyo3(get)]
pub reg_values: Vec<u16>,
}
#[pymethods]
impl FilledNewArray {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(type_: IdType, reg_values: Vec<u16>) -> Result<Self> {
let array = Self { type_, reg_values };
array.sanity_check()?;
Ok(array)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.reg_values.len();
for r in self.reg_values.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"filled-new-array instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.reg_values.len() >= 5 {
format!(
"{} .. {}",
self.reg_values[0],
self.reg_values[self.reg_values.len() - 1]
)
} else {
self.reg_values
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("filled-new-array {{{}}} {}", args, self.type_.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.reg_values.len() >= 5 {
format!(
"{}, ..., {}",
self.reg_values[0],
self.reg_values[self.reg_values.len() - 1]
)
} else {
self.reg_values
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(", ")
};
format!(
"Instruction(FilledNewArray([{}], {}))",
args,
self.type_.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.type_.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
types.insert(self.type_.clone());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl FilledNewArray {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self, type_idx: usize) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.reg_values.len();
for r in self.reg_values.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.reg_values.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.reg_values.len() as u8;
InsFormat::Format35C {
op: 0x24,
a,
vc,
ve,
vd,
vf,
vg,
b: type_idx as u16,
}
} else if consec && len <= 255 {
let a = self.reg_values.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x25,
a,
vc,
b: type_idx as u16,
}
} else {
// Not supposed to happend with a sanitized array
panic!("Invalid NewArrayInstruction {self:?}")
}
}
}
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct FillArrayData {
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub elt_width: u16,
#[pyo3(get)]
pub data: Vec<u8>,
}
#[pymethods]
impl FillArrayData {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(arr: u8, elt_width: u16, data: Vec<u8>) -> Self {
Self {
arr,
elt_width,
data,
}
}
pub fn __str__(&self) -> String {
let data: String = if self.data.len() / self.elt_width as usize == 0 {
"".into()
} else if self.data.len() / self.elt_width as usize <= 2 {
let mut arr = "".into();
for (i, v) in self.data.iter().enumerate() {
if i == 0 {
arr += "0x"
} else if i % self.elt_width as usize == 0 {
arr += " 0x"
}
arr += format!("{v:02x}").as_str();
}
arr
} else {
let mut arr = "0x".into();
for v in &self.data[..self.elt_width as usize] {
arr += format!("{v:02x}").as_str();
}
arr += " ... 0x";
for v in &self.data[self.data.len() - self.elt_width as usize..] {
arr += format!("{v:02x}").as_str();
}
arr
};
format!("fill-array-data {} {}", self.arr, data)
}
pub fn __repr__(&self) -> String {
let data: String = if self.data.len() / self.elt_width as usize == 0 {
"".into()
} else if self.data.len() / self.elt_width as usize <= 2 {
let mut arr = "".into();
for (i, v) in self.data.iter().enumerate() {
if i == 0 {
arr += "0x"
} else if i % self.elt_width as usize == 0 {
arr += ", 0x"
}
arr += format!("{v:02x}").as_str();
}
arr
} else {
let mut arr = "0x".into();
for v in &self.data[..self.elt_width as usize] {
arr += format!("{v:02x}").as_str();
}
arr += ", ..., 0x";
for v in &self.data[self.data.len() - self.elt_width as usize..] {
arr += format!("{v:02x}").as_str();
}
arr
};
format!("Instruction(FillArrayData({}, [{}]))", self.arr, data)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl FillArrayData {
/// Return the raw instruction ([`InsFormat`]).
///
/// `data_offset` is the offset to the address where the data are located.
pub fn get_raw_ins(&self, data_offset: i32) -> InsFormat {
InsFormat::Format31T {
op: 0x26,
va: self.arr,
b: data_offset,
}
}
}
/// Throws the exception in the register.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct Throw {
#[pyo3(get)]
pub reg: u8,
}
#[pymethods]
impl Throw {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8) -> Self {
Self { reg }
}
pub fn __str__(&self) -> String {
format!("throw {}", self.reg)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Throw({}))", self.reg)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Throw {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format11X {
op: 0x27,
va: self.reg,
}
}
}
/// Jump to the label.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Goto {
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl Goto {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(label: String) -> Self {
Self { label }
}
pub fn __str__(&self) -> String {
format!("goto {}", self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Goto({}))", self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
2
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Goto {
/// Return the raw instruction ([`InsFormat`]).
///
/// - `branch_offset` is the offset to the address.
/// - `goto_size` is the estimated size of the goto used to compute the offset.
/// It may not be the optimal size, but the instructions of the associtated
/// size will be used, and the offset is expected to fit in the instruction.
///
/// Possible goto size and associated offset size:
/// - `2`: offset must fit in an i8
/// - `4`: offset must fit in an i16
/// - `6`: offset must fit in an i32
pub fn get_raw_ins(&self, data_offset: i32, goto_size: usize) -> InsFormat {
if goto_size == 2 && (I8_MIN_AS_I32..=I8_MAX_AS_I32).contains(&data_offset) {
InsFormat::Format10T {
op: 0x28,
a: data_offset as i8,
}
} else if goto_size == 4 && (I16_MIN_AS_I32..=I16_MAX_AS_I32).contains(&data_offset) {
InsFormat::Format20T {
op: 0x29,
a: data_offset as i16,
}
} else if goto_size == 6 {
InsFormat::Format30T {
op: 0x2a,
a: data_offset,
}
} else {
panic!("Invalid goto_size and/or data_offset value")
}
}
/// Return the size of a goto instruction from the goto instruction address and
/// and interval for the branch address. The size will be selected to be the smallest
/// possible size that fit the offset for the worst case scenario.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
///
/// The address for the intervals are in code address units `u16`.
pub fn size_from_branch_offset_interval(
addr_goto: usize,
min_addr_branch: usize,
max_addr_branch: usize,
) -> Result<usize> {
let worst_offset = if max_addr_branch as i32 - addr_goto as i32
> addr_goto as i32 - min_addr_branch as i32
{
max_addr_branch as i32 - addr_goto as i32
} else {
min_addr_branch as i32 - addr_goto as i32
};
match worst_offset {
I8_MIN_AS_I32..=I8_MAX_AS_I32 => Ok(2),
I16_MIN_AS_I32..=I16_MAX_AS_I32 => Ok(4),
_ => Ok(6),
}
}
}
/// Jump to a label depending on the value of a register. If the value
/// is not matched, continue the extecution at the next instruction.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Switch {
#[pyo3(get)]
pub reg: u8,
#[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub branches: HashMap<i32, String>,
}
#[pymethods]
impl Switch {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(reg: u8, branches: HashMap<i32, String>) -> Self {
Self { reg, branches }
}
pub fn __str__(&self) -> String {
let mut branches_str: String = "".into();
let mut branches: Vec<_> = self.branches.iter().collect();
branches.sort_by_key(|(key, _)| **key);
for (key, label) in branches {
branches_str += &format!("\n {key}: goto {label}");
}
format!("switch {} {}", self.reg, branches_str)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Switch({}, ...))", self.reg)
}
/// Test if the swith is packed of pack
pub fn is_packed(&self) -> bool {
let mut last = None;
let mut keys = self.branches.keys().collect::<Vec<_>>();
keys.sort();
for key in keys.into_iter().cloned() {
if let Some(last) = &last {
if *last != key - 1 {
return false;
}
}
last = Some(key);
}
true
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl Switch {
/// Return the raw instruction ([`InsFormat`]).
///
/// `table_offset` is the offset to the address where the branche table located.
pub fn get_raw_ins(&self, data_offset: i32) -> InsFormat {
InsFormat::Format31T {
op: if self.is_packed() { 0x2b } else { 0x2c },
va: self.reg,
b: data_offset,
}
}
}
/// Store the result of the comparison between the registers.
///
/// - b < c: a = -1
/// - b == c: a = 0
/// - b > c : a = 1
/// - b == c == Nan: a = -1
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct CmpLFloat {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub c: u8,
}
#[pymethods]
impl CmpLFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("cmpl-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CmpLFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CmpLFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x2d,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Store the result of the comparison between the registers.
///
/// - b < c: a = -1
/// - b == c: a = 0
/// - b > c : a = 1
/// - b == c == Nan: a = 1
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct CmpGFloat {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub c: u8,
}
#[pymethods]
impl CmpGFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("cmpg-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CmpGFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CmpGFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x2e,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Store the result of the comparison between the registers.
///
/// - b < c: a = -1
/// - b == c: a = 0
/// - b > c : a = 1
/// - b == c == Nan: a = -1
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct CmpLDouble {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub c: u8,
}
#[pymethods]
impl CmpLDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("cmpl-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CmpLDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CmpLDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x2f,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Store the result of the comparison between the registers.
///
/// - b < c: a = -1
/// - b == c: a = 0
/// - b > c : a = 1
/// - b == c == Nan: a = 1
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct CmpGDouble {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub c: u8,
}
#[pymethods]
impl CmpGDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("cmpg-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CmpGDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CmpGDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x30,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Store the result of the comparison between the registers.
///
/// - b < c: a = -1
/// - b == c: a = 0
/// - b > c : a = 1
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct CmpLong {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub c: u8,
}
#[pymethods]
impl CmpLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("cmp-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(CmpLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl CmpLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x31,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Jump to the label if a == b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfEq {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfEq {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-eq uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-eq uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-eq {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfEq({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfEq {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x32,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a != b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfNe {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfNe {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-neq uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-neq uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-neq {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfNe({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfNe {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x33,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a < b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfLt {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfLt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-lt uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-lt uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-lt {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfLt({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfLt {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x34,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a >= b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfGe {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfGe {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-ge uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-ge uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-ge {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfGe({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfGe {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x35,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a > b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfGt {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfGt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-gt uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-gt uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-gt {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfGt({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfGt {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x36,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a <= b
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfLe {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub b: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfLe {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, b: u8, label: String) -> Result<Self> {
let ins = Self { a, b, label };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.a & 0b1111_0000 != 0 {
Err(anyhow!(
"if-le uses registers indexed on 4 bits, found {}",
self.a
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"if-le uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("if-le {} {} {}", self.a, self.b, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfLe({}, {}, {}))", self.a, self.b, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfLe {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format22T {
op: 0x37,
va: self.a,
vb: self.b,
c: branch_offset,
}
}
}
/// Jump to the label if a == 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfEqZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfEqZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-eqz {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfEqZ({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfEqZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x38,
va: self.a,
b: branch_offset,
}
}
}
/// Jump to the label if a != 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfNeZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfNeZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-neq {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfNe({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfNeZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x39,
va: self.a,
b: branch_offset,
}
}
}
/// Jump to the label if a < 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfLtZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfLtZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-lt {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfLt({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfLtZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x3a,
va: self.a,
b: branch_offset,
}
}
}
/// Jump to the label if a >= 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfGeZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfGeZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-ge {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfGe({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfGeZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x3b,
va: self.a,
b: branch_offset,
}
}
}
/// Jump to the label if a > 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfGtZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfGtZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-gt {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfGt({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfGtZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x3c,
va: self.a,
b: branch_offset,
}
}
}
/// Jump to the label if a <= 0
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IfLeZ {
#[pyo3(get)]
pub a: u8,
#[pyo3(get)]
pub label: String,
}
#[pymethods]
impl IfLeZ {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(a: u8, label: String) -> Result<Self> {
let ins = Self { a, label };
Ok(ins)
}
pub fn __str__(&self) -> String {
format!("if-le {} {}", self.a, self.label)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IfLe({}, {}))", self.a, self.label)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IfLeZ {
/// Return the raw instruction ([`InsFormat`]).
///
/// `branch_offset` is the offset to the address to jump to if
/// the test is true.
pub fn get_raw_ins(&self, branch_offset: i16) -> InsFormat {
InsFormat::Format21T {
op: 0x3d,
va: self.a,
b: branch_offset,
}
}
}
/// Put the value at `arr[idx]` in register dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGet {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGet {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGet({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGet {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x44,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the value at `arr[idx]` in register pair dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetWide {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-wide {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetWide({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x45,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the reference at `arr[idx]` in register (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetObject {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-object {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetObject({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetObject {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x46,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the boolean at `arr[idx]` in register dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetBoolean {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-boolean {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetBoolean({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetBoolean {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x47,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the byte at `arr[idx]` in register dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetByte {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-byte {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetByte({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetByte {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x48,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the char at `arr[idx]` in register dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetChar {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-char {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetChar({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetChar {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x49,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the short at `arr[idx]` in register dest (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AGetShort {
#[pyo3(get)]
pub dest: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl AGetShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, arr: u8, idx: u8) -> Self {
Self { dest, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aget-short {} {} {}", self.dest, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AGetShort({}, {}, {}))",
self.dest, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AGetShort {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4a,
va: self.dest,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the value of register 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APut {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APut {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APut({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APut {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4b,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the value of the register pair 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutWide {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-wide {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutWide({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutWide {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4c,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the object reference in 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutObject {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-object {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutObject({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutObject {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4d,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the boolean in 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutBoolean {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-boolean {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutBoolean({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutBoolean {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4e,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the byte in 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutByte {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-byte {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutByte({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutByte {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x4f,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the char in 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutChar {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-char {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutChar({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutChar {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x50,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the short in 'from' in `arr[idx]` (all values are in registers)
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct APutShort {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub arr: u8,
#[pyo3(get)]
pub idx: u8,
}
#[pymethods]
impl APutShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, arr: u8, idx: u8) -> Self {
Self { from, arr, idx }
}
pub fn __str__(&self) -> String {
format!("aput-short {} {} {}", self.from, self.arr, self.idx)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(APutShort({}, {}, {}))",
self.from, self.arr, self.idx
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl APutShort {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x51,
va: self.from,
vb: self.arr,
vc: self.idx,
}
}
}
/// Put the value in 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGet {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGet {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("iget {} {} {}", self.to, self.obj, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGet({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGet {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x52,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the value in the register pair 'to' in the instance field 'field' of 'obj' ('to'
/// and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetWide {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-wide uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-wide uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-wide {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetWide({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetWide {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x53,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the object reference 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetObject {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-object uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-object uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-object {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetObject({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetObject {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x54,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the boolean in 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetBoolean {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-boolean uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-boolean uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-boolean {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetBoolean({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetBoolean {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x55,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the byte in 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetByte {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-byte uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-byte uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-byte {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetByte({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetByte {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x56,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the char in 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetChar {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-char uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-char uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-char {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetChar({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetChar {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x57,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the short in 'to' in the instance field 'field' of 'obj' ('to' and 'obj' are register)
///
/// The registers 'to' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IGetShort {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IGetShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { to, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.to & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-short uses registers indexed on 4 bits, found {}",
self.to
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iget-short uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iget-short {} {} {}",
self.to,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IGetShort({}, {}, {}))",
self.to,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IGetShort {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x58,
va: self.to,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the value in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPut {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPut {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("iput {} {} {}", self.from, self.obj, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPut({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPut {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x59,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the value in the instance field 'field' of 'obj' in the register pair 'from'
/// ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutWide {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-wide uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-wide uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-wide {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutWide({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutWide {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5a,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the object reference in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutObject {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-object uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-object uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-object {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutObject({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutObject {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5b,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the boolean in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutBoolean {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-boolean uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-boolean uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-boolean {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutBoolean({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutBoolean {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5c,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the byte in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutByte {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-byte uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-byte uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-byte {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutByte({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutByte {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5d,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the char in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutChar {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-char uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-char uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-char {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutChar({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutChar {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5e,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the short in the instance field 'field' of 'obj' in 'from' ('from' and 'obj' are register)
///
/// The registers 'from' and 'obj' are idexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IPutShort {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub obj: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl IPutShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, obj: u8, field: IdField) -> Result<Self> {
let ins = Self { from, obj, field };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.from & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-short uses registers indexed on 4 bits, found {}",
self.from
))
} else if self.obj & 0b1111_0000 != 0 {
Err(anyhow!(
"iput-short uses registers indexed on 4 bits, found {}",
self.obj
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!(
"iput-short {} {} {}",
self.from,
self.obj,
self.field.__str__()
)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(IPutShort({}, {}, {}))",
self.from,
self.obj,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IPutShort {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format22C {
op: 0x5f,
va: self.from,
vb: self.obj,
c: field_idx as u16,
}
}
}
/// Put the value in 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGet {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGet {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!("Instruction(SGet({}, {}))", self.to, self.field.__repr__())
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGet {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x60,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the value in the register pair 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetWide {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-wide {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetWide({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetWide {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x61,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the object reference 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetObject {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-object {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetObject({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetObject {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x62,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the boolean in 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetBoolean {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-boolean {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetBoolean({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetBoolean {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x63,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the byte in 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetByte {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-byte {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetByte({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetByte {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x64,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the char in 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetChar {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-char {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetChar({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetChar {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x65,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the short in 'to' in the static field 'field' ('to' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SGetShort {
#[pyo3(get)]
pub to: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SGetShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, field: IdField) -> Self {
Self { to, field }
}
pub fn __str__(&self) -> String {
format!("sget-short {} {}", self.to, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SGetShort({}, {}))",
self.to,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SGetShort {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x66,
va: self.to,
b: field_idx as u16,
}
}
}
/// Put the value in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPut {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPut {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPut({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPut {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x67,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the value in the static field 'field' in the register pair 'from'
/// ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutWide {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutWide {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-wide {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutWide({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutWide {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x68,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the object reference in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutObject {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutObject {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-object {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutObject({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutObject {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x69,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the boolean in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutBoolean {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutBoolean {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-boolean {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutBoolean({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutBoolean {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x6a,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the byte in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutByte {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-byte {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutByte({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutByte {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x6b,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the char in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutChar {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-char {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutChar({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutChar {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x6c,
va: self.from,
b: field_idx as u16,
}
}
}
/// Put the short in the static field 'field' in 'from' ('from' is a register)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SPutShort {
#[pyo3(get)]
pub from: u8,
#[pyo3(get)]
pub field: IdField,
}
#[pymethods]
impl SPutShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(from: u8, field: IdField) -> Self {
Self { from, field }
}
pub fn __str__(&self) -> String {
format!("sput-short {} {}", self.from, self.field.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SPutShort({}, {}))",
self.from,
self.field.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.field.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.field.get_all_types()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
let mut fields = HashSet::new();
fields.insert(self.field.clone());
fields
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SPutShort {
/// Return the raw instruction ([`InsFormat`]).
///
/// `field_idx` is the index of the field refered to.
pub fn get_raw_ins(&self, field_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0x6d,
va: self.from,
b: field_idx as u16,
}
}
}
/// Call a normal virtual method.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokeVirtual {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeVirtual {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, args: Vec<u16>) -> Result<Self> {
let invoke = Self { method, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-virtual instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-virtual {{{}}} {}", args, self.method.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeVirtual({}, {}))",
args,
self.method.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.method.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.method.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.method.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokeVirtual {
/// Return the raw instruction ([`InsFormat`]).
///
/// `method_idx` is the index of the refered method.
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0x6e,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x74,
a,
vc,
b: meth_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Call the closest superclass's virtual method of a non interface class.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokeSuper {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeSuper {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, args: Vec<u16>) -> Result<Self> {
let invoke = Self { method, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-super instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-super {{{}}} {}", args, self.method.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeSuper({}, {}))",
args,
self.method.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.method.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.method.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.method.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokeSuper {
/// Return the raw instruction ([`InsFormat`]).
///
/// `method_idx` is the index of the refered method.
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0x6f,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x75,
a,
vc,
b: meth_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Call a direct method (non static non overridable, like private).
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokeDirect {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeDirect {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, args: Vec<u16>) -> Result<Self> {
let invoke = Self { method, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-direct instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-direct {{{}}} {}", args, self.method.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeDirect({}, {}))",
args,
self.method.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.method.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.method.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.method.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokeDirect {
/// Return the raw instruction ([`InsFormat`]).
///
/// `method_idx` is the index of the refered method.
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0x70,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x76,
a,
vc,
b: meth_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Call a static method.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokeStatic {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeStatic {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, args: Vec<u16>) -> Result<Self> {
let invoke = Self { method, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-static instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-static {{{}}} {}", args, self.method.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeStatic({}, {}))",
args,
self.method.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.method.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.method.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.method.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokeStatic {
/// Return the raw instruction ([`InsFormat`]).
///
/// `method_idx` is the index of the refered method.
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0x71,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x77,
a,
vc,
b: meth_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Call a interface method (method from an interface on an object whose class is unknown)
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokeInterface {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeInterface {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, args: Vec<u16>) -> Result<Self> {
let invoke = Self { method, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-interface instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-interface {{{}}} {}", args, self.method.__str__())
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeInterface({}, {}))",
args,
self.method.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.method.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.method.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.method.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokeInterface {
/// Return the raw instruction ([`InsFormat`]).
///
/// `method_idx` is the index of the refered method.
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0x72,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0x78,
a,
vc,
b: meth_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Put -val in dest.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NegInt {
dest: u8,
val: u8,
}
#[pymethods]
impl NegInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-int uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-int uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("neg-int {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NegInt({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NegInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x7b,
va: self.dest,
vb: self.val,
}
}
}
/// Put ~val in dest
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NotInt {
dest: u8,
val: u8,
}
#[pymethods]
impl NotInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"not-int uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"not-int uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("not-int {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NotInt({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NotInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x7c,
va: self.dest,
vb: self.val,
}
}
}
/// Put -val in dest. dest and val are pair registers.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NegLong {
dest: u8,
val: u8,
}
#[pymethods]
impl NegLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-long uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-long uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("neg-long {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NegLong({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NegLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x7d,
va: self.dest,
vb: self.val,
}
}
}
/// Put ~val in dest. dest and val are pair registers.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NotLong {
dest: u8,
val: u8,
}
#[pymethods]
impl NotLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"not-long uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"not-long uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("not-long {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NotLong({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NotLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x7e,
va: self.dest,
vb: self.val,
}
}
}
/// Put -val in dest.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NegFloat {
dest: u8,
val: u8,
}
#[pymethods]
impl NegFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-float uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-float uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("neg-float {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NegFloat({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NegFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x7f,
va: self.dest,
vb: self.val,
}
}
}
/// Put -val in dest.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct NegDouble {
dest: u8,
val: u8,
}
#[pymethods]
impl NegDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-double uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"neg-double uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("neg-double {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(NegDouble({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl NegDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x80,
va: self.dest,
vb: self.val,
}
}
}
/// Convert copy val to dest an convert to long.
///
/// TODO: dest is probably a pair register, but is val to?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToLong {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-long uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-long uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-long {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToLong({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x81,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the integer value to a float.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToFloat {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-float uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-float uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-float {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToFloat({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x82,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the integer value to a double
///
/// TODO: dest is probably a pair register, but is val to?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToDouble {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-double uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-double uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-double {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToDouble({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x83,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the long value to an integer.
///
/// TODO: val is probably a pair register, but is dest to?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct LongToInt {
dest: u8,
val: u8,
}
#[pymethods]
impl LongToInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-int uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-int uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("long-to-int {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(LongToInt({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl LongToInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x84,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the long value to a float.
///
/// TODO: val is probably a pair register, but is dest to?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct LongToFloat {
dest: u8,
val: u8,
}
#[pymethods]
impl LongToFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-float uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-float uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("long-to-float {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(LongToFloat({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl LongToFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x85,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the long value to a double.
///
/// dest and val are pair registers.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct LongToDouble {
dest: u8,
val: u8,
}
#[pymethods]
impl LongToDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-double uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"long-to-double uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("long-to-double {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(LongToDouble({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl LongToDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x86,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the float value to an integer.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct FloatToInt {
dest: u8,
val: u8,
}
#[pymethods]
impl FloatToInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-int uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-int uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("float-to-int {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(FloatToInt({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl FloatToInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x87,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the float value to a long.
///
/// TODO: dest is probably a pair register, but is val too?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct FloatToLong {
dest: u8,
val: u8,
}
#[pymethods]
impl FloatToLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-long uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-long uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("float-to-long {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(FloatToLong({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl FloatToLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x88,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the float value to a double.
///
/// TODO: dest is probably a pair register, but is val too?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct FloatToDouble {
dest: u8,
val: u8,
}
#[pymethods]
impl FloatToDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-double uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"float-to-double uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("float-to-double {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(FloatToDouble({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl FloatToDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x89,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the double value to an integer.
///
/// TODO: val is probably a pair register, but is dest too?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DoubleToInt {
dest: u8,
val: u8,
}
#[pymethods]
impl DoubleToInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-int uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-int uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("double-to-int {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DoubleToInt({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DoubleToInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8a,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the double value to a long.
///
/// val and dest are pair registers.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DoubleToLong {
dest: u8,
val: u8,
}
#[pymethods]
impl DoubleToLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-long uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-long uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("double-to-long {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DoubleToLong({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DoubleToLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8b,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the double value to a float.
///
/// TODO: val is probably a pair register, but is dest too?
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DoubleToFloat {
dest: u8,
val: u8,
}
#[pymethods]
impl DoubleToFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-float uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"double-to-float uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("double-to-float {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DoubleToFloat({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DoubleToFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8c,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the integer value to a byte.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToByte {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToByte {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-byte uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-byte uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-byte {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToByte({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToByte {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8d,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the integer value to a char.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToChar {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToChar {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-char uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-char uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-char {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToChar({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToChar {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8e,
va: self.dest,
vb: self.val,
}
}
}
/// Copy val to dest and convert the integer value to a short.
///
/// `dest` and `val` are registered indexed on 4 bits.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct IntToShort {
dest: u8,
val: u8,
}
#[pymethods]
impl IntToShort {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, val: u8) -> Result<Self> {
let ins = Self { dest, val };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-short uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.val & 0b1111_0000 != 0 {
Err(anyhow!(
"int-to-short uses registers indexed on 4 bits, found {}",
self.val
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("int-to-short {} {}", self.dest, self.val)
}
pub fn __repr__(&self) -> String {
format!("Instruction(IntToShort({}, {}))", self.dest, self.val)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl IntToShort {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0x8f,
va: self.dest,
vb: self.val,
}
}
}
/// Put a + b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AddInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("add-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AddInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x90,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a - b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl SubInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("sub-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(SubInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x91,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a * b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl MulInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("mul-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MulInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x92,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a / b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl DivInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("div-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DivInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x93,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a % b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl RemInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("rem-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(RemInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x94,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a & b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AndInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AndInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("and-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AndInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AndInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x95,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a | b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl OrInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("or-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(OrInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl OrInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x96,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a ^ b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct XorInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl XorInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("xor-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(XorInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl XorInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x97,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a << b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShlInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl ShlInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("shl-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShlInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShlInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x98,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a >> b (signed) in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShrInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl ShrInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("shr-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShrInt({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShrInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x99,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a >> b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct UshrInt {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl UshrInt {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("ushr-int {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(UshrInt({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl UshrInt {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9a,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a + b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AddLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("add-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AddLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9b,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a - b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl SubLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("sub-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SubLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9c,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a * b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl MulLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("mul-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(MulLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9d,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a / b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl DivLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("div-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(DivLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9e,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a % b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl RemLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("rem-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(RemLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0x9f,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a & b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AndLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AndLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("and-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AndLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AndLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa0,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a | b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl OrLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("or-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!("Instruction(OrLong({}, {}, {}))", self.dest, self.b, self.c)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl OrLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa1,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a ^ b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct XorLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl XorLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("xor-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(XorLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl XorLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa2,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a << b in dest.
///
/// dest, and b are register pairs, and c is a single register
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShlLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl ShlLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("shl-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ShlLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShlLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa3,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a >> b (signed) in dest.
///
/// dest, and b are register pairs, and c is a single register
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShrLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl ShrLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("shr-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ShrLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShrLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa4,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a >> b in dest.
///
/// dest, and b are register pairs, and c is a single register
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct UshrLong {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl UshrLong {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("ushr-long {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(UshrLong({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl UshrLong {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa5,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a + b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddFloat {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AddFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("add-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AddFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa6,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a - b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubFloat {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl SubFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("sub-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SubFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa7,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a * b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulFloat {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl MulFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("mul-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(MulFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa8,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a / b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivFloat {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl DivFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("div-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(DivFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xa9,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a % b in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemFloat {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl RemFloat {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("rem-float {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(RemFloat({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemFloat {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xaa,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a + b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddDouble {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl AddDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("add-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AddDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xab,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a - b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubDouble {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl SubDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("sub-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(SubDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xac,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a * b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulDouble {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl MulDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("mul-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(MulDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xad,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a / b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivDouble {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl DivDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("div-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(DivDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xae,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put a % b in dest.
///
/// dest, b and c are register pairs
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemDouble {
dest: u8,
b: u8,
c: u8,
}
#[pymethods]
impl RemDouble {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, c: u8) -> Self {
Self { dest, b, c }
}
pub fn __str__(&self) -> String {
format!("rem-double {} {} {}", self.dest, self.b, self.c)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(RemDouble({}, {}, {}))",
self.dest, self.b, self.c
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemDouble {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format23X {
op: 0xaf,
va: self.dest,
vb: self.b,
vc: self.c,
}
}
}
/// Put dest + b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AddInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"add-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"add-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("add-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AddInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb0,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest - b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl SubInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("sub-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(SubInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb1,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest * b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl MulInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("mul-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MulInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb2,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest / b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl DivInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"div-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"div-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("div-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DivInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb3,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest % b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl RemInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rem-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(RemInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb4,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest & b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AndInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AndInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"and-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"and-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("and-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AndInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AndInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb5,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest | b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl OrInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"or-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"or-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("or-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(OrInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl OrInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb6,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest ^ b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct XorInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl XorInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"xor-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"xor-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("xor-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(XorInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl XorInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb7,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest << b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShlInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl ShlInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"shl-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"shl-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("shl-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShlInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShlInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb8,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest >> b (signed) in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShrInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl ShrInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"shr-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"shr-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("shr-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShrInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShrInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xb9,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest >> b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct UshrInt2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl UshrInt2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"ushr-int/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"ushr-int/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("ushr-int/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(UshrInt2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl UshrInt2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xba,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest + b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AddLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"add-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"add-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("add-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AddLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xbb,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest - b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl SubLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("sub-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(SubLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xbc,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest * b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl MulLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("mul-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MulLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xbd,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest / b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl DivLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"div-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"div-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("div-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DivLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xbe,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest % b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl RemLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rem-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(RemLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xbf,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest & b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AndLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AndLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"and-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"and-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("and-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AndLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AndLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc0,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest | b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl OrLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"or-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"or-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("or-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(OrLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl OrLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc1,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest ^ b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct XorLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl XorLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"xor-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"xor-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("xor-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(XorLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl XorLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc2,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest << b in dest.
///
/// dest is a register pair, and b is a single register
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShlLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl ShlLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"shl-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"shl-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("shl-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShlLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShlLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc3,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest >> b (signed) in dest.
///
/// dest is a register pair, and b is a single register
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShrLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl ShrLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"shr-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"shr-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("shr-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(ShrLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShrLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc4,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest >> b in dest.
///
/// dest is a register pair, and b is a single register
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct UshrLong2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl UshrLong2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"ushr-long/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"ushr-long/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("ushr-long/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(UshrLong2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl UshrLong2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc5,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest + b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddFloat2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AddFloat2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"add-float/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"add-float/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("add-float/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AddFloat2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddFloat2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc6,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest - b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubFloat2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl SubFloat2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-float/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-float/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("sub-float/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(SubFloat2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubFloat2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc7,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest * b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulFloat2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl MulFloat2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-float/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-float/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("mul-float/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MulFloat2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulFloat2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc8,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest / b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivFloat2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl DivFloat2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"div-float/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"div-float/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("div-float/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DivFloat2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivFloat2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xc9,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest % b in dest.
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemFloat2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl RemFloat2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-float/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-float/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rem-float/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(RemFloat2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemFloat2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xca,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest + b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddDouble2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl AddDouble2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"add-double/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"add-double/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("add-double/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(AddDouble2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddDouble2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xcb,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest - b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct SubDouble2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl SubDouble2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-double/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"sub-double/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("sub-double/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(SubDouble2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl SubDouble2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xcc,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest * b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulDouble2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl MulDouble2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-double/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"mul-double/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("mul-double/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(MulDouble2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulDouble2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xcd,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest / b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivDouble2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl DivDouble2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"div-double/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"div-double/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("div-double/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(DivDouble2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivDouble2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xce,
va: self.dest,
vb: self.b,
}
}
}
/// Put dest % b in dest.
///
/// dest and b are register pairs
///
/// `dest` and `b` are registers indexed on 4 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemDouble2Addr {
dest: u8,
b: u8,
}
#[pymethods]
impl RemDouble2Addr {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8) -> Result<Self> {
let ins = Self { dest, b };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
if self.dest & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-double/2addr uses registers indexed on 4 bits, found {}",
self.dest
))
} else if self.b & 0b1111_0000 != 0 {
Err(anyhow!(
"rem-double/2addr uses registers indexed on 4 bits, found {}",
self.b
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rem-double/2addr {} {}", self.dest, self.b)
}
pub fn __repr__(&self) -> String {
format!("Instruction(RemDouble2Addr({}, {}))", self.dest, self.b)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemDouble2Addr {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format12X {
op: 0xcf,
va: self.dest,
vb: self.b,
}
}
}
/// Put b + lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AddIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl AddIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"add-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (add-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (add-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("add-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AddIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AddIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"add-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (add-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (add-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xd8,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd0,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put lit - b in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RsubIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl RsubIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"rsub-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (rsub-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (rsub-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rsub-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(RsubIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RsubIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"sub-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (sub-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (sub-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xd9,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd1,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b * lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct MulIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl MulIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"mul-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (mul-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (mul-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("mul-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(MulIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl MulIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"mul-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (mul-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (mul-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xda,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd2,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b / lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DivIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl DivIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"div-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (div-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (div-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("div-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(DivIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl DivIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"div-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (div-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (div-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xdb,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd3,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b % lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct RemIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl RemIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"rem-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (rem-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (rem-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("rem-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(RemIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl RemIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"rem-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (rem-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (rem-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xdc,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd4,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b & lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct AndIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl AndIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"and-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (and-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (and-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("and-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(AndIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl AndIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"and-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (and-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (and-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xdd,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd5,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b | lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl OrIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"or-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (or-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (or-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("or-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(OrIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl OrIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"or-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (or-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (or-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xde,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd6,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b ^ lit in dest.
///
/// Either `dest` and `b` are registers indexed on 4 bits and lit is encoded in 16 bits
/// or `dest` and `b` are registers indexed on 8 bits and lit is encoded in 8 bits
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct XorIntLit {
dest: u8,
b: u8,
lit: i16,
}
#[pymethods]
impl XorIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i16) -> Result<Self> {
let ins = Self { dest, b, lit };
ins.sanity_check()?;
Ok(ins)
}
pub fn sanity_check(&self) -> Result<()> {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
Err(anyhow!(
"xor-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (xor-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (xor-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest,
self.b,
self.lit
))
} else {
Ok(())
}
}
pub fn __str__(&self) -> String {
format!("xor-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(XorIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl XorIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
let mut reg_on_4_bit = true;
let mut lit_on_8_bits = true;
if self.dest & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.b & 0b1111_0000 != 0 {
reg_on_4_bit = false;
}
if self.lit < I8_MIN_AS_I16 || self.lit > I8_MAX_AS_I16 {
lit_on_8_bits = false;
}
if !reg_on_4_bit && !lit_on_8_bits {
// Should not happen on a sanitized op
panic!(
"xor-int/lit uses either registers indexed on 4 bits, and a literal \
encoded on 16 bits (xor-int/lit16), or registers indexed on 8 bits and \
a literal encoded on 8 bits (xor-int/lit8). Found reg {} and {}, and lit \
{}",
self.dest, self.b, self.lit
)
} else if lit_on_8_bits {
InsFormat::Format22B {
op: 0xdf,
va: self.dest,
vb: self.b,
c: self.lit as i8,
}
} else {
InsFormat::Format22S {
op: 0xd7,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
}
/// Put b << lit in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShlIntLit {
dest: u8,
b: u8,
lit: i8,
}
#[pymethods]
impl ShlIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i8) -> Self {
Self { dest, b, lit }
}
pub fn __str__(&self) -> String {
format!("shl-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ShlIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShlIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format22B {
op: 0xe0,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
/// Put b >> lit (signed) in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct ShrIntLit {
dest: u8,
b: u8,
lit: i8,
}
#[pymethods]
impl ShrIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i8) -> Self {
Self { dest, b, lit }
}
pub fn __str__(&self) -> String {
format!("shr-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ShrIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ShrIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format22B {
op: 0xe1,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
/// Put b >> lit in dest.
#[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct UshrIntLit {
dest: u8,
b: u8,
lit: i8,
}
#[pymethods]
impl UshrIntLit {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(dest: u8, b: u8, lit: i8) -> Self {
Self { dest, b, lit }
}
pub fn __str__(&self) -> String {
format!("ushr-int/lit {} {} {}", self.dest, self.b, self.lit)
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(UshrIntLit({}, {}, {}))",
self.dest, self.b, self.lit
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
self.get_raw_ins().size()
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl UshrIntLit {
/// Return the raw instruction ([`InsFormat`]).
pub fn get_raw_ins(&self) -> InsFormat {
InsFormat::Format22B {
op: 0xe2,
va: self.dest,
vb: self.b,
c: self.lit,
}
}
}
/// Call a polymorphic method.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct InvokePolymorphic {
#[pyo3(get)]
pub method: IdMethod,
#[pyo3(get)]
pub proto: IdMethodType,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokePolymorphic {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(method: IdMethod, proto: IdMethodType, args: Vec<u16>) -> Result<Self> {
let invoke = Self {
method,
proto,
args,
};
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-polymorphic instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"invoke-polymorphic {{{}}} {} {}",
args,
self.method.__str__(),
self.proto.__str__()
)
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokePolymorphic({}, {}, {}))",
args,
self.method.__str__(),
self.proto.__str__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
8
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
let mut strings = self.method.get_all_strings();
strings.extend(self.proto.get_all_strings());
strings
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = self.method.get_all_types();
types.extend(self.proto.get_all_types());
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
let mut protos = self.method.get_all_protos();
protos.insert(self.proto.clone());
protos
}
/// Return all field ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
let mut methods = HashSet::new();
methods.insert(self.method.clone());
methods
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl InvokePolymorphic {
/// Return the raw instruction ([`InsFormat`]).
///
/// - `method_idx` is the index of the refered method.
/// - `proto_idx` is the index of the protoype used.
pub fn get_raw_ins(&self, meth_idx: u16, proto_idx: u16) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format45CC {
op: 0xfa,
a,
vc,
ve,
vd,
vf,
vg,
b: meth_idx,
h: proto_idx,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format4RCC {
op: 0xfb,
a,
vc,
b: meth_idx,
h: proto_idx,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Invoke a method from a call site.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct InvokeCustom {
#[pyo3(get)]
pub call_site: CallSite,
#[pyo3(get)]
pub args: Vec<u16>,
}
#[pymethods]
impl InvokeCustom {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(call_site: CallSite, args: Vec<u16>) -> Result<Self> {
let invoke = Self { call_site, args };
invoke.sanity_check()?;
Ok(invoke)
}
pub fn sanity_check(&self) -> Result<()> {
let mut last = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if (four_bites && len <= 5) || (consec && len <= 255) {
Ok(())
} else {
Err(anyhow!(
"invoke-custom instruction must either use 5 or \
less register indexed on 4 bites or less than 255 \
consecutive registers"
))
}
}
pub fn __str__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!("invoke-custom {{{}}} {}", args, self.call_site.__str__(),)
}
pub fn __repr__(&self) -> String {
let args = if self.args.len() >= 5 {
format!("{} .. {}", self.args[0], self.args[self.args.len() - 1])
} else {
self.args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<_>>()
.join(" ")
};
format!(
"Instruction(InvokeCustom({}, {}))",
args,
self.call_site.__str__(),
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
6
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.call_site.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.call_site.get_all_types()
}
/// Return all strings referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.call_site.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
self.call_site.get_all_field_ids()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
self.call_site.get_all_method_ids()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
self.call_site.get_all_method_handles()
}
}
impl InvokeCustom {
/// Return the raw instruction ([`InsFormat`]).
///
/// - `call_site_idx` is the index of the call site.
pub fn get_raw_ins(&self, call_site_idx: usize) -> InsFormat {
let mut last = None;
let mut first = None;
let mut consec = true;
let mut four_bites = true;
let len = self.args.len();
for r in self.args.iter().cloned() {
if first.is_none() {
first = Some(r);
}
if let Some(last) = last {
if r != last + 1 {
consec = false;
}
}
if r & 0b1111_0000 != 0 {
four_bites = false;
}
last = Some(r);
}
if four_bites && len <= 5 {
let mut regs = vec![];
for reg in self.args.iter().cloned() {
regs.push(reg);
}
while regs.len() != 5 {
regs.push(0);
}
let [vc, vd, ve, vf, vg]: [u8; 5] = regs
.into_iter()
.map(|r| r as u8)
.collect::<Vec<_>>()
.try_into()
.ok()
.unwrap();
let a = self.args.len() as u8;
InsFormat::Format35C {
op: 0xfc,
a,
vc,
ve,
vd,
vf,
vg,
b: call_site_idx as u16,
}
} else if consec && len <= 255 {
let a = self.args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 };
InsFormat::Format3RC {
op: 0xfd,
a,
vc,
b: call_site_idx as u16,
}
} else {
// Not supposed to happend with a sanitized invoke
panic!("Invalid Invoke instruction {self:?}")
}
}
}
/// Put contents reference to the method handle in the register.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ConstMethodHandle {
#[pyo3(get)]
pub handle: MethodHandle,
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl ConstMethodHandle {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, handle: MethodHandle) -> Self {
Self { to, handle }
}
pub fn __str__(&self) -> String {
format!("const-method-handle {} {}", self.to, self.handle.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ConstMethodHandle({}, {}))",
self.to,
self.handle.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.handle.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.handle.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
self.handle.get_all_protos()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
self.handle.get_all_field_ids()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
self.handle.get_all_method_ids()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
self.handle.get_all_method_handles()
}
}
impl ConstMethodHandle {
/// Return the raw instruction ([`InsFormat`]).
///
/// - `method_handle_idx` is the index of the method handle.
pub fn get_raw_ins(&self, method_handle_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0xfe,
va: self.to,
b: method_handle_idx as u16,
}
}
}
/// Put contents reference to the prototype in the register.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ConstMethodType {
#[pyo3(get)]
pub proto: IdMethodType,
#[pyo3(get)]
pub to: u8,
}
#[pymethods]
impl ConstMethodType {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(to: u8, proto: IdMethodType) -> Self {
Self { to, proto }
}
pub fn __str__(&self) -> String {
format!("const-method-type {} {}", self.to, self.proto.__str__())
}
pub fn __repr__(&self) -> String {
format!(
"Instruction(ConstMethodType({}, {}))",
self.to,
self.proto.__repr__()
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
4
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
self.proto.get_all_strings()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
self.proto.get_all_types()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
let mut protos = HashSet::new();
protos.insert(self.proto.clone());
protos
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
impl ConstMethodType {
/// Return the raw instruction ([`InsFormat`]).
///
/// - `proto_idx` is the index of the method protoype.
pub fn get_raw_ins(&self, proto_idx: usize) -> InsFormat {
InsFormat::Format21C {
op: 0xff,
va: self.to,
b: proto_idx as u16,
}
}
}
/// Try block. It does not match an dalvik instruction but is derived from the code item struct.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Try {
#[pyo3(get)]
pub end_label: String,
/// The list of exceptions and their associated handler label.
///
/// # Warning
///
/// The handler are sorted: if severat Exception Type match an exceptions, the
/// the handler used is the first in the list.
#[pyo3(get)]
pub handlers: Vec<(IdType, String)>,
#[pyo3(get)]
pub default_handler: Option<String>,
}
#[pymethods]
impl Try {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(
end_label: String,
handlers: Vec<(IdType, String)>,
default_handler: Option<String>,
) -> Self {
Self {
end_label,
default_handler,
handlers,
}
}
pub fn __str__(&self) -> String {
let handlers = self
.handlers
.iter()
.map(|(ty, label)| format!(" {}: {label}", ty.__str__()))
.collect::<Vec<_>>()
.join("\n ");
let default_handler = if let Some(label) = &self.default_handler {
format!(" default: {label}")
} else {
"".into()
};
format!(
"try until {}{}{}",
self.end_label, handlers, default_handler
)
}
pub fn __repr__(&self) -> String {
let handlers = self
.handlers
.iter()
.map(|(ty, label)| format!("{}, {label}", ty.__repr__()))
.collect::<Vec<_>>()
.join(", ");
format!(
"Instruction(Try({}, [{}], {:?}))",
self.end_label, handlers, self.default_handler,
)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
0
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
let mut strings = HashSet::new();
for (ty, _) in &self.handlers {
strings.extend(ty.get_all_strings());
}
strings
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
let mut types = HashSet::new();
for (ty, _) in &self.handlers {
types.insert(ty.clone());
}
types
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}
/// Label marker. It does not match an dalvik instruction, but it's use as a marker for a
/// jump destination.
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Label {
#[pyo3(get)]
pub name: String,
}
#[pymethods]
impl Label {
pub fn __eq__(&self, other: &Self) -> bool {
self == other
}
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new]
pub fn new(name: String) -> Self {
Self { name }
}
pub fn __str__(&self) -> String {
format!("{}:", self.name)
}
pub fn __repr__(&self) -> String {
format!("Instruction(Label({}))", self.name)
}
/// Return the smallest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn min_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the bigest size possible for the associated instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn max_ins_size(&self) -> usize {
self.ins_size()
}
/// Return the actual size of the instruction.
///
/// # Warning
///
/// The returned size is the size in bytes (`u8`) (the same as the value return
/// by the `Serializable::size()` method), but instructions in the bytecode
/// count addresses by unit of `u16`.
pub fn ins_size(&self) -> usize {
0
}
/// Return all strings referenced in the instruction.
pub fn get_all_strings(&self) -> HashSet<DexString> {
HashSet::new()
}
/// Return all types referenced in the instruction.
pub fn get_all_types(&self) -> HashSet<IdType> {
HashSet::new()
}
/// Return all prototypes referenced in the instruction.
pub fn get_all_protos(&self) -> HashSet<IdMethodType> {
HashSet::new()
}
/// Return all field ids referenced in the instruction.
pub fn get_all_field_ids(&self) -> HashSet<IdField> {
HashSet::new()
}
/// Return all method ids referenced in the instruction.
pub fn get_all_method_ids(&self) -> HashSet<IdMethod> {
HashSet::new()
}
/// Return all method handles referenced in the instruction.
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
HashSet::new()
}
}