@@ -172,14 +172,6 @@ static inline void ineg(stack_frame_t *op_stack)
172172 push_int (op_stack , - op1 );
173173}
174174
175- static inline void invokevirtual (stack_frame_t * op_stack )
176- {
177- int64_t op = pop_int (op_stack );
178- 179- /* FIXME: the implement is not correct. */
180- printf ("%" PRId64 "\n" , op );
181- }
182- 183175static inline void iconst (stack_frame_t * op_stack , uint8_t current )
184176{
185177 push_int (op_stack , current - i_iconst_0 );
@@ -906,10 +898,83 @@ stack_entry_t *execute(method_t *method,
906898 }
907899
908900 /* Invoke instance method; dispatch based on class */
909- case i_invokevirtual :
910- invokevirtual (op_stack );
901+ case i_invokevirtual : {
902+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
903+ uint16_t index = ((param1 << 8 ) | param2 );
904+ 905+ /* the method to be called */
906+ char * method_name , * method_descriptor , * class_name ;
907+ class_name = find_method_info_from_index (index , clazz , & method_name ,
908+ & method_descriptor );
909+ 910+ /* to handle print method */
911+ if (!strcmp (class_name , "java/io/PrintStream" )) {
912+ stack_entry_t element = top (op_stack );
913+ 914+ switch (element .type ) {
915+ /* integer */
916+ case STACK_ENTRY_INT :
917+ case STACK_ENTRY_SHORT :
918+ case STACK_ENTRY_BYTE :
919+ case STACK_ENTRY_LONG : {
920+ int64_t op = pop_int (op_stack );
921+ printf ("%ld\n" , op );
922+ break ;
923+ }
924+ default :
925+ printf ("print type (%d) is not supported\n" , element .type );
926+ break ;
927+ }
928+ pc += 3 ;
929+ break ;
930+ }
931+ 932+ /* FIXME: consider method modifier */
933+ class_file_t * target_class =
934+ find_or_add_class_to_heap (class_name , prefix );
935+ 936+ method_t * method =
937+ find_method (method_name , method_descriptor , target_class );
938+ uint16_t num_params = get_number_of_parameters (method );
939+ local_variable_t own_locals [method -> code .max_locals ];
940+ memset (own_locals , 0 , sizeof (own_locals ));
941+ for (int i = num_params ; i >= 1 ; i -- ) {
942+ pop_to_local (op_stack , & own_locals [i ]);
943+ }
944+ object_t * obj = pop_ref (op_stack );
945+ 946+ /* first argument is this pointer */
947+ own_locals [0 ].entry .ptr_value = obj ;
948+ own_locals [0 ].type = STACK_ENTRY_REF ;
949+ 950+ stack_entry_t * exec_res = execute (method , own_locals , target_class );
951+ switch (exec_res -> type ) {
952+ case STACK_ENTRY_BYTE :
953+ push_int (op_stack , exec_res -> entry .char_value );
954+ break ;
955+ case STACK_ENTRY_SHORT :
956+ push_int (op_stack , exec_res -> entry .short_value );
957+ break ;
958+ case STACK_ENTRY_INT :
959+ push_int (op_stack , exec_res -> entry .int_value );
960+ break ;
961+ case STACK_ENTRY_LONG :
962+ push_long (op_stack , exec_res -> entry .long_value );
963+ break ;
964+ case STACK_ENTRY_REF :
965+ push_ref (op_stack , exec_res -> entry .ptr_value );
966+ break ;
967+ case STACK_ENTRY_NONE :
968+ /* nothing */
969+ break ;
970+ default :
971+ assert (0 && "unknown return type" );
972+ }
973+ 974+ free (exec_res );
911975 pc += 3 ;
912976 break ;
977+ }
913978
914979 /* Push int constant */
915980 case i_iconst_m1 :
0 commit comments