@@ -94,6 +94,9 @@ typedef enum {
94
94
i_areturn = 0xb0 ,
95
95
i_return = 0xb1 ,
96
96
i_getstatic = 0xb2 ,
97
+ i_putstatic = 0xb3 ,
98
+ i_getfield = 0xb4 ,
99
+ i_putfield = 0xb5 ,
97
100
i_invokevirtual = 0xb6 ,
98
101
i_invokespecial = 0xb7 ,
99
102
i_invokestatic = 0xb8 ,
@@ -783,10 +786,124 @@ stack_entry_t *execute(method_t *method,
783
786
break ;
784
787
785
788
/* Get static field from class */
786
- case i_getstatic :
787
- /* FIXME: unimplemented */
789
+ case i_getstatic : {
790
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
791
+ uint16_t index = ((param1 << 8 ) | param2 );
792
+
793
+ char * field_name , * field_descriptor , * class_name ;
794
+ class_name = find_field_info_from_index (index , clazz , & field_name ,
795
+ & field_descriptor );
796
+
797
+ /* skip java.lang.System in order to support java print
798
+ * method */
799
+ if (!strcmp (class_name , "java/lang/System" )) {
800
+ pc += 3 ;
801
+ break ;
802
+ }
803
+
804
+ class_file_t * target_class =
805
+ find_or_add_class_to_heap (class_name , prefix );
806
+ field_t * field =
807
+ find_field (field_name , field_descriptor , target_class );
808
+
809
+ switch (field_descriptor [0 ]) {
810
+ case 'B' :
811
+ /* signed byte */
812
+ push_byte (op_stack , field -> static_var -> value .char_value );
813
+ break ;
814
+ case 'C' :
815
+ /* FIXME: complete Unicode handling */
816
+ /* unicode character code */
817
+ push_short (op_stack , field -> static_var -> value .short_value );
818
+ break ;
819
+ case 'I' :
820
+ /* integer */
821
+ push_int (op_stack , field -> static_var -> value .int_value );
822
+ break ;
823
+ case 'J' :
824
+ /* long integer */
825
+ push_long (op_stack , field -> static_var -> value .long_value );
826
+ break ;
827
+ case 'S' :
828
+ /* signed short */
829
+ push_short (op_stack , field -> static_var -> value .short_value );
830
+ break ;
831
+ case 'Z' :
832
+ /* true or false */
833
+ push_byte (op_stack , field -> static_var -> value .char_value );
834
+ break ;
835
+ case 'L' :
836
+ /* an instance of class */
837
+ push_ref (op_stack , field -> static_var -> value .ptr_value );
838
+ break ;
839
+ default :
840
+ fprintf (stderr , "Unknown field descriptor %c\n" ,
841
+ field_descriptor [0 ]);
842
+ exit (1 );
843
+ }
788
844
pc += 3 ;
789
845
break ;
846
+ }
847
+
848
+ /* Put static field to class */
849
+ case i_putstatic : {
850
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
851
+ uint16_t index = ((param1 << 8 ) | param2 );
852
+
853
+ char * field_name , * field_descriptor , * class_name ;
854
+ class_name = find_field_info_from_index (index , clazz , & field_name ,
855
+ & field_descriptor );
856
+
857
+ class_file_t * target_class =
858
+ find_or_add_class_to_heap (class_name , prefix );
859
+ field_t * field =
860
+ find_field (field_name , field_descriptor , target_class );
861
+
862
+ switch (field_descriptor [0 ]) {
863
+ case 'B' :
864
+ /* signed byte */
865
+ field -> static_var -> value .char_value = (u1 ) pop_int (op_stack );
866
+ field -> static_var -> type = VAR_BYTE ;
867
+ break ;
868
+ case 'C' :
869
+ /* FIXME: complete Unicode handling */
870
+ /* unicode character code */
871
+ field -> static_var -> value .char_value = (u2 ) pop_int (op_stack );
872
+ field -> static_var -> type = VAR_SHORT ;
873
+ break ;
874
+ case 'I' :
875
+ /* integer */
876
+ field -> static_var -> value .int_value = (u4 ) pop_int (op_stack );
877
+ field -> static_var -> type = VAR_INT ;
878
+ break ;
879
+ case 'J' :
880
+ /* long integer */
881
+ field -> static_var -> value .long_value = (u8 ) pop_int (op_stack );
882
+ field -> static_var -> type = VAR_LONG ;
883
+ break ;
884
+ case 'S' :
885
+ /* signed short */
886
+ field -> static_var -> value .short_value = (u2 ) pop_int (op_stack );
887
+ field -> static_var -> type = VAR_SHORT ;
888
+ break ;
889
+ case 'Z' :
890
+ /* true or false */
891
+ field -> static_var -> value .char_value = (u1 ) pop_int (op_stack );
892
+ field -> static_var -> type = VAR_BYTE ;
893
+ break ;
894
+ case 'L' :
895
+ /* an instance of class ClassName */
896
+ field -> static_var -> value .ptr_value = pop_ref (op_stack );
897
+ field -> static_var -> type = VAR_PTR ;
898
+ break ;
899
+ default :
900
+ fprintf (stderr , "Unknown field descriptor %c\n" ,
901
+ field_descriptor [0 ]);
902
+ exit (1 );
903
+ }
904
+ pc += 3 ;
905
+ break ;
906
+ }
790
907
791
908
/* Invoke instance method; dispatch based on class */
792
909
case i_invokevirtual :
@@ -820,6 +937,91 @@ stack_entry_t *execute(method_t *method,
820
937
pc += 3 ;
821
938
break ;
822
939
940
+ /* Fetch field from object */
941
+ case i_getfield : {
942
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
943
+ uint16_t index = ((param1 << 8 ) | param2 );
944
+
945
+ object_t * obj = pop_ref (op_stack );
946
+ char * field_name , * field_descriptor ;
947
+ find_field_info_from_index (index , clazz , & field_name ,
948
+ & field_descriptor );
949
+
950
+ variable_t * addr = find_field_addr (obj , field_name );
951
+
952
+ switch (field_descriptor [0 ]) {
953
+ case 'I' :
954
+ push_int (op_stack , addr -> value .int_value );
955
+ break ;
956
+ case 'J' :
957
+ push_long (op_stack , addr -> value .long_value );
958
+ break ;
959
+ case 'L' :
960
+ push_ref (op_stack , addr -> value .ptr_value );
961
+ break ;
962
+ default :
963
+ assert (0 && "Only support integer and reference field" );
964
+ break ;
965
+ }
966
+ pc += 3 ;
967
+ break ;
968
+ }
969
+
970
+ /* Set field in object */
971
+ case i_putfield : {
972
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
973
+ uint16_t index = ((param1 << 8 ) | param2 );
974
+ int64_t value = 0 ;
975
+ void * addr = NULL ;
976
+
977
+ /* get prepared value from the stack */
978
+ stack_entry_t element = top (op_stack );
979
+ switch (element .type ) {
980
+ /* integer */
981
+ case STACK_ENTRY_INT :
982
+ case STACK_ENTRY_SHORT :
983
+ case STACK_ENTRY_BYTE :
984
+ case STACK_ENTRY_LONG :
985
+ value = pop_int (op_stack );
986
+ break ;
987
+ case STACK_ENTRY_REF :
988
+ addr = pop_ref (op_stack );
989
+ break ;
990
+ default :
991
+ assert (0 && "Only support integer and reference field" );
992
+ break ;
993
+ }
994
+
995
+ object_t * obj = pop_ref (op_stack );
996
+
997
+ /* update value into object's field */
998
+ char * field_name , * field_descriptor ;
999
+ find_field_info_from_index (index , clazz , & field_name ,
1000
+ & field_descriptor );
1001
+
1002
+ variable_t * var = find_field_addr (obj , field_name );
1003
+
1004
+ switch (field_descriptor [0 ]) {
1005
+ case 'I' :
1006
+ var -> value .int_value = (int32_t ) value ;
1007
+ var -> type = VAR_INT ;
1008
+ break ;
1009
+ case 'J' :
1010
+ var -> value .long_value = value ;
1011
+ var -> type = VAR_LONG ;
1012
+ break ;
1013
+ case 'L' :
1014
+ var -> value .ptr_value = addr ;
1015
+ var -> type = VAR_PTR ;
1016
+ break ;
1017
+ default :
1018
+ assert (0 && "Only support integer and reference field" );
1019
+ break ;
1020
+ }
1021
+ pc += 3 ;
1022
+ break ;
1023
+ }
1024
+
823
1025
/* create new object */
824
1026
case i_new : {
825
1027
uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
0 commit comments