unageanu-javaclass 0.2.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/ChangeLog +5 -0
  2. data/javaclass.gemspec +18 -0
  3. data/lib/javaclass.rb +1 -0
  4. data/lib/javaclass/accessflag.rb +1 -1
  5. data/lib/javaclass/attribute.rb +293 -2
  6. data/lib/javaclass/base.rb +33 -4
  7. data/lib/javaclass/code.rb +78 -0
  8. data/lib/javaclass/constant.rb +2 -2
  9. data/lib/javaclass/member.rb +18 -18
  10. data/lib/javaclass/reader.rb +460 -6
  11. data/sample/caller.rb +95 -0
  12. data/sample/java_class/com/example/Constants.class +0 -0
  13. data/sample/java_class/com/example/Deprecated.class +0 -0
  14. data/sample/java_class/com/example/InnerClass.class +0 -0
  15. data/sample/java_class/com/example/InnerClassImpl.class +0 -0
  16. data/sample/java_class/com/example/Kitten.class +0 -0
  17. data/sample/java_class/com/example/ThrowsException.class +0 -0
  18. data/sample/java_class/com/example/annotation/Annotated.class +0 -0
  19. data/sample/java_class/com/example/annotation/AnnotatedMethod.class +0 -0
  20. data/sample/java_class/com/example/annotation/ClassAnnotationA.class +0 -0
  21. data/sample/java_class/com/example/annotation/HasDefaultValue.class +0 -0
  22. data/sample/java_class/com/example/annotation/RuntimeAnnotationA.class +0 -0
  23. data/sample/java_class/com/example/annotation/RuntimeAnnotationB.class +0 -0
  24. data/sample/java_class/com/example/annotation/RuntimeAnnotationC.class +0 -0
  25. data/sample/java_class/com/example/annotation/SourceAnnotationA.class +0 -0
  26. data/sample/java_class/com/example/caller/A.class +0 -0
  27. data/sample/java_class/com/example/caller/B.class +0 -0
  28. data/sample/java_class/com/example/caller/C.class +0 -0
  29. data/sample/java_class/com/example/caller/CallSample$A.class +0 -0
  30. data/sample/java_class/com/example/caller/CallSample$B.class +0 -0
  31. data/sample/java_class/com/example/caller/CallSample$C.class +0 -0
  32. data/sample/java_class/com/example/caller/CallSample.class +0 -0
  33. data/sample/java_class/com/example/caller/D.class +0 -0
  34. data/sample/java_class/com/example/code/Statement.class +0 -0
  35. data/sample/java_class/com/example/types/TypeVariables.class +0 -0
  36. data/sample/java_src/com/example/caller/A.java +19 -0
  37. data/sample/java_src/com/example/caller/B.java +7 -0
  38. data/sample/java_src/com/example/caller/C.java +7 -0
  39. data/sample/java_src/com/example/caller/CallSample.java +23 -0
  40. data/sample/java_src/com/example/caller/D.java +5 -0
  41. data/sample/java_src/com/example/code/Statement.java +41 -0
  42. data/sample/sample.rb +3 -3
  43. data/test/all_tests.rb +9 -0
  44. data/test/java_src/com/example/TestClass1.java +35 -0
  45. data/test/test_attribute.rb +150 -2
  46. data/test/test_class.rb +0 -1
  47. data/test/test_member.rb +4 -1
  48. metadata +44 -46
@@ -348,7 +348,7 @@ module JavaClass
348
348
  return -1.0/0 if bytes == 0xff800000
349
349
  return 0.0/0.0 if bytes >= 0x7f800001 && bytes <= 0x7fffffff
350
350
  return 0.0/0.0 if bytes >= 0xff800001 && bytes <= 0xffffffff
351
- s = ((bytes >> 31) == 0) ? 1 : -1
351
+ s = ((bytes >> 31) == 0) ? 1.0 : -1.0
352
352
  e = ((bytes >> 23) & 0xff)
353
353
  m = (e == 0) ? ((bytes & 0x7fffff) << 1) : ((bytes & 0x7fffff) | 0x800000)
354
354
  return s*m*(2**(e-150))
@@ -441,7 +441,7 @@ module JavaClass
441
441
  s = ((bytes >> 63) == 0) ? 1 : -1
442
442
  e = ((bytes >> 52) & 0x7ff)
443
443
  m = (e == 0) ? ((bytes & 0xfffffffffffff) << 1 ) : ((bytes & 0xfffffffffffff) | 0x10000000000000)
444
- return s*m*(2**(e-1075))
444
+ return (s*m*(2**(e-1075))).to_f
445
445
  end
446
446
  end
447
447
 
@@ -167,24 +167,24 @@ module JavaClass
167
167
  str << "\n" << attributes["Exceptions"].to_s if attributes.key? "Exceptions"
168
168
  if ( attributes.key? "Code")
169
169
  str << " {\n"
170
- # codes = attributes["Code"]
171
- # local_types = codes.attributes["LocalVariableTypeTable"] if codes.attributes.key? "LocalVariableTypeTable"
172
- #
173
- # if codes.attributes.key? "LocalVariableTable"
174
- # codes.attributes["LocalVariableTable"].local_variable_table.each {|l|
175
- # type = local_types.find_by_index(l.index) if local_types != nil
176
- # str << " // signature " << type.signature << "\n" if type != nil
177
- # str << " " << convert_field_descriptor(l.descriptor)
178
- # str << " " << l.name << ";\n"
179
- # }
180
- # end
181
- # str << "\n"
182
- # lines = codes.attributes["LineNumberTable"] if codes.attributes.key? "LineNumberTable"
183
- # codes.codes.each_index {|i|
184
- # str << " " << convert_code(codes.codes[i])
185
- # str << " // line : #{lines.line_number(i)}" if lines != nil && lines.line_number(i) != nil
186
- # str << "\n";
187
- # }
170
+ codes = attributes["Code"]
171
+ local_types = codes.attributes["LocalVariableTypeTable"] if codes.attributes.key? "LocalVariableTypeTable"
172
+
173
+ if codes.attributes.key? "LocalVariableTable"
174
+ codes.attributes["LocalVariableTable"].local_variable_table.each {|l|
175
+ type = local_types.find_by_index(l.index) if local_types != nil
176
+ str << " // signature " << type.signature << "\n" if type != nil
177
+ str << " " << convert_field_descriptor(l.descriptor)
178
+ str << " " << l.name << ";\n"
179
+ }
180
+ end
181
+ str << "\n"
182
+ lines = codes.attributes["LineNumberTable"] if codes.attributes.key? "LineNumberTable"
183
+ codes.codes.each_index {|i|
184
+ str << " " << codes.codes[i].to_s
185
+ str << " // #{lines.line_number(i)}" if lines != nil && lines.line_number(i) != nil
186
+ str << "\n";
187
+ }
188
188
  str << "}"
189
189
  end
190
190
  str << " #{attributes['AnnotationDefault'].to_s}" if attributes.key? 'AnnotationDefault'
@@ -120,13 +120,21 @@ module_function
120
120
  #
121
121
  #=== IOから指定したバイト数だけデータを読み込んで返す
122
122
  #
123
- #*size::読み込むだバイト数
123
+ #*size::読み込むバイト数
124
124
  #*io::IO
125
125
  #<b>戻り値</b>::データ
126
126
  #
127
- def read( size, io )
127
+ def read( size, io, unsigned=true )
128
128
  res = 0
129
- size.times{|i| res = res << 8 | io.getc }
129
+ size.times{|i|
130
+ res = res << 8 | io.getc
131
+ }
132
+ if !unsigned
133
+ border = 0x80 << (8 * (size-1))
134
+ mask = 0x7f
135
+ (size-1).times { mask = mask << 8 | 0xff }
136
+ res = (res & border ) != 0 ? (res & mask ) - border : res
137
+ end
130
138
  return res
131
139
  end
132
140
 
@@ -214,6 +222,7 @@ module_function
214
222
  name = java_class.get_constant_value( name_index )
215
223
  length = read( 4, io )
216
224
  attr = nil
225
+
217
226
  case name
218
227
  when "ConstantValue"
219
228
  constant_value_index = read( 2, io )
@@ -270,9 +279,10 @@ module_function
270
279
  max_locals = read( 2, io )
271
280
  codes = []
272
281
  code_length = read( 4, io )
273
- code_length.times {
274
- codes << read( 1, io )
275
- }
282
+ readed = 0
283
+ while( code_length > readed )
284
+ readed += read_code( readed, io, java_class, codes )
285
+ end
276
286
  exception_table = []
277
287
  exception_table_length = read( 2, io )
278
288
  exception_table_length.times {
@@ -302,6 +312,13 @@ module_function
302
312
  local_variable_type_table << read_local_variable_type( io, java_class )
303
313
  }
304
314
  attr = LocalVariableTypeTableAttribute.new( java_class, name_index, local_variable_type_table )
315
+ when "StackMapTable"
316
+ stack_map_frame_entries = []
317
+ entry_count = read( 2, io )
318
+ entry_count.times {
319
+ stack_map_frame_entries << read_stack_map_frame_entry( io, java_class )
320
+ }
321
+ attr = StackMapTableAttribute .new( java_class, name_index, stack_map_frame_entries )
305
322
  else
306
323
  read( length, io ) # 読み飛ばす。
307
324
  attr = Attribute.new( java_class, name_index )
@@ -446,4 +463,441 @@ module_function
446
463
  return LocalVariableType.new( java_class, \
447
464
  start_pc, length, name_index, signature_index, index )
448
465
  end
466
+
467
+ #
468
+ #=== スタックマップフレームを読み込む
469
+ #
470
+ #*io::IO
471
+ #*java_class::Javaクラス
472
+ #
473
+ def read_stack_map_frame_entry( io, java_class )
474
+ frame_type = read( 1, io )
475
+ if frame_type < 64
476
+ return SameFrame.new( frame_type )
477
+ elsif frame_type >= 64 && frame_type < 128
478
+ variable_info = read_variable_info( io, java_class )
479
+ return SameLocals1StackItemFrame.new( frame_type, [variable_info] )
480
+ elsif frame_type == 247
481
+ offset_delta = read( 2, io )
482
+ variable_info = read_variable_info( io, java_class )
483
+ return SameLocals1StackItemFrameExtended.new(
484
+ frame_type, offset_delta, [variable_info] )
485
+ elsif frame_type >= 248 && frame_type < 251
486
+ offset_delta = read( 2, io )
487
+ return ChopFrame.new( frame_type, offset_delta )
488
+ elsif frame_type == 251
489
+ offset_delta = read( 2, io )
490
+ return SameFrameExtended.new( frame_type, offset_delta )
491
+ elsif frame_type >= 252 && frame_type < 255
492
+ offset_delta = read( 2, io )
493
+ variable_infos=[]
494
+ (frame_type - 251).times {|i|
495
+ variable_infos << read_variable_info( io, java_class )
496
+ }
497
+ return AppendFrame.new( frame_type, offset_delta, variable_infos )
498
+ elsif frame_type == 255
499
+ offset_delta = read( 2, io )
500
+ local_size = read( 2, io )
501
+ local_variable_infos=[]
502
+ (local_size).times {|i|
503
+ local_variable_infos << read_variable_info( io, java_class )
504
+ }
505
+ stack_size = read( 2, io )
506
+ stack_variable_infos=[]
507
+ (stack_size).times {|i|
508
+ stack_variable_infos << read_variable_info( io, java_class )
509
+ }
510
+ return FullFrame.new( frame_type, offset_delta, local_variable_infos, stack_variable_infos )
511
+ end
512
+ end
513
+
514
+ #
515
+ #=== 変数情報を読み込む
516
+ #
517
+ #*io::IO
518
+ #*java_class::Javaクラス
519
+ #
520
+ def read_variable_info( io, java_class )
521
+ tag = read( 1, io )
522
+ case tag
523
+ when 7
524
+ return ObjectVariableInfo.new( tag, read( 2, io ) )
525
+ when 8
526
+ return UninitializedVariableInfo.new( tag, read( 2, io ) )
527
+ else
528
+ return VariableInfo.new( tag )
529
+ end
530
+ end
531
+
532
+ #
533
+ #=== コードを読み込む
534
+ #
535
+ #*index::code中での出現位置
536
+ #*io::IO
537
+ #*java_class::Javaクラス
538
+ #*codes::コードを追加するバッファ
539
+ #
540
+ def read_code( index, io, java_class, codes )
541
+ code = nil
542
+ opcode = read( 1, io )
543
+ case opcode
544
+ when 0x19 # aload
545
+ operands = [
546
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
547
+ ]
548
+ code = Code.new( java_class, index, opcode, operands )
549
+ when 0xBD # anewarray
550
+ operands = [
551
+ Operand.new( "u2", read( 2, io ), "index"),
552
+ ]
553
+ code = Code.new( java_class, index, opcode, operands )
554
+ when 0x3A # astore
555
+ operands = [
556
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
557
+ ]
558
+ code = Code.new( java_class, index, opcode, operands )
559
+ when 0x10 # bipush
560
+ operands = [
561
+ Operand.new( "s1", read( 1, io, false ), "<n>"),
562
+ ]
563
+ code = Code.new( java_class, index, opcode, operands )
564
+ when 0xC0 # checkcast
565
+ operands = [
566
+ Operand.new( "u2", read( 2, io ), "index"),
567
+ ]
568
+ code = Code.new( java_class, index, opcode, operands )
569
+ when 0x18 # dload
570
+ operands = [
571
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
572
+ ]
573
+ code = Code.new( java_class, index, opcode, operands )
574
+ when 0x39 # dstore
575
+ operands = [
576
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
577
+ ]
578
+ code = Code.new( java_class, index, opcode, operands )
579
+ when 0x17 # fload
580
+ operands = [
581
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
582
+ ]
583
+ code = Code.new( java_class, index, opcode, operands )
584
+ when 0x38 # fstore
585
+ operands = [
586
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
587
+ ]
588
+ code = Code.new( java_class, index, opcode, operands )
589
+ when 0xB4 # getfield
590
+ operands = [
591
+ Operand.new( "u2", read( 2, io ), "index"),
592
+ ]
593
+ code = Code.new( java_class, index, opcode, operands )
594
+ when 0xB2 # getstatic
595
+ operands = [
596
+ Operand.new( "u2", read( 2, io ), "index"),
597
+ ]
598
+ code = Code.new( java_class, index, opcode, operands )
599
+ when 0xA7 # goto
600
+ operands = [
601
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
602
+ ]
603
+ code = Code.new( java_class, index, opcode, operands )
604
+ when 0xC8 # goto_w
605
+ operands = [
606
+ Operand.new( "s4", read( 4, io, false ), "branchoffset"),
607
+ ]
608
+ code = Code.new( java_class, index, opcode, operands )
609
+ when 0xA5 # if_acmpeq
610
+ operands = [
611
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
612
+ ]
613
+ code = Code.new( java_class, index, opcode, operands )
614
+ when 0xA6 # if_acmpne
615
+ operands = [
616
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
617
+ ]
618
+ code = Code.new( java_class, index, opcode, operands )
619
+ when 0x9F # if_icmpeq
620
+ operands = [
621
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
622
+ ]
623
+ code = Code.new( java_class, index, opcode, operands )
624
+ when 0xA2 # if_icmpge
625
+ operands = [
626
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
627
+ ]
628
+ code = Code.new( java_class, index, opcode, operands )
629
+ when 0xA3 # if_icmpgt
630
+ operands = [
631
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
632
+ ]
633
+ code = Code.new( java_class, index, opcode, operands )
634
+ when 0xA4 # if_icmple
635
+ operands = [
636
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
637
+ ]
638
+ code = Code.new( java_class, index, opcode, operands )
639
+ when 0xA1 # if_icmplt
640
+ operands = [
641
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
642
+ ]
643
+ code = Code.new( java_class, index, opcode, operands )
644
+ when 0xA0 # if_icmpne
645
+ operands = [
646
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
647
+ ]
648
+ code = Code.new( java_class, index, opcode, operands )
649
+ when 0x99 # ifeq
650
+ operands = [
651
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
652
+ ]
653
+ code = Code.new( java_class, index, opcode, operands )
654
+ when 0x9C # ifge
655
+ operands = [
656
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
657
+ ]
658
+ code = Code.new( java_class, index, opcode, operands )
659
+ when 0x9D # ifgt
660
+ operands = [
661
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
662
+ ]
663
+ code = Code.new( java_class, index, opcode, operands )
664
+ when 0x9E # ifle
665
+ operands = [
666
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
667
+ ]
668
+ code = Code.new( java_class, index, opcode, operands )
669
+ when 0x9B # iflt
670
+ operands = [
671
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
672
+ ]
673
+ code = Code.new( java_class, index, opcode, operands )
674
+ when 0x9A # ifne
675
+ operands = [
676
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
677
+ ]
678
+ code = Code.new( java_class, index, opcode, operands )
679
+ when 0xC7 # ifnonnull
680
+ operands = [
681
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
682
+ ]
683
+ code = Code.new( java_class, index, opcode, operands )
684
+ when 0xC6 # ifnull
685
+ operands = [
686
+ Operand.new( "s2", read( 2, io, false ), "branch-offset"),
687
+ ]
688
+ code = Code.new( java_class, index, opcode, operands )
689
+ when 0x84 # iinc
690
+ operands = [
691
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
692
+ Operand.new( "s1", read( 1, io, false ), "<n>"),
693
+ ]
694
+ code = Code.new( java_class, index, opcode, operands )
695
+ when 0x15 # iload
696
+ operands = [
697
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
698
+ ]
699
+ code = Code.new( java_class, index, opcode, operands )
700
+ when 0xC1 # instanceof
701
+ operands = [
702
+ Operand.new( "u2", read( 2, io ), "index"),
703
+ ]
704
+ code = Code.new( java_class, index, opcode, operands )
705
+ when 0xB9 # invokeinterface
706
+ operands = [
707
+ Operand.new( "u2", read( 2, io ), "index"),
708
+ Operand.new( "u1", read( 1, io ), "<n>"),
709
+ Operand.new( "u1", read( 1, io ), "0"),
710
+ ]
711
+ code = Code.new( java_class, index, opcode, operands )
712
+ when 0xB7 # invokespecial
713
+ operands = [
714
+ Operand.new( "u2", read( 2, io ), "index"),
715
+ ]
716
+ code = Code.new( java_class, index, opcode, operands )
717
+ when 0xB8 # invokestatic
718
+ operands = [
719
+ Operand.new( "u2", read( 2, io ), "index"),
720
+ ]
721
+ code = Code.new( java_class, index, opcode, operands )
722
+ when 0xB6 # invokevirtual
723
+ operands = [
724
+ Operand.new( "u2", read( 2, io ), "index"),
725
+ ]
726
+ code = Code.new( java_class, index, opcode, operands )
727
+ when 0x36 # istore
728
+ operands = [
729
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
730
+ ]
731
+ code = Code.new( java_class, index, opcode, operands )
732
+ when 0xA8 # jsr
733
+ operands = [
734
+ Operand.new( "s2", read( 2, io, false ), "branchoffset"),
735
+ ]
736
+ code = Code.new( java_class, index, opcode, operands )
737
+ when 0xC9 # jsr_w
738
+ operands = [
739
+ Operand.new( "s4", read( 4, io, false ), "branchoffset"),
740
+ ]
741
+ code = Code.new( java_class, index, opcode, operands )
742
+ when 0x12 # ldc
743
+ operands = [
744
+ Operand.new( "u1", read( 1, io ), "index"),
745
+ ]
746
+ code = Code.new( java_class, index, opcode, operands )
747
+ when 0x14 # ldc2_w
748
+ operands = [
749
+ Operand.new( "u2", read( 2, io ), "index"),
750
+ ]
751
+ code = Code.new( java_class, index, opcode, operands )
752
+ when 0x13 # ldc_w
753
+ operands = [
754
+ Operand.new( "u2", read( 2, io ), "index"),
755
+ ]
756
+ code = Code.new( java_class, index, opcode, operands )
757
+ when 0x16 # lload
758
+ operands = [
759
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
760
+ ]
761
+ code = Code.new( java_class, index, opcode, operands )
762
+ when 0xAB # lookupswitch
763
+ operands = []
764
+ # 0 to 3 bytes of padding zeros
765
+ ((index+1)%4 == 0 ? 0 :4-((index+1)%4)).times {|i|
766
+ operands << Operand.new( "u1", read( 1, io ), "0 padding")
767
+ }
768
+ operands << Operand.new( "s4", read( 4, io, false ), "default_offset")
769
+ n = read( 4, io, false )
770
+ operands << Operand.new( "s4", n, "n")
771
+ n.times {|i|
772
+ operands << Operand.new( "s4", read( 4, io, false ), "key_#{i}")
773
+ operands << Operand.new( "s4", read( 4, io, false ), "offset_#{i}")
774
+ }
775
+ code = Code.new( java_class, index, opcode, operands )
776
+ when 0x37 # lstore
777
+ operands = [
778
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
779
+ ]
780
+ code = Code.new( java_class, index, opcode, operands )
781
+ when 0xC5 # multianewarray
782
+ operands = [
783
+ Operand.new( "u2", read( 2, io ), "index"),
784
+ Operand.new( "u1", read( 1, io ), "<n>"),
785
+ ]
786
+ code = Code.new( java_class, index, opcode, operands )
787
+ when 0xBB # new
788
+ operands = [
789
+ Operand.new( "u2", read( 2, io ), "index"),
790
+ ]
791
+ code = Code.new( java_class, index, opcode, operands )
792
+ when 0xBC # newarray
793
+ operands = [
794
+ Operand.new( "u1", read( 1, io ), "array-type"),
795
+ ]
796
+ code = Code.new( java_class, index, opcode, operands )
797
+ when 0xB5 # putfield
798
+ operands = [
799
+ Operand.new( "u2", read( 2, io ), "index"),
800
+ ]
801
+ code = Code.new( java_class, index, opcode, operands )
802
+ when 0xB3 # putstatic
803
+ operands = [
804
+ Operand.new( "u2", read( 2, io ), "index"),
805
+ ]
806
+ code = Code.new( java_class, index, opcode, operands )
807
+ when 0xA9 # ret
808
+ operands = [
809
+ Operand.new( "u1", read( 1, io ), "<varnum>"),
810
+ ]
811
+ code = Code.new( java_class, index, opcode, operands )
812
+ when 0x11 # sipush
813
+ operands = [
814
+ Operand.new( "s2", read( 2, io, false ), "<n>"),
815
+ ]
816
+ code = Code.new( java_class, index, opcode, operands )
817
+ when 0xAA # tableswitch
818
+ operands = []
819
+ # 0 to 3 bytes of padding zeros
820
+ ((index+1)%4 == 0 ? 0 :4-((index+1)%4)).times {|i|
821
+ operands << Operand.new( "u1", read( 1, io ), "0 padding")
822
+ }
823
+ operands << Operand.new( "s4", read( 4, io, false ), "default_offset")
824
+ low = read( 4, io, false )
825
+ hight = read( 4, io, false )
826
+ operands << Operand.new( "s4", low, "<low>")
827
+ operands << Operand.new( "s4", hight, "<low> + N - 1")
828
+ (hight-low+1).times {|i|
829
+ operands << Operand.new( "s4", read( 4, io, false ), "offset_#{i}")
830
+ }
831
+ code = Code.new( java_class, index, opcode, operands )
832
+ when 0xC4 # wide
833
+ opcode = read( 1, io )
834
+ case opcode
835
+ when 0x19 # aload
836
+ operands = [
837
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
838
+ ]
839
+ code = Code.new( java_class, index, opcode, operands, true )
840
+ when 0x3A # astore
841
+ operands = [
842
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
843
+ ]
844
+ code = Code.new( java_class, index, opcode, operands, true )
845
+ when 0x18 # dload
846
+ operands = [
847
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
848
+ ]
849
+ code = Code.new( java_class, index, opcode, operands, true )
850
+ when 0x39 # dstore
851
+ operands = [
852
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
853
+ ]
854
+ code = Code.new( java_class, index, opcode, operands, true )
855
+ when 0x17 # fload
856
+ operands = [
857
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
858
+ ]
859
+ code = Code.new( java_class, index, opcode, operands, true )
860
+ when 0x38 # fstore
861
+ operands = [
862
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
863
+ ]
864
+ code = Code.new( java_class, index, opcode, operands, true )
865
+ when 0x84 # iinc
866
+ operands = [
867
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
868
+ Operand.new( "s2", read( 2, io, false ), "<n>"),
869
+ ]
870
+ code = Code.new( java_class, index, opcode, operands, true )
871
+ when 0x15 # iload
872
+ operands = [
873
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
874
+ ]
875
+ code = Code.new( java_class, index, opcode, operands, true )
876
+ when 0x36 # istore
877
+ operands = [
878
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
879
+ ]
880
+ code = Code.new( java_class, index, opcode, operands, true )
881
+ when 0x16 # lload
882
+ operands = [
883
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
884
+ ]
885
+ code = Code.new( java_class, index, opcode, operands, true )
886
+ when 0x37 # lstore
887
+ operands = [
888
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
889
+ ]
890
+ code = Code.new( java_class, index, opcode, operands, true )
891
+ when 0xA9 # ret
892
+ operands = [
893
+ Operand.new( "u2", read( 2, io ), "<varnum>"),
894
+ ]
895
+ code = Code.new( java_class, index, opcode, operands, true )
896
+ end
897
+ else
898
+ code = Code.new( java_class, index, opcode )
899
+ end
900
+ codes << code if code
901
+ return code ? code.to_bytes.length : 1
902
+ end
449
903
  end