@@ -178,11 +178,10 @@ impl Jvm {
178178
179179 let class = self . resolve_class ( class_name) . await ?;
180180
181- let field = class. definition . field ( name, descriptor, true ) ;
182- if let Some ( field) = field {
183- self . ensure_initialized ( & class) . await ?;
181+ if let Some ( ( declaring_class, field) ) = self . resolve_static_field ( & class, name, descriptor) {
182+ self . ensure_initialized ( & declaring_class) . await ?;
184183
185- Ok ( class . definition . get_static_field ( & * field) ?. into ( ) )
184+ Ok ( declaring_class . definition . get_static_field ( & * field) ?. into ( ) )
186185 } else {
187186 Err ( self
188187 . exception ( "java/lang/NoSuchFieldError" , & format ! ( "{class_name}.{name}:{descriptor}" ) )
@@ -196,14 +195,12 @@ impl Jvm {
196195 {
197196 tracing:: trace!( "Put static field {}.{}:{} = {:?}" , class_name, name, descriptor, value) ;
198197
199- let mut class = self . resolve_class ( class_name) . await ?;
200-
201- let field = class. definition . field ( name, descriptor, true ) ;
198+ let class = self . resolve_class ( class_name) . await ?;
202199
203- if let Some ( field) = field {
204- self . ensure_initialized ( & class ) . await ?;
200+ if let Some ( ( mut declaring_class , field) ) = self . resolve_static_field ( & class , name , descriptor ) {
201+ self . ensure_initialized ( & declaring_class ) . await ?;
205202
206- class . definition . put_static_field ( & * field, value. into ( ) )
203+ declaring_class . definition . put_static_field ( & * field, value. into ( ) )
207204 } else {
208205 Err ( self
209206 . exception ( "java/lang/NoSuchFieldError" , & format ! ( "{class_name}.{name}:{descriptor}" ) )
@@ -262,18 +259,10 @@ impl Jvm {
262259
263260 let class = self . resolve_class ( class_name) . await ?;
264261
265- let method = class. definition . method ( name, descriptor, true ) ;
266-
267- if let Some ( method) = method {
268- if !method. access_flags ( ) . contains ( MethodAccessFlags :: STATIC ) {
269- return Err ( self
270- . exception ( "java/lang/IncompatibleClassChangeError" , & format ! ( "{class_name}.{name}:{descriptor}" ) )
271- . await ) ;
272- }
273-
274- self . ensure_initialized ( & class) . await ?;
262+ if let Some ( ( declaring_class, method) ) = self . resolve_static_method ( & class, name, descriptor) {
263+ self . ensure_initialized ( & declaring_class) . await ?;
275264
276- Ok ( self . execute_method ( & class , None , & method, args) . await ?. into ( ) )
265+ Ok ( self . execute_method ( & declaring_class , None , & method, args) . await ?. into ( ) )
277266 } else {
278267 tracing:: error!( "No such method: {}.{}:{}" , class_name, name, descriptor) ;
279268
@@ -815,6 +804,34 @@ impl Jvm {
815804 monitors. entry ( key) . or_insert_with ( || Arc :: new ( Event :: new ( ) ) ) . clone ( )
816805 }
817806
807+ // JVMS 5.4.3.2 field resolution: search the class, then its superinterfaces, then its superclass
808+ fn resolve_static_field ( & self , class : & Class , name : & str , descriptor : & str ) -> Option < ( Class , Box < dyn Field > ) > {
809+ if let Some ( field) = class. definition . field ( name, descriptor, true ) {
810+ return Some ( ( class. clone ( ) , field) ) ;
811+ }
812+
813+ for interface in class. definition . interface_names ( ) {
814+ if let Some ( interface_class) = self . get_class ( & interface)
815+ && let Some ( found) = self . resolve_static_field ( & interface_class, name, descriptor)
816+ {
817+ return Some ( found) ;
818+ }
819+ }
820+
821+ let super_class = self . get_class ( & class. definition . super_class_name ( ) ?) ?;
822+ self . resolve_static_field ( & super_class, name, descriptor)
823+ }
824+
825+ // JVMS 5.4.3.3 method resolution for static methods; interfaces have no static methods in this runtime
826+ fn resolve_static_method ( & self , class : & Class , name : & str , descriptor : & str ) -> Option < ( Class , Box < dyn Method > ) > {
827+ if let Some ( method) = class. definition . method ( name, descriptor, true ) {
828+ return Some ( ( class. clone ( ) , method) ) ;
829+ }
830+
831+ let super_class = self . get_class ( & class. definition . super_class_name ( ) ?) ?;
832+ self . resolve_static_method ( & super_class, name, descriptor)
833+ }
834+
818835 pub ( crate ) fn find_field ( & self , class : & dyn ClassDefinition , name : & str , descriptor : & str ) -> Result < Option < Box < dyn Field > > > {
819836 let field = class. field ( name, descriptor, false ) ;
820837
0 commit comments