@@ -94,6 +94,8 @@ typedef enum {
9494 i_areturn = 0xb0 ,
9595 i_return = 0xb1 ,
9696 i_getstatic = 0xb2 ,
97+ i_getfield = 0xb4 ,
98+ i_putfield = 0xb5 ,
9799 i_invokevirtual = 0xb6 ,
98100 i_invokespecial = 0xb7 ,
99101 i_invokestatic = 0xb8 ,
@@ -820,6 +822,91 @@ stack_entry_t *execute(method_t *method,
820822 pc += 3 ;
821823 break ;
822824
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+ 823910 /* create new object */
824911 case i_new : {
825912 uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
0 commit comments