@@ -124,17 +124,25 @@ impl<'a> ClassWriter<'a> {
124
124
& Attribute :: RawAttribute { name_index : ref n_idx, info : ref bytes } => self . write_u16 ( n_idx. idx as u16 ) . and ( self . write_u32 ( bytes. len ( ) as u32 ) ) . and ( self . write_n ( bytes) ) ,
125
125
& Attribute :: ConstantValue ( ref idx) => self . write_u16 ( cp. get_utf8_index ( "ConstantValue" ) as u16 ) . and ( self . write_u32 ( 2 ) ) . and ( self . write_u16 ( idx. idx as u16 ) ) ,
126
126
& Attribute :: Code { max_stack, max_locals, ref code, ref exception_table, ref attributes } => {
127
+ let mut target: Vec < u8 > = vec ! [ ] ;
128
+
129
+ {
130
+ let mut code_writer = ClassWriter :: new ( & mut target) ;
131
+
132
+ let _ = code_writer. write_u16 ( max_stack)
133
+ . and ( code_writer. write_u16 ( max_locals) )
134
+ . and ( code_writer. write_instructions ( code) )
135
+ . and ( code_writer. write_exception_handlers ( exception_table) )
136
+ . and ( code_writer. write_attributes ( attributes, cp) ) ;
137
+ }
138
+
127
139
self . write_u16 ( cp. get_utf8_index ( "Code" ) as u16 )
128
- . and ( self . write_u32 ( 33 ) )
129
- . and ( self . write_u16 ( max_stack) )
130
- . and ( self . write_u16 ( max_locals) )
131
- . and ( self . write_instructions ( code) )
132
- . and ( self . write_exception_handlers ( exception_table) )
133
- . and ( self . write_attributes ( attributes, cp) )
140
+ . and ( self . write_u32 ( target. len ( ) as u32 ) )
141
+ . and ( self . write_n ( & target) )
134
142
} ,
135
143
& Attribute :: StackMapTable ( ref table) => self . write_stack_map_table ( table, cp) ,
136
- & Attribute :: Exceptions ( ref table) => self . write_u16 ( cp. get_utf8_index ( "Exceptions" ) as u16 ) . and ( self . write_u32 ( 2 + ( table. len ( ) as u32 ) * 2 ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_u16 ( x. idx as u16 ) ) ) ,
137
- & Attribute :: InnerClasses ( ref table) => self . write_u16 ( cp. get_utf8_index ( "InnerClasses" ) as u16 ) . and ( self . write_u32 ( 2 + ( table. len ( ) as u32 ) * 8 ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| {
144
+ & Attribute :: Exceptions ( ref table) => self . write_u16 ( cp. get_utf8_index ( "Exceptions" ) as u16 ) . and ( self . write_u32 ( 2 + ( table. len ( ) as u32 ) * 2 ) ) . and ( self . write_u16 ( table . len ( ) as u16 ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_u16 ( x. idx as u16 ) ) ) ,
145
+ & Attribute :: InnerClasses ( ref table) => self . write_u16 ( cp. get_utf8_index ( "InnerClasses" ) as u16 ) . and ( self . write_u32 ( 2 + ( table. len ( ) as u32 ) * 8 ) ) . and ( self . write_u16 ( table . len ( ) as u16 ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| {
138
146
self . write_u16 ( x. inner_class_info_index . idx as u16 )
139
147
. and ( self . write_u16 ( x. outer_class_info_index . idx as u16 ) )
140
148
. and ( self . write_u16 ( x. inner_name_index . idx as u16 ) )
@@ -163,8 +171,24 @@ impl<'a> ClassWriter<'a> {
163
171
. and ( self . write_u16 ( x. index ) )
164
172
} ) ) ,
165
173
& Attribute :: Deprecated => self . write_u16 ( cp. get_utf8_index ( "Deprecated" ) as u16 ) . and ( self . write_u32 ( 0 ) ) ,
166
- & Attribute :: RuntimeVisibleAnnotations ( ref table) => self . write_u16 ( cp. get_utf8_index ( "RuntimeVisibleAnnotations" ) as u16 ) . and ( self . write_u32 ( table. iter ( ) . fold ( 2 , |acc, x| acc + x. len ( ) as u32 ) ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_annotation ( x, cp) ) ) ,
167
- & Attribute :: RuntimeInvisibleAnnotations ( ref table) => self . write_u16 ( cp. get_utf8_index ( "RuntimeInvisibleAnnotations" ) as u16 ) . and ( self . write_u32 ( table. iter ( ) . fold ( 2 , |acc, x| acc + x. len ( ) as u32 ) ) ) . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_annotation ( x, cp) ) ) ,
174
+ & Attribute :: RuntimeVisibleAnnotations ( ref table) => {
175
+ self . write_u16 ( cp. get_utf8_index ( "RuntimeVisibleAnnotations" ) as u16 )
176
+ // attribute_length
177
+ . and ( self . write_u32 ( table. iter ( ) . fold ( 2 , |acc, x| acc + x. len ( ) as u32 ) ) )
178
+ // num_annotations
179
+ . and ( self . write_u16 ( table. len ( ) as u16 ) )
180
+ // annotations
181
+ . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_annotation ( x, cp) ) )
182
+ } ,
183
+ & Attribute :: RuntimeInvisibleAnnotations ( ref table) => {
184
+ self . write_u16 ( cp. get_utf8_index ( "RuntimeInvisibleAnnotations" ) as u16 )
185
+ // attribute_length
186
+ . and ( self . write_u32 ( table. iter ( ) . fold ( 2 , |acc, x| acc + x. len ( ) as u32 ) ) )
187
+ // num_annotations
188
+ . and ( self . write_u16 ( table. len ( ) as u16 ) )
189
+ // annotations
190
+ . and ( table. iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_annotation ( x, cp) ) )
191
+ } ,
168
192
& Attribute :: RuntimeVisibleParameterAnnotations ( ref table) => {
169
193
self . write_u16 ( cp. get_utf8_index ( "RuntimeVisibleParameterAnnotations" ) as u16 )
170
194
// attribute_length
@@ -185,11 +209,11 @@ impl<'a> ClassWriter<'a> {
185
209
} ,
186
210
& Attribute :: RuntimeVisibleTypeAnnotations ( ref table) => {
187
211
// TODO
188
- self . write_u8 ( 1 )
212
+ self . write_u32 ( 1 )
189
213
} ,
190
214
& Attribute :: RuntimeInvisibleTypeAnnotations ( ref table) => {
191
215
// TODO
192
- self . write_u8 ( 2 )
216
+ self . write_u16 ( 2 )
193
217
} ,
194
218
& Attribute :: AnnotationDefault ( ref value) => {
195
219
self . write_u16 ( cp. get_utf8_index ( "AnnotationDefault" ) as u16 )
@@ -282,7 +306,12 @@ impl<'a> ClassWriter<'a> {
282
306
}
283
307
284
308
fn write_annotation ( & mut self , annotation : & Annotation , cp : & ConstantPool ) -> Result < usize , Error > {
285
- self . write_u16 ( annotation. type_index . idx as u16 ) . and ( annotation. element_value_pairs . iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_element_value_pair ( x, cp) ) )
309
+ // type_index
310
+ self . write_u16 ( annotation. type_index . idx as u16 )
311
+ // num_element_value_pairs
312
+ . and ( self . write_u16 ( annotation. element_value_pairs . len ( ) as u16 ) )
313
+ // element_value_pairs
314
+ . and ( annotation. element_value_pairs . iter ( ) . fold ( Ok ( 0 ) , |_, x| self . write_element_value_pair ( x, cp) ) )
286
315
}
287
316
288
317
fn write_instructions ( & mut self , instructions : & Vec < Instruction > ) -> Result < usize , Error > {
@@ -295,7 +324,7 @@ impl<'a> ClassWriter<'a> {
295
324
} )
296
325
} ;
297
326
298
- self . write_u32 ( written_bytes as u32 ) . and_then ( |x| self . write_n ( & target) . map ( |y| x + y) )
327
+ self . write_u32 ( target . len ( ) as u32 ) . and_then ( |x| self . write_n ( & target) . map ( |y| x + y) )
299
328
}
300
329
301
330
/// Renders a single instruction into the output stream
@@ -304,6 +333,7 @@ impl<'a> ClassWriter<'a> {
304
333
& Instruction :: AALOAD => self . write_u8 ( 0x32 ) ,
305
334
& Instruction :: AASTORE => self . write_u8 ( 0x53 ) ,
306
335
& Instruction :: ACONST_NULL => self . write_u8 ( 0x01 ) ,
336
+ & Instruction :: ALOAD ( value) => self . write_u8 ( 0x19 ) . and ( self . write_u8 ( value) ) ,
307
337
& Instruction :: ALOAD_0 => self . write_u8 ( 0x2a ) ,
308
338
& Instruction :: ALOAD_1 => self . write_u8 ( 0x2b ) ,
309
339
& Instruction :: ALOAD_2 => self . write_u8 ( 0x2c ) ,
@@ -429,8 +459,8 @@ impl<'a> ClassWriter<'a> {
429
459
& Instruction :: IMUL => self . write_u8 ( 0x68 ) ,
430
460
& Instruction :: INEG => self . write_u8 ( 0x74 ) ,
431
461
& Instruction :: INSTANCEOF ( value) => self . write_u8 ( 0xc1 ) . and ( self . write_u16 ( value) ) ,
432
- & Instruction :: INVOKEDYNAMIC ( value) => self . write_u8 ( 0xba ) . and ( self . write_u16 ( value) ) ,
433
- & Instruction :: INVOKEINTERFACE ( a, b) => self . write_u8 ( 0xb9 ) . and ( self . write_u16 ( a) ) . and ( self . write_u8 ( b) ) ,
462
+ & Instruction :: INVOKEDYNAMIC ( value) => self . write_u8 ( 0xba ) . and ( self . write_u16 ( value) ) . and ( self . write_u16 ( 0 ) ) ,
463
+ & Instruction :: INVOKEINTERFACE ( a, b) => self . write_u8 ( 0xb9 ) . and ( self . write_u16 ( a) ) . and ( self . write_u8 ( b) ) . and ( self . write_u8 ( 0 ) ) ,
434
464
& Instruction :: INVOKESPECIAL ( value) => self . write_u8 ( 0xb7 ) . and ( self . write_u16 ( value) ) ,
435
465
& Instruction :: INVOKESTATIC ( value) => self . write_u8 ( 0xb8 ) . and ( self . write_u16 ( value) ) ,
436
466
& Instruction :: INVOKEVIRTUAL ( value) => self . write_u8 ( 0xb6 ) . and ( self . write_u16 ( value) ) ,
0 commit comments