From cfbd3fb90ba27faa0ef99aed87fe70d7233cce26 Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Tue, 16 Jul 2024 00:42:49 +0200 Subject: [PATCH] WIP --- androscalpel/src/dex_writer.rs | 129 +--- androscalpel/src/instructions.rs | 1120 ++++++++++++++++-------------- 2 files changed, 617 insertions(+), 632 deletions(-) diff --git a/androscalpel/src/dex_writer.rs b/androscalpel/src/dex_writer.rs index f11464f..04c55b9 100644 --- a/androscalpel/src/dex_writer.rs +++ b/androscalpel/src/dex_writer.rs @@ -438,18 +438,17 @@ impl DexWriter { for ins in &code.insns { match ins { - Instruction::Label(Label { name }) => { + Instruction::Label { name } => { label_min_max_addrs.insert(name.clone(), (min_addr, max_addr)); min_addr += ins.min_ins_size() / 2; max_addr += ins.max_ins_size() / 2; } - Instruction::ConstString(ins) => { - let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!( - "String {} (found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let size = ins.get_raw_ins(*string_idx).size() / 2; + Instruction::ConstString { .. } => { + let size = ins + .get_raw_ins(Some(&self.strings)) + .with_context(|| format!("In code of {}", method_id.__repr__()))? + .size() + / 2; min_addr += size; max_addr += size; } @@ -465,23 +464,23 @@ impl DexWriter { let mut goto_sizes = vec![]; for ins in &code.insns { match ins { - Instruction::Label(Label { name }) => { + Instruction::Label { name } => { label_addrs.insert(name.clone(), addr); addr += ins.max_ins_size() / 2; } - Instruction::ConstString(ins) => { - let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!( - "String {} (found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - addr += ins.get_raw_ins(*string_idx).size() / 2; + Instruction::ConstString { .. } => { + addr += ins.get_raw_ins(Some(&self.strings, None))?.size() / 2; + // should not fail after + // first loop, no need + // for context } - Instruction::Goto(Goto { label }) => { + Instruction::Goto { label } => { let (min_addr, max_addr) = label_min_max_addrs .get(label) .ok_or(anyhow!("Label {label} not found in label estimation map"))?; - let size = Goto::size_from_branch_offset_interval(addr, *min_addr, *max_addr)?; + let size = Instruction::goto_size_from_branch_offset_interval( + addr, *min_addr, *max_addr, + )?; goto_sizes.push(size); addr += size / 2; } @@ -502,86 +501,20 @@ impl DexWriter { addr = 0; for ins in &code.insns { match ins { - Instruction::ConstString(ins) => { - let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!( - "String {} (found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(*string_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::ConstClass(ins) => { - let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!( - "Class {} (type of class found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::CheckCast(ins) => { - let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!( - "Class {} (type of class found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InstanceOf(ins) => { - let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!( - "Class {} (type of class found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::NewInstance(ins) => { - let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!( - "Class {} (type of class found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::NewArray(ins) => { - let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!( - "Type {} (type found in code of {}) not found in dex builder", - ins.lit.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::FilledNewArray(ins) => { - let class_idx = *self.type_ids.get(&ins.type_).ok_or(anyhow!( - "Type {} (type found in code of {}) not found in dex builder", - ins.type_.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(class_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::FillArrayData(ins) => { + Instruction::FillArrayData { + data, + elt_width, + arr, + } => { let payload = InsFormat::FormatFillArrayDataPayload { - elt_width: ins.elt_width, - data: ins.data.clone(), + elt_width: *elt_width, + data: data.clone(), }; if payload_addr % 2 != 0 { // https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1347 // The ART check if the array data table is 4 bytes aligned (= 2 ins alligned) // TODO: check how it is donne in android and other dex generation code. - let nop = (Instruction::Nop {}).get_raw_ins()?; + let nop = (Instruction::Nop {}).get_raw_ins(None, None)?; payload_addr += nop.size() / 2; payloads.push(nop); } @@ -1372,15 +1305,17 @@ impl DexWriter { handler_off += catches.size(); handlers.list.push(catches); } - Instruction::Label(_) => (), + Instruction::Label { .. } => (), _ => { - let ins = ins.get_raw_ins().with_context(|| { - format!( + let ins = ins + .get_raw_ins(Some(&self.strings), Some(&self.type_ids)) + .with_context(|| { + format!( "Failed to convert instruction {} (found in code of {}) to raw instruction", ins.__repr__(), method_id.__repr__() ) - })?; + })?; addr += ins.size() / 2; insns.push(ins); } @@ -1388,7 +1323,7 @@ impl DexWriter { } if addr % 2 != 0 { // make sure the payload section is 4 bytes aligned - let nop = (Instruction::Nop {}).get_raw_ins()?; + let nop = (Instruction::Nop {}).get_raw_ins(None, None)?; //addr += nop.size() / 2; insns.push(nop); } diff --git a/androscalpel/src/instructions.rs b/androscalpel/src/instructions.rs index f0b8850..7bb15db 100644 --- a/androscalpel/src/instructions.rs +++ b/androscalpel/src/instructions.rs @@ -3881,22 +3881,28 @@ impl Instruction { impl Instruction { /// Return the raw instruction ([`InsFormat`]) when it does not need additionnal data. /// - /// # Warning + /// Some instruction require additional data, provided as options. If the required information + /// is not provided, the method will return an error. /// - /// Some instruction require additionnal data, or do not have associated instruction format. - /// This method will return an error for thos instruction. + /// # Variants that require `strings` /// - /// This method should be used in a match statetement in the default branch, for brevity. - /// - /// # Variants that do not implement this method: + /// `strings` is a lookup table that associate it's idx to a string. /// /// - `ConstString` + /// + /// # Variants that require `types_ids` + /// + /// `types_ids` is a lookup table that associate it'ss idx to a type. + /// /// - `ConstClass` /// - `CheckCast` /// - `InstanceOf` /// - `NewInstance` /// - `NewArray` /// - `FilledNewArray` + /// + /// # Variants that do not implement this method: + /// /// - `FillArrayData` /// - `Goto` /// - `Switch` @@ -3951,376 +3957,98 @@ impl Instruction { /// - `ConstMethodType` /// - `Try` /// - `Label` - pub fn get_raw_ins(&self) -> Result { - match self { - Self::ConstString { .. } => Err(anyhow!( + pub fn get_raw_ins( + &self, + strings: Option<&HashMap>, + type_ids: Option<&HashMap>, + ) -> Result { + match (self, strings, type_ids) { + (Self::ConstString { .. }, None, _type_ids) => Err(anyhow!( "Cannot get the raw instruction of a const-string without knowing the string idx" )), - Self::ConstClass { .. } => Err(anyhow!( + (Self::ConstString { reg, lit }, Some(strings), _type_ids) => { + let string_idx = strings.get(lit).ok_or(anyhow!( + "String {} not found in dex builder", + lit.__repr__(), + ))?; + match string_idx { + 0..=U16_MAX_AS_USIZE => Ok(InsFormat::Format21C { + op: 0x1a, + va: *reg, + b: *string_idx as u16, + }), + _ => Ok(InsFormat::Format31C { + op: 0x1b, + va: *reg, + b: *string_idx as u32, + }), + } + } + (Self::ConstClass { .. }, _strings, None) => Err(anyhow!( "Cannot get the raw instruction of a const-class without knowing the class idx" )), - 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::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::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::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::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::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 converted to raw instruction")), - Self::Nop {} => Ok(InsFormat::Format10X { op: 0x00 }), - Self::Move { from, to } => match (to, from) { - (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { - op: 0x01, - va: *to as u8, - vb: *from as u8, - }), - (0..=0xff, _) => Ok(InsFormat::Format22X { - op: 0x02, - va: *to as u8, - vb: *from, - }), - (_, _) => Ok(InsFormat::Format32X { - op: 0x03, - va: *to, - vb: *from, - }), - }, - Self::MoveWide { from, to } => match (to, from) { - (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { - op: 0x04, - va: *to as u8, - vb: *from as u8, - }), - (0..=0xff, _) => Ok(InsFormat::Format22X { - op: 0x05, - va: *to as u8, - vb: *from, - }), - (_, _) => Ok(InsFormat::Format32X { - op: 0x06, - va: *to, - vb: *from, - }), - }, - Self::MoveObject { from, to } => match (to, from) { - (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { - op: 0x07, - va: *to as u8, - vb: *from as u8, - }), - (0..=0xff, _) => Ok(InsFormat::Format22X { - op: 0x08, - va: *to as u8, - vb: *from, - }), - (_, _) => Ok(InsFormat::Format32X { - op: 0x09, - va: *to, - vb: *from, - }), - }, - Self::MoveResult { to } => Ok(InsFormat::Format11X { op: 0x0a, va: *to }), - Self::MoveResultWide { to } => Ok(InsFormat::Format11X { op: 0x0b, va: *to }), - Self::MoveResultObject { to } => Ok(InsFormat::Format11X { op: 0x0c, va: *to }), - Self::MoveException { to } => Ok(InsFormat::Format11X { op: 0x0d, va: *to }), - Self::ReturnVoid {} => Ok(InsFormat::Format10X { op: 0x0e }), - Self::Return { reg } => Ok(InsFormat::Format11X { op: 0x0f, va: *reg }), - Self::ReturnWide { reg } => Ok(InsFormat::Format11X { op: 0x10, va: *reg }), - Self::ReturnObject { reg } => Ok(InsFormat::Format11X { op: 0x11, va: *reg }), - Self::Const { lit, reg } => match (reg, lit) { - (0..=0b0000_1111, -8..=7) => Ok(InsFormat::Format11N { - op: 0x12, - va: *reg, - b: *lit as i8, - }), - (_, I16_MIN_AS_I32..=I16_MAX_AS_I32) => Ok(InsFormat::Format21S { - op: 0x13, - va: *reg, - b: *lit as i16, - }), - (_, lit) if lit % 0x1_0000 == 0 => Ok(InsFormat::Format21H { - op: 0x15, - va: *reg, - b: (*lit / 0x1_0000) as i16, - }), - (_, _) => Ok(InsFormat::Format31I { - op: 0x14, - va: *reg, - b: *lit, - }), - }, - Self::ConstWide { lit, reg } => match lit { - I16_MIN_AS_I64..=I16_MAX_AS_I64 => Ok(InsFormat::Format21S { - op: 0x16, - va: *reg, - b: *lit as i16, - }), - I32_MIN_AS_I64..=I32_MAX_AS_I64 => Ok(InsFormat::Format31I { - op: 0x17, - va: *reg, - b: *lit as i32, - }), - lit if lit % 0x1_0000_0000_0000 == 0 => Ok(InsFormat::Format21H { - op: 0x19, - va: *reg, - b: (*lit / 0x1_0000_0000_0000) as i16, - }), - _ => Ok(InsFormat::Format51L { - op: 0x18, - va: *reg, - b: *lit, - }), - }, - /* needs string_idx - Self::ConstString { reg, string_idx } => match string_idx { - 0..=U16_MAX_AS_USIZE => Ok(InsFormat::Format21C { - op: 0x1a, - va: *reg, - b: string_idx as u16, - }, - _ => Ok(InsFormat::Format31C { - op: 0x1b, - va: *reg, - b: string_idx as u32, - }), - }, - */ - /* needs cclass_idx - Self::ConstClass { reg, class_idx} => Ok(InsFormat::Format21C { + (Self::ConstClass { reg, lit }, _strings, Some(types)) => Ok(InsFormat::Format21C { op: 0x1c, va: *reg, - b: *class_idx as u16, + b: *types + .get(lit) + .ok_or(anyhow!("Class {} not found in dex builder", lit.__repr__(),))? + as u16, }), - */ - Self::MonitorEnter { reg } => Ok(InsFormat::Format11X { op: 0x1d, va: *reg }), - Self::MonitorExit { reg } => Ok(InsFormat::Format11X { op: 0x1e, va: *reg }), - /* needs type_idx - Self::CheckCast {reg, type_idx} => Ok(InsFormat::Format21C { + (Self::CheckCast { .. }, _strings, None) => Err(anyhow!( + "Cannot get the raw instruction of a check-cast without knowing the type idx" + )), + (Self::CheckCast { reg, lit }, _strings, Some(types)) => Ok(InsFormat::Format21C { op: 0x1f, va: *reg, - b: *type_idx as u16, + b: *types + .get(lit) + .ok_or(anyhow!("Class {} not found in dex builder", lit.__repr__(),))? + as u16, }), - */ - /* needs type_idx - Self::InstanceOf { dest, obj, type_idx } => Ok(InsFormat::Format22C { - op: 0x20, - va: *dest, - vb: *obj, - c: type_idx as u16, - }, - */ - Self::ArrayLength { dest, arr } => Ok(InsFormat::Format12X { - op: 0x21, - va: *dest, - vb: *arr, - }), - /* needs type_idx - Self::NewInstance {reg, type_idx} => Ok(InsFormat::Format21C { + (Self::InstanceOf { .. }, _strings, None) => Err(anyhow!( + "Cannot get the raw instruction of a instance-of without knowing the type idx" + )), + (Self::InstanceOf { dest, obj, lit }, _strings, Some(types)) => { + Ok(InsFormat::Format22C { + op: 0x20, + va: *dest, + vb: *obj, + c: *types + .get(lit) + .ok_or(anyhow!("Class {} not found in dex builder", lit.__repr__(),))? + as u16, + }) + } + (Self::NewInstance { .. }, _strings, None) => Err(anyhow!( + "Cannot get the raw instruction of a new-instance without knowing the class idx" + )), + (Self::NewInstance { reg, lit }, _strings, Some(types)) => Ok(InsFormat::Format21C { op: 0x22, va: *reg, - b: *type_idx as u16, + b: *types + .get(lit) + .ok_or(anyhow!("Class {} not found in dex builder", lit.__repr__(),))? + as u16, }), - */ - /* needs type_idx - Self::NewArray { reg, size_reg, type_idx} => Ok(InsFormat::Format22C { - op: 0x23, - va: *reg, - vb: *size_reg, - c: *type_idx as u16, - }), - */ - /* need type_idx - Self::FilledNewArray { reg_values } => { + (Self::NewArray { .. }, _strings, None) => Err(anyhow!( + "Cannot get the raw instruction of a new-array without knowing the type idx" + )), + (Self::NewArray { reg, size_reg, lit }, _strings, Some(types)) => { + Ok(InsFormat::Format22C { + op: 0x23, + va: *reg, + vb: *size_reg, + c: *types + .get(lit) + .ok_or(anyhow!("Type {} not found in dex builder", lit.__repr__(),))? + as u16, + }) + } + (Self::FilledNewArray { .. }, _strings, None) => Err(anyhow!( + "Cannot get the raw instruction of a filled-new-array without knowing the type idx" + )), + (Self::FilledNewArray { reg_values, type_ }, _strings, Some(types)) => { let mut last = None; let mut first = None; let mut consec = true; @@ -4364,7 +4092,9 @@ impl Instruction { vd, vf, vg, - b: type_idx as u16, + b: *types + .get(type_) + .ok_or(anyhow!("Type {} not found in dex builder", type_.__repr__(),))? as u16, }) } else if consec && len <= 255 { let a = reg_values.len() as u8; @@ -4373,24 +4103,342 @@ impl Instruction { op: 0x25, a, vc, - b: type_idx as u16, + b: *types + .get(type_) + .ok_or(anyhow!("Type {} not found in dex builder", type_.__repr__(),))? as u16, }) } else { // Not supposed to happend with a sanitized array panic!("Invalid NewArrayInstruction {self:?}") } } + (Self::FillArrayData { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a fill-array-data without knowing the offset \ + to the -fill-array-data-payload" + )), + (Self::Goto { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the size of a goto without knowing the branch offset" + )), + (Self::Switch { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a switch without knowing the offset \ + to the packed/sparse-switch-payload" + )), + (Self::IfEq { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-eq without knowing \ + the offset to the branch" + )), + (Self::IfNe { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-ne without knowing \ + the offset to the branch" + )), + (Self::IfLt { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-lt without knowing \ + the offset to the branch" + )), + (Self::IfGe { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-ge without knowing \ + the offset to the branch" + )), + (Self::IfGt { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-gt without knowing \ + the offset to the branch" + )), + (Self::IfLe { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-le without knowing \ + the offset to the branch" + )), + (Self::IfEqZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-eqz without knowing \ + the offset to the branch" + )), + (Self::IfNeZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-nez without knowing \ + the offset to the branch" + )), + (Self::IfLtZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-ltz without knowing \ + the offset to the branch" + )), + (Self::IfGeZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-gez without knowing \ + the offset to the branch" + )), + (Self::IfGtZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-gtz without knowing \ + the offset to the branch" + )), + (Self::IfLeZ { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a if-lez without knowing \ + the offset to the branch" + )), + (Self::IGet { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget without knowing the field idx" + )), + (Self::IGetWide { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-wide without knowing the field idx" + )), + (Self::IGetObject { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-object without knowing the field idx" + )), + (Self::IGetBoolean { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-boolean without knowing the field idx" + )), + (Self::IGetByte { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-byte without knowing the field idx" + )), + (Self::IGetChar { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-char without knowing the field idx" + )), + (Self::IGetShort { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iget-short without knowing the field idx" + )), + (Self::IPut { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput without knowing the field idx" + )), + (Self::IPutWide { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-wide without knowing the field idx" + )), + (Self::IPutObject { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-object without knowing the field idx" + )), + (Self::IPutBoolean { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-boolean without knowing the field idx" + )), + (Self::IPutByte { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-byte without knowing the field idx" + )), + (Self::IPutChar { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-char without knowing the field idx" + )), + (Self::IPutShort { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a iput-short without knowing the field idx" + )), + (Self::SGet { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget without knowing the field idx" + )), + (Self::SGetWide { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-wide without knowing the field idx" + )), + (Self::SGetObject { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-object without knowing the field idx" + )), + (Self::SGetBoolean { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-boolean without knowing the field idx" + )), + (Self::SGetByte { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-byte without knowing the field idx" + )), + (Self::SGetChar { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-char without knowing the field idx" + )), + (Self::SGetShort { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sget-short without knowing the field idx" + )), + (Self::SPut { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput without knowing the field idx" + )), + (Self::SPutWide { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-wide without knowing the field idx" + )), + (Self::SPutObject { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-object without knowing the field idx" + )), + (Self::SPutBoolean { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-boolean without knowing the field idx" + )), + (Self::SPutByte { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-byte without knowing the field idx" + )), + (Self::SPutChar { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-char without knowing the field idx" + )), + (Self::SPutShort { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a sput-short without knowing the field idx" + )), + (Self::InvokeVirtual { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-virtual without knowing \ + the method idx" + )), + (Self::InvokeSuper { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-super without knowing \ + the method idx" + )), + (Self::InvokeDirect { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-direct without knowing \ + the method idx" + )), + (Self::InvokeStatic { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-static without knowing \ + the method idx" + )), + (Self::InvokeInterface { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-interface without knowing \ + the method idx" + )), + (Self::InvokePolymorphic { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-polymorphic without knowing \ + the method idx and proto idx" + )), + (Self::InvokeCustom { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-custom without knowing the \ + call site idx" + )), + (Self::ConstMethodHandle { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a const-method-handle \ + without knowing the method handle idx" + )), + (Self::ConstMethodType { .. }, _strings, _types) => Err(anyhow!( + "Cannot get the raw instruction of a const-method-type \ + without knowing the proto idx" + )), + (Self::Try { .. }, _strings, _types) => Err(anyhow!( + "Try instruction cannot be converted to raw instruction" + )), + (Self::Label { .. }, _strings, _types) => { + Err(anyhow!("Label cannot be converted to raw instruction")) + } + (Self::Nop {}, _strings, _types) => Ok(InsFormat::Format10X { op: 0x00 }), + (Self::Move { from, to }, _strings, _types) => match (to, from) { + (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { + op: 0x01, + va: *to as u8, + vb: *from as u8, + }), + (0..=0xff, _) => Ok(InsFormat::Format22X { + op: 0x02, + va: *to as u8, + vb: *from, + }), + (_, _) => Ok(InsFormat::Format32X { + op: 0x03, + va: *to, + vb: *from, + }), + }, + (Self::MoveWide { from, to }, _strings, _types) => match (to, from) { + (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { + op: 0x04, + va: *to as u8, + vb: *from as u8, + }), + (0..=0xff, _) => Ok(InsFormat::Format22X { + op: 0x05, + va: *to as u8, + vb: *from, + }), + (_, _) => Ok(InsFormat::Format32X { + op: 0x06, + va: *to, + vb: *from, + }), + }, + (Self::MoveObject { from, to }, _strings, _types) => match (to, from) { + (0..=0b0000_1111, 0..=0b0000_1111) => Ok(InsFormat::Format12X { + op: 0x07, + va: *to as u8, + vb: *from as u8, + }), + (0..=0xff, _) => Ok(InsFormat::Format22X { + op: 0x08, + va: *to as u8, + vb: *from, + }), + (_, _) => Ok(InsFormat::Format32X { + op: 0x09, + va: *to, + vb: *from, + }), + }, + (Self::MoveResult { to }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x0a, va: *to }) + } + (Self::MoveResultWide { to }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x0b, va: *to }) + } + (Self::MoveResultObject { to }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x0c, va: *to }) + } + (Self::MoveException { to }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x0d, va: *to }) + } + (Self::ReturnVoid {}, _strings, _types) => Ok(InsFormat::Format10X { op: 0x0e }), + (Self::Return { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x0f, va: *reg }) + } + (Self::ReturnWide { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x10, va: *reg }) + } + (Self::ReturnObject { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x11, va: *reg }) + } + (Self::Const { lit, reg }, _strings, _types) => match (reg, lit) { + (0..=0b0000_1111, -8..=7) => Ok(InsFormat::Format11N { + op: 0x12, + va: *reg, + b: *lit as i8, + }), + (_, I16_MIN_AS_I32..=I16_MAX_AS_I32) => Ok(InsFormat::Format21S { + op: 0x13, + va: *reg, + b: *lit as i16, + }), + (_, lit) if lit % 0x1_0000 == 0 => Ok(InsFormat::Format21H { + op: 0x15, + va: *reg, + b: (*lit / 0x1_0000) as i16, + }), + (_, _) => Ok(InsFormat::Format31I { + op: 0x14, + va: *reg, + b: *lit, + }), + }, + (Self::ConstWide { lit, reg }, _strings, _types) => match lit { + I16_MIN_AS_I64..=I16_MAX_AS_I64 => Ok(InsFormat::Format21S { + op: 0x16, + va: *reg, + b: *lit as i16, + }), + I32_MIN_AS_I64..=I32_MAX_AS_I64 => Ok(InsFormat::Format31I { + op: 0x17, + va: *reg, + b: *lit as i32, + }), + lit if lit % 0x1_0000_0000_0000 == 0 => Ok(InsFormat::Format21H { + op: 0x19, + va: *reg, + b: (*lit / 0x1_0000_0000_0000) as i16, + }), + _ => Ok(InsFormat::Format51L { + op: 0x18, + va: *reg, + b: *lit, + }), + }, + (Self::MonitorEnter { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x1d, va: *reg }) + } + (Self::MonitorExit { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x1e, va: *reg }) + } + (Self::ArrayLength { dest, arr }, _strings, _types) => Ok(InsFormat::Format12X { + op: 0x21, + va: *dest, + vb: *arr, + }), */ /* needs data_offset - Self::FillArrayData { arr, data_offset } => Ok(InsFormat::Format31T { + (Self::FillArrayData { arr, data_offset }, _strings, _types) => Ok(InsFormat::Format31T { op: 0x26, va: *arr, b: data_offset, }), */ - Self::Throw { reg } => Ok(InsFormat::Format11X { op: 0x27, va: *reg }), + (Self::Throw { reg }, _strings, _types) => { + Ok(InsFormat::Format11X { op: 0x27, va: *reg }) + } /* needs data_offset - Self::Goto { data_offset } => { + (Self::Goto { data_offset }, _strings, _types) => { if goto_size == 2 && (I8_MIN_AS_I32..=I8_MAX_AS_I32).contains(&data_offset) { Ok(InsFormat::Format10T { op: 0x28, @@ -4413,352 +4461,352 @@ impl Instruction { } */ /* needs data_offset - Self::Switch {reg, data_offset} => Ok(InsFormat::Format31T { + (Self::Switch {reg, data_offset}, _strings, _types) => Ok(InsFormat::Format31T { op: if is_packed() { 0x2b } else { 0x2c }, va: *reg, b: data_offset, }), */ - Self::CmpLFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::CmpLFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x2d, va: *dest, vb: *b, vc: *c, }), - Self::CmpGFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::CmpGFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x2e, va: *dest, vb: *b, vc: *c, }), - Self::CmpLDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::CmpLDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x2f, va: *dest, vb: *b, vc: *c, }), - Self::CmpGDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::CmpGDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x30, va: *dest, vb: *b, vc: *c, }), - Self::CmpLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::CmpLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x31, va: *dest, vb: *b, vc: *c, }), /* needs branch_offset - Self::IfEq { a, b } => Ok(InsFormat::Format22T { + (Self::IfEq { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x32, va: *a, vb: *b, c: *branch_offset, }), - Self::IfNe { a, b } => Ok(InsFormat::Format22T { + (Self::IfNe { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x33, va: *a, vb: *b, c: *branch_offset, }), - Self::IfLt { a, b } => Ok(InsFormat::Format22T { + (Self::IfLt { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x34, va: *a, vb: *b, c: *branch_offset, }), - Self::IfGe { a, b } => Ok(InsFormat::Format22T { + (Self::IfGe { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x35, va: *a, vb: *b, c: *branch_offset, }), - Self::IfGt { a, b } => Ok(InsFormat::Format22T { + (Self::IfGt { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x36, va: *a, vb: *b, c: *branch_offset, }), - Self::IfLe { a, b } => Ok(InsFormat::Format22T { + (Self::IfLe { a, b }, _strings, _types) => Ok(InsFormat::Format22T { op: 0x37, va: *a, vb: *b, c: *branch_offset, }), - Self::IfEqZ { a } => Ok(InsFormat::Format21T { + (Self::IfEqZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x38, va: *a, b: *branch_offset, }), - Self::IfNeZ { a } => Ok(InsFormat::Format21T { + (Self::IfNeZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x39, va: *a, b: *branch_offset, }), - Self::IfLtZ { a } => Ok(InsFormat::Format21T { + (Self::IfLtZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x3a, va: *a, b: *branch_offset, }), - Self::IfGeZ { a } => Ok(InsFormat::Format21T { + (Self::IfGeZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x3b, va: *a, b: *branch_offset, }), - Self::IfGtZ { a } => Ok(InsFormat::Format21T { + (Self::IfGtZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x3c, va: *a, b: *branch_offset, }), - Self::IfLeZ { a } => Ok(InsFormat::Format21T { + (Self::IfLeZ { a }, _strings, _types) => Ok(InsFormat::Format21T { op: 0x3d, va: *a, b: *branch_offset, }), */ - Self::AGet { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGet { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x44, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetWide { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetWide { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x45, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetObject { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetObject { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x46, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetBoolean { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetBoolean { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x47, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetByte { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetByte { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x48, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetChar { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetChar { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x49, va: *dest, vb: *arr, vc: *idx, }), - Self::AGetShort { dest, arr, idx } => Ok(InsFormat::Format23X { + (Self::AGetShort { dest, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4a, va: *dest, vb: *arr, vc: *idx, }), - Self::APut { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APut { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4b, va: *from, vb: *arr, vc: *idx, }), - Self::APutWide { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutWide { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4c, va: *from, vb: *arr, vc: *idx, }), - Self::APutObject { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutObject { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4d, va: *from, vb: *arr, vc: *idx, }), - Self::APutBoolean { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutBoolean { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4e, va: *from, vb: *arr, vc: *idx, }), - Self::APutByte { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutByte { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x4f, va: *from, vb: *arr, vc: *idx, }), - Self::APutChar { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutChar { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x50, va: *from, vb: *arr, vc: *idx, }), - Self::APutShort { from, arr, idx } => Ok(InsFormat::Format23X { + (Self::APutShort { from, arr, idx }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x51, va: *from, vb: *arr, vc: *idx, }), /* needs field_idx - Self::IGet { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGet { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x52, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetWide { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetWide { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x53, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetObject { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetObject { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x54, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetBoolean { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetBoolean { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x55, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetByte { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetByte { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x56, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetChar { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetChar { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x57, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IGetShort { to, obj, field } => Ok(InsFormat::Format22C { + (Self::IGetShort { to, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x58, va: *to, vb: *obj, c: field_idx as u16, }), - Self::IPut { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPut { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x59, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutWide { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutWide { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5a, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutObject { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutObject { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5b, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutBoolean { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutBoolean { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5c, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutByte { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutByte { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5d, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutChar { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutChar { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5e, va: *from, vb: *obj, c: field_idx as u16, }), - Self::IPutShort { from, obj, field } => Ok(InsFormat::Format22C { + (Self::IPutShort { from, obj, field }, _strings, _types) => Ok(InsFormat::Format22C { op: 0x5f, va: *from, vb: *obj, c: field_idx as u16, }), - Self::SGet { to, field } => Ok(InsFormat::Format21C { + (Self::SGet { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x60, va: *to, b: field_idx as u16, }), - Self::SGetWide { to, field } => Ok(InsFormat::Format21C { + (Self::SGetWide { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x61, va: *to, b: field_idx as u16, }), - Self::SGetObject { to, field } => Ok(InsFormat::Format21C { + (Self::SGetObject { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x62, va: *to, b: field_idx as u16, }), - Self::SGetBoolean { to, field } => Ok(InsFormat::Format21C { + (Self::SGetBoolean { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x63, va: *to, b: field_idx as u16, }), - Self::SGetByte { to, field } => Ok(InsFormat::Format21C { + (Self::SGetByte { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x64, va: *to, b: field_idx as u16, }), - Self::SGetChar { to, field } => Ok(InsFormat::Format21C { + (Self::SGetChar { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x65, va: *to, b: field_idx as u16, }), - Self::SGetShort { to, field } => Ok(InsFormat::Format21C { + (Self::SGetShort { to, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x66, va: *to, b: field_idx as u16, }), - Self::SPut { from, field } => Ok(InsFormat::Format21C { + (Self::SPut { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x67, va: *from, b: field_idx as u16, }), - Self::SPutWide { from, field } => Ok(InsFormat::Format21C { + (Self::SPutWide { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x68, va: *from, b: field_idx as u16, }), - Self::SPutObject { from, field } => Ok(InsFormat::Format21C { + (Self::SPutObject { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x69, va: *from, b: field_idx as u16, }), - Self::SPutBoolean { from, field } => Ok(InsFormat::Format21C { + (Self::SPutBoolean { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x6a, va: *from, b: field_idx as u16, }), - Self::SPutByte { from, field } => Ok(InsFormat::Format21C { + (Self::SPutByte { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x6b, va: *from, b: field_idx as u16, }), - Self::SPutChar { from, field } => Ok(InsFormat::Format21C { + (Self::SPutChar { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x6c, va: *from, b: field_idx as u16, }), - Self::SPutShort { from, field } => Ok(InsFormat::Format21C { + (Self::SPutShort { from, field }, _strings, _types) => Ok(InsFormat::Format21C { op: 0x6d, va: *from, b: field_idx as u16, }), */ /* needs meth_idx - Self::InvokeVirtual { args, method } => { + (Self::InvokeVirtual { args, method }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -4818,7 +4866,7 @@ impl Instruction { panic!("Invalid Invoke instruction {self:?}") } } - Self::InvokeSuper { args, method } => { + (Self::InvokeSuper { args, method }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -4878,7 +4926,7 @@ impl Instruction { panic!("Invalid Invoke instruction {self:?}") } } - Self::InvokeDirect { args, method } => { + (Self::InvokeDirect { args, method }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -4938,7 +4986,7 @@ impl Instruction { panic!("Invalid Invoke instruction {self:?}") } } - Self::InvokeStatic { args, method } => { + (Self::InvokeStatic { args, method }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -4998,7 +5046,7 @@ impl Instruction { panic!("Invalid Invoke instruction {self:?}") } } - Self::InvokeInterface { args, method } => { + (Self::InvokeInterface { args, method }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -5059,464 +5107,464 @@ impl Instruction { } } */ - Self::NegInt { dest, val } => Ok(InsFormat::Format12X { + (Self::NegInt { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x7b, va: *dest, vb: *val, }), - Self::NotInt { dest, val } => Ok(InsFormat::Format12X { + (Self::NotInt { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x7c, va: *dest, vb: *val, }), - Self::NegLong { dest, val } => Ok(InsFormat::Format12X { + (Self::NegLong { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x7d, va: *dest, vb: *val, }), - Self::NotLong { dest, val } => Ok(InsFormat::Format12X { + (Self::NotLong { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x7e, va: *dest, vb: *val, }), - Self::NegFloat { dest, val } => Ok(InsFormat::Format12X { + (Self::NegFloat { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x7f, va: *dest, vb: *val, }), - Self::NegDouble { dest, val } => Ok(InsFormat::Format12X { + (Self::NegDouble { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x80, va: *dest, vb: *val, }), - Self::IntToLong { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToLong { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x81, va: *dest, vb: *val, }), - Self::IntToFloat { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToFloat { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x82, va: *dest, vb: *val, }), - Self::IntToDouble { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToDouble { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x83, va: *dest, vb: *val, }), - Self::LongToInt { dest, val } => Ok(InsFormat::Format12X { + (Self::LongToInt { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x84, va: *dest, vb: *val, }), - Self::LongToFloat { dest, val } => Ok(InsFormat::Format12X { + (Self::LongToFloat { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x85, va: *dest, vb: *val, }), - Self::LongToDouble { dest, val } => Ok(InsFormat::Format12X { + (Self::LongToDouble { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x86, va: *dest, vb: *val, }), - Self::FloatToInt { dest, val } => Ok(InsFormat::Format12X { + (Self::FloatToInt { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x87, va: *dest, vb: *val, }), - Self::FloatToLong { dest, val } => Ok(InsFormat::Format12X { + (Self::FloatToLong { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x88, va: *dest, vb: *val, }), - Self::FloatToDouble { dest, val } => Ok(InsFormat::Format12X { + (Self::FloatToDouble { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x89, va: *dest, vb: *val, }), - Self::DoubleToInt { dest, val } => Ok(InsFormat::Format12X { + (Self::DoubleToInt { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8a, va: *dest, vb: *val, }), - Self::DoubleToLong { dest, val } => Ok(InsFormat::Format12X { + (Self::DoubleToLong { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8b, va: *dest, vb: *val, }), - Self::DoubleToFloat { dest, val } => Ok(InsFormat::Format12X { + (Self::DoubleToFloat { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8c, va: *dest, vb: *val, }), - Self::IntToByte { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToByte { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8d, va: *dest, vb: *val, }), - Self::IntToChar { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToChar { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8e, va: *dest, vb: *val, }), - Self::IntToShort { dest, val } => Ok(InsFormat::Format12X { + (Self::IntToShort { dest, val }, _strings, _types) => Ok(InsFormat::Format12X { op: 0x8f, va: *dest, vb: *val, }), - Self::AddInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AddInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x90, va: *dest, vb: *b, vc: *c, }), - Self::SubInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::SubInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x91, va: *dest, vb: *b, vc: *c, }), - Self::MulInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::MulInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x92, va: *dest, vb: *b, vc: *c, }), - Self::DivInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::DivInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x93, va: *dest, vb: *b, vc: *c, }), - Self::RemInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::RemInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x94, va: *dest, vb: *b, vc: *c, }), - Self::AndInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AndInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x95, va: *dest, vb: *b, vc: *c, }), - Self::OrInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::OrInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x96, va: *dest, vb: *b, vc: *c, }), - Self::XorInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::XorInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x97, va: *dest, vb: *b, vc: *c, }), - Self::ShlInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::ShlInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x98, va: *dest, vb: *b, vc: *c, }), - Self::ShrInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::ShrInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x99, va: *dest, vb: *b, vc: *c, }), - Self::UshrInt { dest, b, c } => Ok(InsFormat::Format23X { + (Self::UshrInt { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9a, va: *dest, vb: *b, vc: *c, }), - Self::AddLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AddLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9b, va: *dest, vb: *b, vc: *c, }), - Self::SubLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::SubLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9c, va: *dest, vb: *b, vc: *c, }), - Self::MulLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::MulLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9d, va: *dest, vb: *b, vc: *c, }), - Self::DivLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::DivLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9e, va: *dest, vb: *b, vc: *c, }), - Self::RemLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::RemLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0x9f, va: *dest, vb: *b, vc: *c, }), - Self::AndLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AndLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa0, va: *dest, vb: *b, vc: *c, }), - Self::OrLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::OrLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa1, va: *dest, vb: *b, vc: *c, }), - Self::XorLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::XorLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa2, va: *dest, vb: *b, vc: *c, }), - Self::ShlLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::ShlLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa3, va: *dest, vb: *b, vc: *c, }), - Self::ShrLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::ShrLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa4, va: *dest, vb: *b, vc: *c, }), - Self::UshrLong { dest, b, c } => Ok(InsFormat::Format23X { + (Self::UshrLong { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa5, va: *dest, vb: *b, vc: *c, }), - Self::AddFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AddFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa6, va: *dest, vb: *b, vc: *c, }), - Self::SubFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::SubFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa7, va: *dest, vb: *b, vc: *c, }), - Self::MulFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::MulFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa8, va: *dest, vb: *b, vc: *c, }), - Self::DivFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::DivFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xa9, va: *dest, vb: *b, vc: *c, }), - Self::RemFloat { dest, b, c } => Ok(InsFormat::Format23X { + (Self::RemFloat { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xaa, va: *dest, vb: *b, vc: *c, }), - Self::AddDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::AddDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xab, va: *dest, vb: *b, vc: *c, }), - Self::SubDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::SubDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xac, va: *dest, vb: *b, vc: *c, }), - Self::MulDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::MulDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xad, va: *dest, vb: *b, vc: *c, }), - Self::DivDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::DivDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xae, va: *dest, vb: *b, vc: *c, }), - Self::RemDouble { dest, b, c } => Ok(InsFormat::Format23X { + (Self::RemDouble { dest, b, c }, _strings, _types) => Ok(InsFormat::Format23X { op: 0xaf, va: *dest, vb: *b, vc: *c, }), - Self::AddInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AddInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb0, va: *dest, vb: *b, }), - Self::SubInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::SubInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb1, va: *dest, vb: *b, }), - Self::MulInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::MulInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb2, va: *dest, vb: *b, }), - Self::DivInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::DivInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb3, va: *dest, vb: *b, }), - Self::RemInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::RemInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb4, va: *dest, vb: *b, }), - Self::AndInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AndInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb5, va: *dest, vb: *b, }), - Self::OrInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::OrInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb6, va: *dest, vb: *b, }), - Self::XorInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::XorInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb7, va: *dest, vb: *b, }), - Self::ShlInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::ShlInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb8, va: *dest, vb: *b, }), - Self::ShrInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::ShrInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xb9, va: *dest, vb: *b, }), - Self::UshrInt2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::UshrInt2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xba, va: *dest, vb: *b, }), - Self::AddLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AddLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xbb, va: *dest, vb: *b, }), - Self::SubLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::SubLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xbc, va: *dest, vb: *b, }), - Self::MulLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::MulLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xbd, va: *dest, vb: *b, }), - Self::DivLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::DivLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xbe, va: *dest, vb: *b, }), - Self::RemLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::RemLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xbf, va: *dest, vb: *b, }), - Self::AndLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AndLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc0, va: *dest, vb: *b, }), - Self::OrLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::OrLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc1, va: *dest, vb: *b, }), - Self::XorLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::XorLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc2, va: *dest, vb: *b, }), - Self::ShlLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::ShlLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc3, va: *dest, vb: *b, }), - Self::ShrLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::ShrLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc4, va: *dest, vb: *b, }), - Self::UshrLong2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::UshrLong2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc5, va: *dest, vb: *b, }), - Self::AddFloat2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AddFloat2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc6, va: *dest, vb: *b, }), - Self::SubFloat2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::SubFloat2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc7, va: *dest, vb: *b, }), - Self::MulFloat2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::MulFloat2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc8, va: *dest, vb: *b, }), - Self::DivFloat2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::DivFloat2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xc9, va: *dest, vb: *b, }), - Self::RemFloat2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::RemFloat2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xca, va: *dest, vb: *b, }), - Self::AddDouble2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::AddDouble2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xcb, va: *dest, vb: *b, }), - Self::SubDouble2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::SubDouble2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xcc, va: *dest, vb: *b, }), - Self::MulDouble2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::MulDouble2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xcd, va: *dest, vb: *b, }), - Self::DivDouble2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::DivDouble2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xce, va: *dest, vb: *b, }), - Self::RemDouble2Addr { b, dest } => Ok(InsFormat::Format12X { + (Self::RemDouble2Addr { b, dest }, _strings, _types) => Ok(InsFormat::Format12X { op: 0xcf, va: *dest, vb: *b, }), - Self::AddIntLit { lit, b, dest } => { + (Self::AddIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5553,7 +5601,7 @@ impl Instruction { }) } } - Self::RsubIntLit { lit, b, dest } => { + (Self::RsubIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5590,7 +5638,7 @@ impl Instruction { }) } } - Self::MulIntLit { lit, b, dest } => { + (Self::MulIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5627,7 +5675,7 @@ impl Instruction { }) } } - Self::DivIntLit { lit, b, dest } => { + (Self::DivIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5664,7 +5712,7 @@ impl Instruction { }) } } - Self::RemIntLit { lit, b, dest } => { + (Self::RemIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5701,7 +5749,7 @@ impl Instruction { }) } } - Self::AndIntLit { lit, b, dest } => { + (Self::AndIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5738,7 +5786,7 @@ impl Instruction { }) } } - Self::OrIntLit { lit, b, dest } => { + (Self::OrIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5775,7 +5823,7 @@ impl Instruction { }) } } - Self::XorIntLit { lit, b, dest } => { + (Self::XorIntLit { lit, b, dest }, _strings, _types) => { let mut reg_on_4_bit = true; let mut lit_on_8_bits = true; if dest & 0b1111_0000 != 0 { @@ -5812,26 +5860,26 @@ impl Instruction { }) } } - Self::ShlIntLit { dest, b, lit } => Ok(InsFormat::Format22B { + (Self::ShlIntLit { dest, b, lit }, _strings, _types) => Ok(InsFormat::Format22B { op: 0xe0, va: *dest, vb: *b, c: *lit, }), - Self::ShrIntLit { dest, b, lit } => Ok(InsFormat::Format22B { + (Self::ShrIntLit { dest, b, lit }, _strings, _types) => Ok(InsFormat::Format22B { op: 0xe1, va: *dest, vb: *b, c: *lit, }), - Self::UshrIntLit { dest, b, lit } => Ok(InsFormat::Format22B { + (Self::UshrIntLit { dest, b, lit }, _strings, _types) => Ok(InsFormat::Format22B { op: 0xe2, va: *dest, vb: *b, c: *lit, }), /* needs method_idx and proto_idx - Self::InvokePolymorphic { args, method, proto } => { + (Self::InvokePolymorphic { args, method, proto }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -5895,7 +5943,7 @@ impl Instruction { } */ /* needs call_site_idx - Self::InvokeCustom { args, call_site } => { + (Self::InvokeCustom { args, call_site }, _strings, _types) => { let mut last = None; let mut first = None; let mut consec = true; @@ -5957,14 +6005,14 @@ impl Instruction { } */ /* needs method_handle_idx - Self::ConstMethodHandle {to, handle} => Ok(InsFormat::Format21C { + (Self::ConstMethodHandle {to, handle}, _strings, _types) => Ok(InsFormat::Format21C { op: 0xfe, va: *to, b: method_handle_idx as u16, }), */ /* needs proto_idx - Self::ConstMethodType {to, proto} => Ok(InsFormat::Format21C { + (Self::ConstMethodType {to, proto}, _strings, _types) => Ok(InsFormat::Format21C { op: 0xff, va: *to, b: proto_idx as u16, @@ -5993,8 +6041,10 @@ impl Instruction { _ => todo!(), // TODO: leave as is? } } - /// TODO: remove? rename goto_size_.. ?tmp solution for now - pub fn size_from_branch_offset_interval( + + /// Return the size of a goto instruction from its address and an interval for + /// the destination address in worst case senario. + pub fn goto_size_from_branch_offset_interval( addr_goto: usize, min_addr_branch: usize, max_addr_branch: usize,