From 28585bcd0983d9060120ba65319c7af971fb4dd9 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 10 Oct 2024 15:36:06 +0900 Subject: [PATCH] Upgrade to nom 7 --- Cargo.toml | 2 +- src/attribute_info/parser.rs | 334 ++++++++++++----------- src/code_attribute/parser.rs | 515 ++++++++++++++++++----------------- src/constant_info/parser.rs | 194 ++++++------- src/field_info/parser.rs | 30 +- src/method_info/parser.rs | 30 +- src/parser.rs | 76 +++--- 7 files changed, 593 insertions(+), 588 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 81c9c7c..570aadf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,6 @@ license = "MIT" exclude = [".idea/**/*", "classfile-parser.iml", "java-assets/out/**/*"] [dependencies] -nom = "6" +nom = "7" bitflags = "^2.3" cesu8 = "^1.1" diff --git a/src/attribute_info/parser.rs b/src/attribute_info/parser.rs index b2c645b..661e01d 100644 --- a/src/attribute_info/parser.rs +++ b/src/attribute_info/parser.rs @@ -1,5 +1,8 @@ use nom::{ + bytes::complete::take, + combinator::{map, success}, error::{Error, ErrorKind}, + multi::count, number::complete::{be_u16, be_u32, be_u8}, Err as BaseErr, }; @@ -11,87 +14,88 @@ use attribute_info::*; type Err = BaseErr>; pub fn attribute_parser(input: &[u8]) -> Result<(&[u8], AttributeInfo), Err<&[u8]>> { - do_parse!( + let (input, attribute_name_index) = be_u16(input)?; + let (input, attribute_length) = be_u32(input)?; + let (input, info) = take(attribute_length)(input)?; + Ok(( input, - attribute_name_index: be_u16 - >> attribute_length: be_u32 - >> info: take!(attribute_length) - >> (AttributeInfo { - attribute_name_index, - attribute_length, - info: info.to_owned(), - }) - ) + AttributeInfo { + attribute_name_index, + attribute_length, + info: info.to_owned(), + }, + )) } pub fn exception_entry_parser(input: &[u8]) -> Result<(&[u8], ExceptionEntry), Err<&[u8]>> { - do_parse!( + let (input, start_pc) = be_u16(input)?; + let (input, end_pc) = be_u16(input)?; + let (input, handler_pc) = be_u16(input)?; + let (input, catch_type) = be_u16(input)?; + Ok(( input, - start_pc: be_u16 - >> end_pc: be_u16 - >> handler_pc: be_u16 - >> catch_type: be_u16 - >> (ExceptionEntry { - start_pc, - end_pc, - handler_pc, - catch_type, - }) - ) + ExceptionEntry { + start_pc, + end_pc, + handler_pc, + catch_type, + }, + )) } pub fn code_attribute_parser(input: &[u8]) -> Result<(&[u8], CodeAttribute), Err<&[u8]>> { - do_parse!( + let (input, max_stack) = be_u16(input)?; + let (input, max_locals) = be_u16(input)?; + let (input, code_length) = be_u32(input)?; + let (input, code) = take(code_length)(input)?; + let (input, exception_table_length) = be_u16(input)?; + let (input, exception_table) = + count(exception_entry_parser, exception_table_length as usize)(input)?; + let (input, attributes_count) = be_u16(input)?; + let (input, attributes) = count(attribute_parser, attributes_count as usize)(input)?; + Ok(( input, - max_stack: be_u16 - >> max_locals: be_u16 - >> code_length: be_u32 - >> code: take!(code_length) - >> exception_table_length: be_u16 - >> exception_table: count!(exception_entry_parser, exception_table_length as usize) - >> attributes_count: be_u16 - >> attributes: count!(attribute_parser, attributes_count as usize) - >> (CodeAttribute { - max_stack, - max_locals, - code_length, - code: code.to_owned(), - exception_table_length, - exception_table, - attributes_count, - attributes, - }) - ) + CodeAttribute { + max_stack, + max_locals, + code_length, + code: code.to_owned(), + exception_table_length, + exception_table, + attributes_count, + attributes, + }, + )) } pub fn method_parameters_attribute_parser( input: &[u8], ) -> Result<(&[u8], MethodParametersAttribute), Err<&[u8]>> { - do_parse!( + let (input, parameters_count) = be_u8(input)?; + let (input, parameters) = count(parameters_parser, parameters_count as usize)(input)?; + Ok(( input, - parameters_count: be_u8 - >> parameters: count!(parameters_parser, parameters_count as usize) - >> (MethodParametersAttribute { - parameters_count, - parameters, - }) - ) + MethodParametersAttribute { + parameters_count, + parameters, + }, + )) } pub fn parameters_parser(input: &[u8]) -> Result<(&[u8], ParameterAttribute), Err<&[u8]>> { - do_parse!( + let (input, name_index) = be_u16(input)?; + let (input, access_flags) = be_u16(input)?; + Ok(( input, - name_index: be_u16 - >> access_flags: be_u16 - >> (ParameterAttribute { - name_index, - access_flags - }) - ) + ParameterAttribute { + name_index, + access_flags, + }, + )) } fn same_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - value!(input, SameFrame { frame_type }) + success(SameFrame { frame_type })(input) } fn verification_type_parser(input: &[u8]) -> Result<(&[u8], VerificationTypeInfo), Err<&[u8]>> { @@ -106,8 +110,8 @@ fn verification_type_parser(input: &[u8]) -> Result<(&[u8], VerificationTypeInfo 4 => Ok((new_input, Long)), 5 => Ok((new_input, Null)), 6 => Ok((new_input, UninitializedThis)), - 7 => do_parse!(new_input, class: be_u16 >> (Object { class })), - 8 => do_parse!(new_input, offset: be_u16 >> (Uninitialized { offset })), + 7 => map(be_u16, |class| Object { class })(new_input), + 8 => map(be_u16, |offset| Uninitialized { offset })(new_input), _ => Result::Err(Err::Error(error_position!(input, ErrorKind::NoneOf))), } } @@ -116,83 +120,81 @@ fn same_locals_1_stack_item_frame_parser( input: &[u8], frame_type: u8, ) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( - input, - stack: verification_type_parser >> (SameLocals1StackItemFrame { frame_type, stack }) - ) + let (input, stack) = verification_type_parser(input)?; + Ok((input, SameLocals1StackItemFrame { frame_type, stack })) } fn same_locals_1_stack_item_frame_extended_parser( input: &[u8], frame_type: u8, ) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( + let (input, offset_delta) = be_u16(input)?; + let (input, stack) = verification_type_parser(input)?; + Ok(( input, - offset_delta: be_u16 - >> stack: verification_type_parser - >> (SameLocals1StackItemFrameExtended { - frame_type, - offset_delta, - stack - }) - ) + SameLocals1StackItemFrameExtended { + frame_type, + offset_delta, + stack, + }, + )) } fn chop_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( + let (input, offset_delta) = be_u16(input)?; + Ok(( input, - offset_delta: be_u16 - >> (ChopFrame { - frame_type, - offset_delta - }) - ) + ChopFrame { + frame_type, + offset_delta, + }, + )) } fn same_frame_extended_parser( input: &[u8], frame_type: u8, ) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( + let (input, offset_delta) = be_u16(input)?; + Ok(( input, - offset_delta: be_u16 - >> (SameFrameExtended { - frame_type, - offset_delta - }) - ) + SameFrameExtended { + frame_type, + offset_delta, + }, + )) } fn append_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( + let (input, offset_delta) = be_u16(input)?; + let (input, locals) = count(verification_type_parser, (frame_type - 251) as usize)(input)?; + Ok(( input, - offset_delta: be_u16 - >> locals: count!(verification_type_parser, (frame_type - 251) as usize) - >> (AppendFrame { - frame_type, - offset_delta, - locals - }) - ) + AppendFrame { + frame_type, + offset_delta, + locals, + }, + )) } fn full_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( + let (input, offset_delta) = be_u16(input)?; + let (input, number_of_locals) = be_u16(input)?; + let (input, locals) = count(verification_type_parser, number_of_locals as usize)(input)?; + let (input, number_of_stack_items) = be_u16(input)?; + let (input, stack) = count(verification_type_parser, number_of_stack_items as usize)(input)?; + Ok(( input, - offset_delta: be_u16 - >> number_of_locals: be_u16 - >> locals: count!(verification_type_parser, number_of_locals as usize) - >> number_of_stack_items: be_u16 - >> stack: count!(verification_type_parser, number_of_stack_items as usize) - >> (FullFrame { - frame_type, - offset_delta, - number_of_locals, - locals, - number_of_stack_items, - stack, - }) - ) + FullFrame { + frame_type, + offset_delta, + number_of_locals, + locals, + number_of_stack_items, + stack, + }, + )) } fn stack_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { @@ -209,92 +211,92 @@ fn stack_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFr } fn stack_map_frame_entry_parser(input: &[u8]) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> { - do_parse!( - input, - frame_type: be_u8 >> stack_frame: call!(stack_frame_parser, frame_type) >> (stack_frame) - ) + let (input, frame_type) = be_u8(input)?; + let (input, stack_frame) = stack_frame_parser(input, frame_type)?; + Ok((input, stack_frame)) } pub fn stack_map_table_attribute_parser( input: &[u8], ) -> Result<(&[u8], StackMapTableAttribute), Err<&[u8]>> { - do_parse!( + let (input, number_of_entries) = be_u16(input)?; + let (input, entries) = count(stack_map_frame_entry_parser, number_of_entries as usize)(input)?; + Ok(( input, - number_of_entries: be_u16 - >> entries: count!(stack_map_frame_entry_parser, number_of_entries as usize) - >> (StackMapTableAttribute { - number_of_entries, - entries, - }) - ) + StackMapTableAttribute { + number_of_entries, + entries, + }, + )) } pub fn exceptions_attribute_parser( input: &[u8], ) -> Result<(&[u8], ExceptionsAttribute), Err<&[u8]>> { - do_parse!( + let (input, exception_table_length) = be_u16(input)?; + let (input, exception_table) = count(be_u16, exception_table_length as usize)(input)?; + Ok(( input, - exception_table_length: be_u16 - >> exception_table: count!(be_u16, exception_table_length as usize) - >> (ExceptionsAttribute { - exception_table_length, - exception_table, - }) - ) + ExceptionsAttribute { + exception_table_length, + exception_table, + }, + )) } pub fn constant_value_attribute_parser( input: &[u8], ) -> Result<(&[u8], ConstantValueAttribute), Err<&[u8]>> { - do_parse!( + let (input, constant_value_index) = be_u16(input)?; + Ok(( input, - constant_value_index: be_u16 - >> (ConstantValueAttribute { - constant_value_index, - }) - ) + ConstantValueAttribute { + constant_value_index, + }, + )) } fn bootstrap_method_parser(input: &[u8]) -> Result<(&[u8], BootstrapMethod), Err<&[u8]>> { - do_parse!( + let (input, bootstrap_method_ref) = be_u16(input)?; + let (input, num_bootstrap_arguments) = be_u16(input)?; + let (input, bootstrap_arguments) = count(be_u16, num_bootstrap_arguments as usize)(input)?; + Ok(( input, - bootstrap_method_ref: be_u16 - >> num_bootstrap_arguments: be_u16 - >> bootstrap_arguments: count!(be_u16, num_bootstrap_arguments as usize) - >> (BootstrapMethod { - bootstrap_method_ref, - num_bootstrap_arguments, - bootstrap_arguments, - }) - ) + BootstrapMethod { + bootstrap_method_ref, + num_bootstrap_arguments, + bootstrap_arguments, + }, + )) } pub fn bootstrap_methods_attribute_parser( input: &[u8], ) -> Result<(&[u8], BootstrapMethodsAttribute), Err<&[u8]>> { - do_parse!( + let (input, num_bootstrap_methods) = be_u16(input)?; + let (input, bootstrap_methods) = + count(bootstrap_method_parser, num_bootstrap_methods as usize)(input)?; + Ok(( input, - num_bootstrap_methods: be_u16 - >> bootstrap_methods: count!(bootstrap_method_parser, num_bootstrap_methods as usize) - >> (BootstrapMethodsAttribute { - num_bootstrap_methods, - bootstrap_methods, - }) - ) + BootstrapMethodsAttribute { + num_bootstrap_methods, + bootstrap_methods, + }, + )) } pub fn sourcefile_attribute_parser( input: &[u8], ) -> Result<(&[u8], SourceFileAttribute), Err<&[u8]>> { - do_parse!( + let (input, attribute_name_index) = be_u16(input)?; + let (input, attribute_length) = be_u32(input)?; + let (input, sourcefile_index) = be_u16(input)?; + Ok(( input, - attribute_name_index: be_u16 - >> attribute_length: be_u32 - >> sourcefile_index: be_u16 - >> (SourceFileAttribute { - attribute_name_index, - attribute_length, - sourcefile_index - }) - ) + SourceFileAttribute { + attribute_name_index, + attribute_length, + sourcefile_index, + }, + )) } diff --git a/src/code_attribute/parser.rs b/src/code_attribute/parser.rs index a5de018..af15d24 100644 --- a/src/code_attribute/parser.rs +++ b/src/code_attribute/parser.rs @@ -1,6 +1,10 @@ use code_attribute::types::Instruction; use nom::{ + bytes::complete::{tag, take}, + combinator::{complete, fail, map, success}, + multi::{count, many0}, number::complete::{be_i16, be_i32, be_i8, be_u16, be_u32, be_u8}, + sequence::{pair, preceded, tuple}, IResult, Offset, }; @@ -8,268 +12,281 @@ fn offset<'a>(remaining: &'a [u8], input: &[u8]) -> IResult<&'a [u8], usize> { Ok((remaining, input.offset(remaining))) } -fn align(input: &[u8], address: usize) -> IResult<&[u8], &[u8]> { - take!(input, (4 - address % 4) % 4) +fn align(address: usize) -> impl Fn(&[u8]) -> IResult<&[u8], &[u8]> { + move |input: &[u8]| take((4 - address % 4) % 4)(input) } fn lookupswitch_parser(input: &[u8]) -> IResult<&[u8], Instruction> { // This function provides type annotations required by rustc. fn each_pair(input: &[u8]) -> IResult<&[u8], (i32, i32)> { - do_parse!(input, lookup: be_i32 >> offset: be_i32 >> (lookup, offset)) + let (input, lookup) = be_i32(input)?; + let (input, offset) = be_i32(input)?; + Ok((input, (lookup, offset))) } - - do_parse!( - input, - default: be_i32 - >> npairs: be_u32 - >> pairs: count!(call!(each_pair), npairs as usize) - >> (Instruction::Lookupswitch { default, pairs }) - ) + let (input, default) = be_i32(input)?; + let (input, npairs) = be_u32(input)?; + let (input, pairs) = count(each_pair, npairs as usize)(input)?; + Ok((input, Instruction::Lookupswitch { default, pairs })) } fn tableswitch_parser(input: &[u8]) -> IResult<&[u8], Instruction> { - do_parse!( + let (input, default) = be_i32(input)?; + let (input, low) = be_i32(input)?; + let (input, high) = be_i32(input)?; + let (input, offsets) = count(be_i32, (high - low + 1) as usize)(input)?; + Ok(( input, - default: be_i32 - >> low: be_i32 - >> high: be_i32 - >> offsets: count!(be_i32, (high - low + 1) as usize) - >> (Instruction::Tableswitch { - default, - low, - high, - offsets, - }) - ) + Instruction::Tableswitch { + default, + low, + high, + offsets, + }, + )) } -pub fn code_parser(input: &[u8]) -> IResult<&[u8], Vec<(usize, Instruction)>> { - many0!( - input, - complete!(do_parse!( - address: call!(offset, input) - >> instruction: call!(instruction_parser, address) - >> (address, instruction) - )) - ) +pub fn code_parser(outer_input: &[u8]) -> IResult<&[u8], Vec<(usize, Instruction)>> { + many0(complete(|input| { + let (input, address) = offset(input, outer_input)?; + let (input, instruction) = instruction_parser(input, address)?; + Ok((input, (address, instruction))) + }))(outer_input) } pub fn instruction_parser(input: &[u8], address: usize) -> IResult<&[u8], Instruction> { - switch!(input, be_u8, - 0x32 => value!(Instruction::Aaload) | - 0x53 => value!(Instruction::Aastore) | - 0x01 => value!(Instruction::Aconstnull) | - 0x19 => map!(be_u8, Instruction::Aload) | - 0x2a => value!(Instruction::Aload0) | - 0x2b => value!(Instruction::Aload1) | - 0x2c => value!(Instruction::Aload2) | - 0x2d => value!(Instruction::Aload3) | - 0xbd => map!(be_u16, Instruction::Anewarray) | - 0xb0 => value!(Instruction::Areturn) | - 0xbe => value!(Instruction::Arraylength) | - 0x3a => map!(be_u8, Instruction::Astore) | - 0x4b => value!(Instruction::Astore0) | - 0x4c => value!(Instruction::Astore1) | - 0x4d => value!(Instruction::Astore2) | - 0x4e => value!(Instruction::Astore3) | - 0xbf => value!(Instruction::Athrow) | - 0x33 => value!(Instruction::Baload) | - 0x54 => value!(Instruction::Bastore) | - 0x10 => map!(be_i8, Instruction::Bipush) | - 0x34 => value!(Instruction::Caload) | - 0x55 => value!(Instruction::Castore) | - 0xc0 => map!(be_u16, Instruction::Checkcast) | - 0x90 => value!(Instruction::D2f) | - 0x8e => value!(Instruction::D2i) | - 0x8f => value!(Instruction::D2l) | - 0x63 => value!(Instruction::Dadd) | - 0x31 => value!(Instruction::Daload) | - 0x52 => value!(Instruction::Dastore) | - 0x98 => value!(Instruction::Dcmpg) | - 0x97 => value!(Instruction::Dcmpl) | - 0x0e => value!(Instruction::Dconst0) | - 0x0f => value!(Instruction::Dconst1) | - 0x6f => value!(Instruction::Ddiv) | - 0x18 => map!(be_u8, Instruction::Dload) | - 0x26 => value!(Instruction::Dload0) | - 0x27 => value!(Instruction::Dload1) | - 0x28 => value!(Instruction::Dload2) | - 0x29 => value!(Instruction::Dload3) | - 0x6b => value!(Instruction::Dmul) | - 0x77 => value!(Instruction::Dneg) | - 0x73 => value!(Instruction::Drem) | - 0xaf => value!(Instruction::Dreturn) | - 0x39 => map!(be_u8, Instruction::Dstore) | - 0x47 => value!(Instruction::Dstore0) | - 0x48 => value!(Instruction::Dstore1) | - 0x49 => value!(Instruction::Dstore2) | - 0x4a => value!(Instruction::Dstore3) | - 0x67 => value!(Instruction::Dsub) | - 0x59 => value!(Instruction::Dup) | - 0x5a => value!(Instruction::Dupx1) | - 0x5b => value!(Instruction::Dupx2) | - 0x5c => value!(Instruction::Dup2) | - 0x5d => value!(Instruction::Dup2x1) | - 0x5e => value!(Instruction::Dup2x2) | - 0x8d => value!(Instruction::F2d) | - 0x8b => value!(Instruction::F2i) | - 0x8c => value!(Instruction::F2l) | - 0x62 => value!(Instruction::Fadd) | - 0x30 => value!(Instruction::Faload) | - 0x51 => value!(Instruction::Fastore) | - 0x96 => value!(Instruction::Fcmpg) | - 0x95 => value!(Instruction::Fcmpl) | - 0x0b => value!(Instruction::Fconst0) | - 0x0c => value!(Instruction::Fconst1) | - 0x0d => value!(Instruction::Fconst2) | - 0x6e => value!(Instruction::Fdiv) | - 0x17 => map!(be_u8, Instruction::Fload) | - 0x22 => value!(Instruction::Fload0) | - 0x23 => value!(Instruction::Fload1) | - 0x24 => value!(Instruction::Fload2) | - 0x25 => value!(Instruction::Fload3) | - 0x6a => value!(Instruction::Fmul) | - 0x76 => value!(Instruction::Fneg) | - 0x72 => value!(Instruction::Frem) | - 0xae => value!(Instruction::Freturn) | - 0x38 => map!(be_u8, Instruction::Fstore) | - 0x43 => value!(Instruction::Fstore0) | - 0x44 => value!(Instruction::Fstore1) | - 0x45 => value!(Instruction::Fstore2) | - 0x46 => value!(Instruction::Fstore3) | - 0x66 => value!(Instruction::Fsub) | - 0xb4 => map!(be_u16, Instruction::Getfield) | - 0xb2 => map!(be_u16, Instruction::Getstatic) | - 0xa7 => map!(be_i16, Instruction::Goto) | - 0xc8 => map!(be_i32, Instruction::GotoW) | - 0x91 => value!(Instruction::I2b) | - 0x92 => value!(Instruction::I2c) | - 0x87 => value!(Instruction::I2d) | - 0x86 => value!(Instruction::I2f) | - 0x85 => value!(Instruction::I2l) | - 0x93 => value!(Instruction::I2s) | - 0x60 => value!(Instruction::Iadd) | - 0x2e => value!(Instruction::Iaload) | - 0x7e => value!(Instruction::Iand) | - 0x4f => value!(Instruction::Iastore) | - 0x02 => value!(Instruction::Iconstm1) | - 0x03 => value!(Instruction::Iconst0) | - 0x04 => value!(Instruction::Iconst1) | - 0x05 => value!(Instruction::Iconst2) | - 0x06 => value!(Instruction::Iconst3) | - 0x07 => value!(Instruction::Iconst4) | - 0x08 => value!(Instruction::Iconst5) | - 0x6c => value!(Instruction::Idiv) | - 0xa5 => map!(be_i16, Instruction::IfAcmpeq) | - 0xa6 => map!(be_i16, Instruction::IfAcmpne) | - 0x9f => map!(be_i16, Instruction::IfIcmpeq) | - 0xa0 => map!(be_i16, Instruction::IfIcmpne) | - 0xa1 => map!(be_i16, Instruction::IfIcmplt) | - 0xa2 => map!(be_i16, Instruction::IfIcmpge) | - 0xa3 => map!(be_i16, Instruction::IfIcmpgt) | - 0xa4 => map!(be_i16, Instruction::IfIcmple) | - 0x99 => map!(be_i16, Instruction::Ifeq) | - 0x9a => map!(be_i16, Instruction::Ifne) | - 0x9b => map!(be_i16, Instruction::Iflt) | - 0x9c => map!(be_i16, Instruction::Ifge) | - 0x9d => map!(be_i16, Instruction::Ifgt) | - 0x9e => map!(be_i16, Instruction::Ifle) | - 0xc7 => map!(be_i16, Instruction::Ifnonnull) | - 0xc6 => map!(be_i16, Instruction::Ifnull) | - 0x84 => do_parse!(index: be_u8 >> value: be_i8 >> (Instruction::Iinc{index, value})) | - 0x15 => map!(be_u8, Instruction::Iload) | - 0x1a => value!(Instruction::Iload0) | - 0x1b => value!(Instruction::Iload1) | - 0x1c => value!(Instruction::Iload2) | - 0x1d => value!(Instruction::Iload3) | - 0x68 => value!(Instruction::Imul) | - 0x74 => value!(Instruction::Ineg) | - 0xc1 => map!(be_u16, Instruction::Instanceof) | - 0xba => do_parse!(index: be_u16 >> tag!(&[0, 0]) >> (Instruction::Invokedynamic(index))) | - 0xb9 => do_parse!(index: be_u16 >> count: be_u8 >> tag!(&[0]) >> (Instruction::Invokeinterface{index, count})) | - 0xb7 => map!(be_u16, Instruction::Invokespecial) | - 0xb8 => map!(be_u16, Instruction::Invokestatic) | - 0xb6 => map!(be_u16, Instruction::Invokevirtual) | - 0x80 => value!(Instruction::Ior) | - 0x70 => value!(Instruction::Irem) | - 0xac => value!(Instruction::Ireturn) | - 0x78 => value!(Instruction::Ishl) | - 0x7a => value!(Instruction::Ishr) | - 0x36 => map!(be_u8, Instruction::Istore) | - 0x3b => value!(Instruction::Istore0) | - 0x3c => value!(Instruction::Istore1) | - 0x3d => value!(Instruction::Istore2) | - 0x3e => value!(Instruction::Istore3) | - 0x64 => value!(Instruction::Isub) | - 0x7c => value!(Instruction::Iushr) | - 0x82 => value!(Instruction::Ixor) | - 0xa8 => map!(be_i16, Instruction::Jsr) | - 0xc9 => map!(be_i32, Instruction::JsrW) | - 0x8a => value!(Instruction::L2d) | - 0x89 => value!(Instruction::L2f) | - 0x88 => value!(Instruction::L2i) | - 0x61 => value!(Instruction::Ladd) | - 0x2f => value!(Instruction::Laload) | - 0x7f => value!(Instruction::Land) | - 0x50 => value!(Instruction::Lastore) | - 0x94 => value!(Instruction::Lcmp) | - 0x09 => value!(Instruction::Lconst0) | - 0x0a => value!(Instruction::Lconst1) | - 0x12 => map!(be_u8, Instruction::Ldc) | - 0x13 => map!(be_u16, Instruction::LdcW) | - 0x14 => map!(be_u16, Instruction::Ldc2W) | - 0x6d => value!(Instruction::Ldiv) | - 0x16 => map!(be_u8, Instruction::Lload) | - 0x1e => value!(Instruction::Lload0) | - 0x1f => value!(Instruction::Lload1) | - 0x20 => value!(Instruction::Lload2) | - 0x21 => value!(Instruction::Lload3) | - 0x69 => value!(Instruction::Lmul) | - 0x75 => value!(Instruction::Lneg) | - 0xab => preceded!(call!(align, address + 1), lookupswitch_parser) | - 0x81 => value!(Instruction::Lor) | - 0x71 => value!(Instruction::Lrem) | - 0xad => value!(Instruction::Lreturn) | - 0x79 => value!(Instruction::Lshl) | - 0x7b => value!(Instruction::Lshr) | - 0x37 => map!(be_u8, Instruction::Lstore) | - 0x3f => value!(Instruction::Lstore0) | - 0x40 => value!(Instruction::Lstore1) | - 0x41 => value!(Instruction::Lstore2) | - 0x42 => value!(Instruction::Lstore3) | - 0x65 => value!(Instruction::Lsub) | - 0x7d => value!(Instruction::Lushr) | - 0x83 => value!(Instruction::Lxor) | - 0xc2 => value!(Instruction::Monitorenter) | - 0xc3 => value!(Instruction::Monitorexit) | - 0xc5 => do_parse!(index: be_u16 >> dimensions: be_u8 >> (Instruction::Multianewarray{index, dimensions})) | - 0xbb => map!(be_u16, Instruction::New) | - 0xbc => map!(be_u8, Instruction::Newarray) | - 0x00 => value!(Instruction::Nop) | - 0x57 => value!(Instruction::Pop) | - 0x58 => value!(Instruction::Pop2) | - 0xb5 => map!(be_u16, Instruction::Putfield) | - 0xb3 => map!(be_u16, Instruction::Putstatic) | - 0xa9 => map!(be_u8, Instruction::Ret) | - 0xb1 => value!(Instruction::Return) | - 0x35 => value!(Instruction::Saload) | - 0x56 => value!(Instruction::Sastore) | - 0x11 => map!(be_i16, Instruction::Sipush) | - 0x5f => value!(Instruction::Swap) | - 0xaa => preceded!(call!(align, address + 1), tableswitch_parser) | - 0xc4 => switch!(be_u8, - 0x19 => map!(be_u16, Instruction::AloadWide) | - 0x3a => map!(be_u16, Instruction::AstoreWide) | - 0x18 => map!(be_u16, Instruction::DloadWide) | - 0x39 => map!(be_u16, Instruction::DstoreWide) | - 0x17 => map!(be_u16, Instruction::FloadWide) | - 0x38 => map!(be_u16, Instruction::FstoreWide) | - 0x15 => map!(be_u16, Instruction::IloadWide) | - 0x36 => map!(be_u16, Instruction::IstoreWide) | - 0x16 => map!(be_u16, Instruction::LloadWide) | - 0x37 => map!(be_u16, Instruction::LstoreWide) | - 0xa9 => map!(be_u16, Instruction::RetWide) | - 0x84 => do_parse!(index: be_u16 >> value: be_i16 >> (Instruction::IincWide{index, value})) - ) - ) + let (input, b0) = be_u8(input)?; + let (input, instruction) = match b0 { + 0x32 => success(Instruction::Aaload)(input)?, + 0x53 => success(Instruction::Aastore)(input)?, + 0x01 => success(Instruction::Aconstnull)(input)?, + 0x19 => map(be_u8, Instruction::Aload)(input)?, + 0x2a => success(Instruction::Aload0)(input)?, + 0x2b => success(Instruction::Aload1)(input)?, + 0x2c => success(Instruction::Aload2)(input)?, + 0x2d => success(Instruction::Aload3)(input)?, + 0xbd => map(be_u16, Instruction::Anewarray)(input)?, + 0xb0 => success(Instruction::Areturn)(input)?, + 0xbe => success(Instruction::Arraylength)(input)?, + 0x3a => map(be_u8, Instruction::Astore)(input)?, + 0x4b => success(Instruction::Astore0)(input)?, + 0x4c => success(Instruction::Astore1)(input)?, + 0x4d => success(Instruction::Astore2)(input)?, + 0x4e => success(Instruction::Astore3)(input)?, + 0xbf => success(Instruction::Athrow)(input)?, + 0x33 => success(Instruction::Baload)(input)?, + 0x54 => success(Instruction::Bastore)(input)?, + 0x10 => map(be_i8, Instruction::Bipush)(input)?, + 0x34 => success(Instruction::Caload)(input)?, + 0x55 => success(Instruction::Castore)(input)?, + 0xc0 => map(be_u16, Instruction::Checkcast)(input)?, + 0x90 => success(Instruction::D2f)(input)?, + 0x8e => success(Instruction::D2i)(input)?, + 0x8f => success(Instruction::D2l)(input)?, + 0x63 => success(Instruction::Dadd)(input)?, + 0x31 => success(Instruction::Daload)(input)?, + 0x52 => success(Instruction::Dastore)(input)?, + 0x98 => success(Instruction::Dcmpg)(input)?, + 0x97 => success(Instruction::Dcmpl)(input)?, + 0x0e => success(Instruction::Dconst0)(input)?, + 0x0f => success(Instruction::Dconst1)(input)?, + 0x6f => success(Instruction::Ddiv)(input)?, + 0x18 => map(be_u8, Instruction::Dload)(input)?, + 0x26 => success(Instruction::Dload0)(input)?, + 0x27 => success(Instruction::Dload1)(input)?, + 0x28 => success(Instruction::Dload2)(input)?, + 0x29 => success(Instruction::Dload3)(input)?, + 0x6b => success(Instruction::Dmul)(input)?, + 0x77 => success(Instruction::Dneg)(input)?, + 0x73 => success(Instruction::Drem)(input)?, + 0xaf => success(Instruction::Dreturn)(input)?, + 0x39 => map(be_u8, Instruction::Dstore)(input)?, + 0x47 => success(Instruction::Dstore0)(input)?, + 0x48 => success(Instruction::Dstore1)(input)?, + 0x49 => success(Instruction::Dstore2)(input)?, + 0x4a => success(Instruction::Dstore3)(input)?, + 0x67 => success(Instruction::Dsub)(input)?, + 0x59 => success(Instruction::Dup)(input)?, + 0x5a => success(Instruction::Dupx1)(input)?, + 0x5b => success(Instruction::Dupx2)(input)?, + 0x5c => success(Instruction::Dup2)(input)?, + 0x5d => success(Instruction::Dup2x1)(input)?, + 0x5e => success(Instruction::Dup2x2)(input)?, + 0x8d => success(Instruction::F2d)(input)?, + 0x8b => success(Instruction::F2i)(input)?, + 0x8c => success(Instruction::F2l)(input)?, + 0x62 => success(Instruction::Fadd)(input)?, + 0x30 => success(Instruction::Faload)(input)?, + 0x51 => success(Instruction::Fastore)(input)?, + 0x96 => success(Instruction::Fcmpg)(input)?, + 0x95 => success(Instruction::Fcmpl)(input)?, + 0x0b => success(Instruction::Fconst0)(input)?, + 0x0c => success(Instruction::Fconst1)(input)?, + 0x0d => success(Instruction::Fconst2)(input)?, + 0x6e => success(Instruction::Fdiv)(input)?, + 0x17 => map(be_u8, Instruction::Fload)(input)?, + 0x22 => success(Instruction::Fload0)(input)?, + 0x23 => success(Instruction::Fload1)(input)?, + 0x24 => success(Instruction::Fload2)(input)?, + 0x25 => success(Instruction::Fload3)(input)?, + 0x6a => success(Instruction::Fmul)(input)?, + 0x76 => success(Instruction::Fneg)(input)?, + 0x72 => success(Instruction::Frem)(input)?, + 0xae => success(Instruction::Freturn)(input)?, + 0x38 => map(be_u8, Instruction::Fstore)(input)?, + 0x43 => success(Instruction::Fstore0)(input)?, + 0x44 => success(Instruction::Fstore1)(input)?, + 0x45 => success(Instruction::Fstore2)(input)?, + 0x46 => success(Instruction::Fstore3)(input)?, + 0x66 => success(Instruction::Fsub)(input)?, + 0xb4 => map(be_u16, Instruction::Getfield)(input)?, + 0xb2 => map(be_u16, Instruction::Getstatic)(input)?, + 0xa7 => map(be_i16, Instruction::Goto)(input)?, + 0xc8 => map(be_i32, Instruction::GotoW)(input)?, + 0x91 => success(Instruction::I2b)(input)?, + 0x92 => success(Instruction::I2c)(input)?, + 0x87 => success(Instruction::I2d)(input)?, + 0x86 => success(Instruction::I2f)(input)?, + 0x85 => success(Instruction::I2l)(input)?, + 0x93 => success(Instruction::I2s)(input)?, + 0x60 => success(Instruction::Iadd)(input)?, + 0x2e => success(Instruction::Iaload)(input)?, + 0x7e => success(Instruction::Iand)(input)?, + 0x4f => success(Instruction::Iastore)(input)?, + 0x02 => success(Instruction::Iconstm1)(input)?, + 0x03 => success(Instruction::Iconst0)(input)?, + 0x04 => success(Instruction::Iconst1)(input)?, + 0x05 => success(Instruction::Iconst2)(input)?, + 0x06 => success(Instruction::Iconst3)(input)?, + 0x07 => success(Instruction::Iconst4)(input)?, + 0x08 => success(Instruction::Iconst5)(input)?, + 0x6c => success(Instruction::Idiv)(input)?, + 0xa5 => map(be_i16, Instruction::IfAcmpeq)(input)?, + 0xa6 => map(be_i16, Instruction::IfAcmpne)(input)?, + 0x9f => map(be_i16, Instruction::IfIcmpeq)(input)?, + 0xa0 => map(be_i16, Instruction::IfIcmpne)(input)?, + 0xa1 => map(be_i16, Instruction::IfIcmplt)(input)?, + 0xa2 => map(be_i16, Instruction::IfIcmpge)(input)?, + 0xa3 => map(be_i16, Instruction::IfIcmpgt)(input)?, + 0xa4 => map(be_i16, Instruction::IfIcmple)(input)?, + 0x99 => map(be_i16, Instruction::Ifeq)(input)?, + 0x9a => map(be_i16, Instruction::Ifne)(input)?, + 0x9b => map(be_i16, Instruction::Iflt)(input)?, + 0x9c => map(be_i16, Instruction::Ifge)(input)?, + 0x9d => map(be_i16, Instruction::Ifgt)(input)?, + 0x9e => map(be_i16, Instruction::Ifle)(input)?, + 0xc7 => map(be_i16, Instruction::Ifnonnull)(input)?, + 0xc6 => map(be_i16, Instruction::Ifnull)(input)?, + 0x84 => map(pair(be_u8, be_i8), |(index, value)| Instruction::Iinc { + index, + value, + })(input)?, + 0x15 => map(be_u8, Instruction::Iload)(input)?, + 0x1a => success(Instruction::Iload0)(input)?, + 0x1b => success(Instruction::Iload1)(input)?, + 0x1c => success(Instruction::Iload2)(input)?, + 0x1d => success(Instruction::Iload3)(input)?, + 0x68 => success(Instruction::Imul)(input)?, + 0x74 => success(Instruction::Ineg)(input)?, + 0xc1 => map(be_u16, Instruction::Instanceof)(input)?, + 0xba => map(pair(be_u16, tag(&[0, 0])), |(index, _)| { + Instruction::Invokedynamic(index) + })(input)?, + 0xb9 => map(tuple((be_u16, be_u8, tag(&[0]))), |(index, count, _)| { + Instruction::Invokeinterface { index, count } + })(input)?, + 0xb7 => map(be_u16, Instruction::Invokespecial)(input)?, + 0xb8 => map(be_u16, Instruction::Invokestatic)(input)?, + 0xb6 => map(be_u16, Instruction::Invokevirtual)(input)?, + 0x80 => success(Instruction::Ior)(input)?, + 0x70 => success(Instruction::Irem)(input)?, + 0xac => success(Instruction::Ireturn)(input)?, + 0x78 => success(Instruction::Ishl)(input)?, + 0x7a => success(Instruction::Ishr)(input)?, + 0x36 => map(be_u8, Instruction::Istore)(input)?, + 0x3b => success(Instruction::Istore0)(input)?, + 0x3c => success(Instruction::Istore1)(input)?, + 0x3d => success(Instruction::Istore2)(input)?, + 0x3e => success(Instruction::Istore3)(input)?, + 0x64 => success(Instruction::Isub)(input)?, + 0x7c => success(Instruction::Iushr)(input)?, + 0x82 => success(Instruction::Ixor)(input)?, + 0xa8 => map(be_i16, Instruction::Jsr)(input)?, + 0xc9 => map(be_i32, Instruction::JsrW)(input)?, + 0x8a => success(Instruction::L2d)(input)?, + 0x89 => success(Instruction::L2f)(input)?, + 0x88 => success(Instruction::L2i)(input)?, + 0x61 => success(Instruction::Ladd)(input)?, + 0x2f => success(Instruction::Laload)(input)?, + 0x7f => success(Instruction::Land)(input)?, + 0x50 => success(Instruction::Lastore)(input)?, + 0x94 => success(Instruction::Lcmp)(input)?, + 0x09 => success(Instruction::Lconst0)(input)?, + 0x0a => success(Instruction::Lconst1)(input)?, + 0x12 => map(be_u8, Instruction::Ldc)(input)?, + 0x13 => map(be_u16, Instruction::LdcW)(input)?, + 0x14 => map(be_u16, Instruction::Ldc2W)(input)?, + 0x6d => success(Instruction::Ldiv)(input)?, + 0x16 => map(be_u8, Instruction::Lload)(input)?, + 0x1e => success(Instruction::Lload0)(input)?, + 0x1f => success(Instruction::Lload1)(input)?, + 0x20 => success(Instruction::Lload2)(input)?, + 0x21 => success(Instruction::Lload3)(input)?, + 0x69 => success(Instruction::Lmul)(input)?, + 0x75 => success(Instruction::Lneg)(input)?, + 0xab => preceded(align(address + 1), lookupswitch_parser)(input)?, + 0x81 => success(Instruction::Lor)(input)?, + 0x71 => success(Instruction::Lrem)(input)?, + 0xad => success(Instruction::Lreturn)(input)?, + 0x79 => success(Instruction::Lshl)(input)?, + 0x7b => success(Instruction::Lshr)(input)?, + 0x37 => map(be_u8, Instruction::Lstore)(input)?, + 0x3f => success(Instruction::Lstore0)(input)?, + 0x40 => success(Instruction::Lstore1)(input)?, + 0x41 => success(Instruction::Lstore2)(input)?, + 0x42 => success(Instruction::Lstore3)(input)?, + 0x65 => success(Instruction::Lsub)(input)?, + 0x7d => success(Instruction::Lushr)(input)?, + 0x83 => success(Instruction::Lxor)(input)?, + 0xc2 => success(Instruction::Monitorenter)(input)?, + 0xc3 => success(Instruction::Monitorexit)(input)?, + 0xc5 => map(pair(be_u16, be_u8), |(index, dimensions)| { + Instruction::Multianewarray { index, dimensions } + })(input)?, + 0xbb => map(be_u16, Instruction::New)(input)?, + 0xbc => map(be_u8, Instruction::Newarray)(input)?, + 0x00 => success(Instruction::Nop)(input)?, + 0x57 => success(Instruction::Pop)(input)?, + 0x58 => success(Instruction::Pop2)(input)?, + 0xb5 => map(be_u16, Instruction::Putfield)(input)?, + 0xb3 => map(be_u16, Instruction::Putstatic)(input)?, + 0xa9 => map(be_u8, Instruction::Ret)(input)?, + 0xb1 => success(Instruction::Return)(input)?, + 0x35 => success(Instruction::Saload)(input)?, + 0x56 => success(Instruction::Sastore)(input)?, + 0x11 => map(be_i16, Instruction::Sipush)(input)?, + 0x5f => success(Instruction::Swap)(input)?, + 0xaa => preceded(align(address + 1), tableswitch_parser)(input)?, + 0xc4 => { + let (input, b1) = be_u8(input)?; + match b1 { + 0x19 => map(be_u16, Instruction::AloadWide)(input)?, + 0x3a => map(be_u16, Instruction::AstoreWide)(input)?, + 0x18 => map(be_u16, Instruction::DloadWide)(input)?, + 0x39 => map(be_u16, Instruction::DstoreWide)(input)?, + 0x17 => map(be_u16, Instruction::FloadWide)(input)?, + 0x38 => map(be_u16, Instruction::FstoreWide)(input)?, + 0x15 => map(be_u16, Instruction::IloadWide)(input)?, + 0x36 => map(be_u16, Instruction::IstoreWide)(input)?, + 0x16 => map(be_u16, Instruction::LloadWide)(input)?, + 0x37 => map(be_u16, Instruction::LstoreWide)(input)?, + 0xa9 => map(be_u16, Instruction::RetWide)(input)?, + 0x84 => map(pair(be_u16, be_i16), |(index, value)| { + Instruction::IincWide { index, value } + })(input)?, + _ => fail(input)?, + } + } + _ => fail(input)?, + }; + Ok((input, instruction)) } diff --git a/src/constant_info/parser.rs b/src/constant_info/parser.rs index 423f1f8..87ff98d 100644 --- a/src/constant_info/parser.rs +++ b/src/constant_info/parser.rs @@ -1,4 +1,6 @@ use nom::{ + bytes::complete::take, + combinator::map, error::{Error, ErrorKind}, number::complete::{be_f32, be_f64, be_i32, be_i64, be_u16, be_u8}, Err, @@ -15,140 +17,121 @@ fn utf8_constant(input: &[u8]) -> Utf8Constant { } } -named!(const_utf8<&[u8], ConstantInfo>, do_parse!( - length: be_u16 >> - constant: map!(take!(length), utf8_constant) >> - (ConstantInfo::Utf8(constant)) -)); +fn const_utf8(input: &[u8]) -> ConstantInfoResult { + let (input, length) = be_u16(input)?; + let (input, constant) = map(take(length), utf8_constant)(input)?; + Ok((input, ConstantInfo::Utf8(constant))) +} -named!(const_integer<&[u8], ConstantInfo>, do_parse!( - value: be_i32 >> - (ConstantInfo::Integer( - IntegerConstant { - value, - } - )) -)); +fn const_integer(input: &[u8]) -> ConstantInfoResult { + let (input, value) = be_i32(input)?; + Ok((input, ConstantInfo::Integer(IntegerConstant { value }))) +} -named!(const_float<&[u8], ConstantInfo>, do_parse!( - value: be_f32 >> - (ConstantInfo::Float( - FloatConstant { - value, - } - )) -)); +fn const_float(input: &[u8]) -> ConstantInfoResult { + let (input, value) = be_f32(input)?; + Ok((input, ConstantInfo::Float(FloatConstant { value }))) +} -named!(const_long<&[u8], ConstantInfo>, do_parse!( - value: be_i64 >> - (ConstantInfo::Long( - LongConstant { - value, - } - )) -)); +fn const_long(input: &[u8]) -> ConstantInfoResult { + let (input, value) = be_i64(input)?; + Ok((input, ConstantInfo::Long(LongConstant { value }))) +} -named!(const_double<&[u8], ConstantInfo>, do_parse!( - value: be_f64 >> - (ConstantInfo::Double( - DoubleConstant { - value, - } - )) -)); +fn const_double(input: &[u8]) -> ConstantInfoResult { + let (input, value) = be_f64(input)?; + Ok((input, ConstantInfo::Double(DoubleConstant { value }))) +} -named!(const_class<&[u8], ConstantInfo>, do_parse!( - name_index: be_u16 >> - (ConstantInfo::Class( - ClassConstant { - name_index, - } - )) -)); +fn const_class(input: &[u8]) -> ConstantInfoResult { + let (input, name_index) = be_u16(input)?; + Ok((input, ConstantInfo::Class(ClassConstant { name_index }))) +} -named!(const_string<&[u8], ConstantInfo>, do_parse!( - string_index: be_u16 >> - (ConstantInfo::String( - StringConstant { - string_index, - } - )) -)); +fn const_string(input: &[u8]) -> ConstantInfoResult { + let (input, string_index) = be_u16(input)?; + Ok((input, ConstantInfo::String(StringConstant { string_index }))) +} -named!(const_field_ref<&[u8], ConstantInfo>, do_parse!( - class_index: be_u16 >> - name_and_type_index: be_u16 >> - (ConstantInfo::FieldRef( - FieldRefConstant { +fn const_field_ref(input: &[u8]) -> ConstantInfoResult { + let (input, class_index) = be_u16(input)?; + let (input, name_and_type_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::FieldRef(FieldRefConstant { class_index, name_and_type_index, - } + }), )) -)); +} -named!(const_method_ref<&[u8], ConstantInfo>, do_parse!( - class_index: be_u16 >> - name_and_type_index: be_u16 >> - (ConstantInfo::MethodRef( - MethodRefConstant { +fn const_method_ref(input: &[u8]) -> ConstantInfoResult { + let (input, class_index) = be_u16(input)?; + let (input, name_and_type_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::MethodRef(MethodRefConstant { class_index, name_and_type_index, - } + }), )) -)); +} -named!(const_interface_method_ref<&[u8], ConstantInfo>, do_parse!( - class_index: be_u16 >> - name_and_type_index: be_u16 >> - (ConstantInfo::InterfaceMethodRef( - InterfaceMethodRefConstant { +fn const_interface_method_ref(input: &[u8]) -> ConstantInfoResult { + let (input, class_index) = be_u16(input)?; + let (input, name_and_type_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::InterfaceMethodRef(InterfaceMethodRefConstant { class_index, name_and_type_index, - } + }), )) -)); +} -named!(const_name_and_type<&[u8], ConstantInfo>, do_parse!( - name_index: be_u16 >> - descriptor_index: be_u16 >> - (ConstantInfo::NameAndType( - NameAndTypeConstant { +fn const_name_and_type(input: &[u8]) -> ConstantInfoResult { + let (input, name_index) = be_u16(input)?; + let (input, descriptor_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::NameAndType(NameAndTypeConstant { name_index, descriptor_index, - } + }), )) -)); +} -named!(const_method_handle<&[u8], ConstantInfo>, do_parse!( - reference_kind: be_u8 >> - reference_index: be_u16 >> - (ConstantInfo::MethodHandle( - MethodHandleConstant { +fn const_method_handle(input: &[u8]) -> ConstantInfoResult { + let (input, reference_kind) = be_u8(input)?; + let (input, reference_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::MethodHandle(MethodHandleConstant { reference_kind, reference_index, - } + }), )) -)); +} -named!(const_method_type<&[u8], ConstantInfo>, do_parse!( - descriptor_index: be_u16 >> - (ConstantInfo::MethodType( - MethodTypeConstant { - descriptor_index, - } +fn const_method_type(input: &[u8]) -> ConstantInfoResult { + let (input, descriptor_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::MethodType(MethodTypeConstant { descriptor_index }), )) -)); +} -named!(const_invoke_dynamic<&[u8], ConstantInfo>, do_parse!( - bootstrap_method_attr_index: be_u16 >> - name_and_type_index: be_u16 >> - (ConstantInfo::InvokeDynamic( - InvokeDynamicConstant { +fn const_invoke_dynamic(input: &[u8]) -> ConstantInfoResult { + let (input, bootstrap_method_attr_index) = be_u16(input)?; + let (input, name_and_type_index) = be_u16(input)?; + Ok(( + input, + ConstantInfo::InvokeDynamic(InvokeDynamicConstant { bootstrap_method_attr_index, name_and_type_index, - } + }), )) -)); +} type ConstantInfoResult<'a> = Result<(&'a [u8], ConstantInfo), Err>>; type ConstantInfoVecResult<'a> = Result<(&'a [u8], Vec), Err>>; @@ -174,10 +157,9 @@ fn const_block_parser(input: &[u8], const_type: u8) -> ConstantInfoResult { } fn single_constant_parser(input: &[u8]) -> ConstantInfoResult { - do_parse!( - input, - const_type: be_u8 >> const_block: call!(const_block_parser, const_type) >> (const_block) - ) + let (input, const_type) = be_u8(input)?; + let (input, const_block) = const_block_parser(input, const_type)?; + Ok((input, const_block)) } pub fn constant_parser(i: &[u8], const_pool_size: usize) -> ConstantInfoVecResult { diff --git a/src/field_info/parser.rs b/src/field_info/parser.rs index f21cb11..b4c7bba 100644 --- a/src/field_info/parser.rs +++ b/src/field_info/parser.rs @@ -1,23 +1,23 @@ -use nom::{number::complete::be_u16, IResult}; +use nom::{multi::count, number::complete::be_u16, IResult}; use attribute_info::attribute_parser; use field_info::{FieldAccessFlags, FieldInfo}; pub fn field_parser(input: &[u8]) -> IResult<&[u8], FieldInfo> { - do_parse!( + let (input, access_flags) = be_u16(input)?; + let (input, name_index) = be_u16(input)?; + let (input, descriptor_index) = be_u16(input)?; + let (input, attributes_count) = be_u16(input)?; + let (input, attributes) = count(attribute_parser, attributes_count as usize)(input)?; + Ok(( input, - access_flags: be_u16 - >> name_index: be_u16 - >> descriptor_index: be_u16 - >> attributes_count: be_u16 - >> attributes: count!(attribute_parser, attributes_count as usize) - >> (FieldInfo { - access_flags: FieldAccessFlags::from_bits_truncate(access_flags), - name_index, - descriptor_index, - attributes_count, - attributes, - }) - ) + FieldInfo { + access_flags: FieldAccessFlags::from_bits_truncate(access_flags), + name_index, + descriptor_index, + attributes_count, + attributes, + }, + )) } diff --git a/src/method_info/parser.rs b/src/method_info/parser.rs index cc38bb0..9d9140e 100644 --- a/src/method_info/parser.rs +++ b/src/method_info/parser.rs @@ -1,23 +1,23 @@ -use nom::{number::complete::be_u16, IResult}; +use nom::{multi::count, number::complete::be_u16, IResult}; use attribute_info::attribute_parser; use method_info::{MethodAccessFlags, MethodInfo}; pub fn method_parser(input: &[u8]) -> IResult<&[u8], MethodInfo> { - do_parse!( + let (input, access_flags) = be_u16(input)?; + let (input, name_index) = be_u16(input)?; + let (input, descriptor_index) = be_u16(input)?; + let (input, attributes_count) = be_u16(input)?; + let (input, attributes) = count(attribute_parser, attributes_count as usize)(input)?; + Ok(( input, - access_flags: be_u16 - >> name_index: be_u16 - >> descriptor_index: be_u16 - >> attributes_count: be_u16 - >> attributes: count!(attribute_parser, attributes_count as usize) - >> (MethodInfo { - access_flags: MethodAccessFlags::from_bits_truncate(access_flags), - name_index, - descriptor_index, - attributes_count, - attributes, - }) - ) + MethodInfo { + access_flags: MethodAccessFlags::from_bits_truncate(access_flags), + name_index, + descriptor_index, + attributes_count, + attributes, + }, + )) } diff --git a/src/parser.rs b/src/parser.rs index 6f7e1fb..a9d2be9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,9 +4,13 @@ use attribute_info::attribute_parser; use constant_info::constant_parser; use field_info::field_parser; use method_info::method_parser; +use nom::bytes::complete::tag; +use nom::multi::count; use types::{ClassAccessFlags, ClassFile}; -named!(magic_parser, tag!(&[0xCA, 0xFE, 0xBA, 0xBE])); +fn magic_parser(input: &[u8]) -> IResult<&[u8], &[u8]> { + tag(&[0xCA, 0xFE, 0xBA, 0xBE])(input) +} /// Parse a byte array into a ClassFile. This will probably be deprecated in 0.4.0 in as it returns /// a nom IResult type, which exposes the internal parsing library and not a good idea. @@ -26,40 +30,40 @@ named!(magic_parser, tag!(&[0xCA, 0xFE, 0xBA, 0xBE])); /// ``` pub fn class_parser(input: &[u8]) -> IResult<&[u8], ClassFile> { use nom::number::complete::be_u16; - do_parse!( + let (input, _) = magic_parser(input)?; + let (input, minor_version) = be_u16(input)?; + let (input, major_version) = be_u16(input)?; + let (input, const_pool_size) = be_u16(input)?; + let (input, const_pool) = constant_parser(input, (const_pool_size - 1) as usize)?; + let (input, access_flags) = be_u16(input)?; + let (input, this_class) = be_u16(input)?; + let (input, super_class) = be_u16(input)?; + let (input, interfaces_count) = be_u16(input)?; + let (input, interfaces) = count(be_u16, interfaces_count as usize)(input)?; + let (input, fields_count) = be_u16(input)?; + let (input, fields) = count(field_parser, fields_count as usize)(input)?; + let (input, methods_count) = be_u16(input)?; + let (input, methods) = count(method_parser, methods_count as usize)(input)?; + let (input, attributes_count) = be_u16(input)?; + let (input, attributes) = count(attribute_parser, attributes_count as usize)(input)?; + Ok(( input, - magic_parser - >> minor_version: be_u16 - >> major_version: be_u16 - >> const_pool_size: be_u16 - >> const_pool: call!(constant_parser, (const_pool_size - 1) as usize) - >> access_flags: be_u16 - >> this_class: be_u16 - >> super_class: be_u16 - >> interfaces_count: be_u16 - >> interfaces: count!(be_u16, interfaces_count as usize) - >> fields_count: be_u16 - >> fields: count!(field_parser, fields_count as usize) - >> methods_count: be_u16 - >> methods: count!(method_parser, methods_count as usize) - >> attributes_count: be_u16 - >> attributes: count!(attribute_parser, attributes_count as usize) - >> (ClassFile { - minor_version, - major_version, - const_pool_size, - const_pool, - access_flags: ClassAccessFlags::from_bits_truncate(access_flags), - this_class, - super_class, - interfaces_count, - interfaces, - fields_count, - fields, - methods_count, - methods, - attributes_count, - attributes, - }) - ) + ClassFile { + minor_version, + major_version, + const_pool_size, + const_pool, + access_flags: ClassAccessFlags::from_bits_truncate(access_flags), + this_class, + super_class, + interfaces_count, + interfaces, + fields_count, + fields, + methods_count, + methods, + attributes_count, + attributes, + }, + )) }