@@ -172,14 +172,6 @@ static inline void ineg(stack_frame_t *op_stack)
172
172
push_int (op_stack , - op1 );
173
173
}
174
174
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
-
183
175
static inline void iconst (stack_frame_t * op_stack , uint8_t current )
184
176
{
185
177
push_int (op_stack , current - i_iconst_0 );
@@ -906,10 +898,83 @@ stack_entry_t *execute(method_t *method,
906
898
}
907
899
908
900
/* 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 );
911
975
pc += 3 ;
912
976
break ;
977
+ }
913
978
914
979
/* Push int constant */
915
980
case i_iconst_m1 :
0 commit comments