29126 lines
886 KiB
Rust
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()
|
|
}
|
|
}
|