@@ -94,6 +94,8 @@ typedef enum {
94
94
i_areturn = 0xb0 ,
95
95
i_return = 0xb1 ,
96
96
i_getstatic = 0xb2 ,
97
+ i_getfield = 0xb4 ,
98
+ i_putfield = 0xb5 ,
97
99
i_invokevirtual = 0xb6 ,
98
100
i_invokespecial = 0xb7 ,
99
101
i_invokestatic = 0xb8 ,
@@ -820,6 +822,91 @@ stack_entry_t *execute(method_t *method,
820
822
pc += 3 ;
821
823
break ;
822
824
825
+ /* Fetch field from object */
826
+ case i_getfield : {
827
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
828
+ uint16_t index = ((param1 << 8 ) | param2 );
829
+
830
+ object_t * obj = pop_ref (op_stack );
831
+ char * field_name , * field_descriptor ;
832
+ find_field_info_from_index (index , clazz , & field_name ,
833
+ & field_descriptor );
834
+
835
+ variable_t * addr = find_field_addr (obj , field_name );
836
+
837
+ switch (field_descriptor [0 ]) {
838
+ case 'I' :
839
+ push_int (op_stack , addr -> value .int_value );
840
+ break ;
841
+ case 'J' :
842
+ push_long (op_stack , addr -> value .long_value );
843
+ break ;
844
+ case 'L' :
845
+ push_ref (op_stack , addr -> value .ptr_value );
846
+ break ;
847
+ default :
848
+ assert (0 && "Only support integer and reference field" );
849
+ break ;
850
+ }
851
+ pc += 3 ;
852
+ break ;
853
+ }
854
+
855
+ /* Set field in object */
856
+ case i_putfield : {
857
+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
858
+ uint16_t index = ((param1 << 8 ) | param2 );
859
+ int64_t value = 0 ;
860
+ void * addr = NULL ;
861
+
862
+ /* get prepared value from the stack */
863
+ stack_entry_t element = top (op_stack );
864
+ switch (element .type ) {
865
+ /* integer */
866
+ case STACK_ENTRY_INT :
867
+ case STACK_ENTRY_SHORT :
868
+ case STACK_ENTRY_BYTE :
869
+ case STACK_ENTRY_LONG :
870
+ value = pop_int (op_stack );
871
+ break ;
872
+ case STACK_ENTRY_REF :
873
+ addr = pop_ref (op_stack );
874
+ break ;
875
+ default :
876
+ assert (0 && "Only support integer and reference field" );
877
+ break ;
878
+ }
879
+
880
+ object_t * obj = pop_ref (op_stack );
881
+
882
+ /* update value into object's field */
883
+ char * field_name , * field_descriptor ;
884
+ find_field_info_from_index (index , clazz , & field_name ,
885
+ & field_descriptor );
886
+
887
+ variable_t * var = find_field_addr (obj , field_name );
888
+
889
+ switch (field_descriptor [0 ]) {
890
+ case 'I' :
891
+ var -> value .int_value = (int32_t ) value ;
892
+ var -> type = VAR_INT ;
893
+ break ;
894
+ case 'J' :
895
+ var -> value .long_value = value ;
896
+ var -> type = VAR_LONG ;
897
+ break ;
898
+ case 'L' :
899
+ var -> value .ptr_value = addr ;
900
+ var -> type = VAR_PTR ;
901
+ break ;
902
+ default :
903
+ assert (0 && "Only support integer and reference field" );
904
+ break ;
905
+ }
906
+ pc += 3 ;
907
+ break ;
908
+ }
909
+
823
910
/* create new object */
824
911
case i_new : {
825
912
uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
0 commit comments