@@ -6,6 +6,8 @@ use jvm_types::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags};
66
77use crate :: { RuntimeClassProto , RuntimeContext , classes:: java:: lang:: Object } ;
88
9+ use super :: { HashMap , HashMapEntry } ;
10+
911// abstract class java.util.HashMap$HashIterator
1012pub struct HashMapHashIterator ;
1113
@@ -16,24 +18,39 @@ impl HashMapHashIterator {
1618 parent_class : Some ( "java/lang/Object" ) ,
1719 interfaces : vec ! [ "java/util/Iterator" ] ,
1820 methods : vec ! [
19- JavaMethodProto :: new( "<init>" , "([Ljava/lang/Object;)V" , Self :: init, MethodAccessFlags :: empty( ) ) ,
21+ JavaMethodProto :: new(
22+ "<init>" ,
23+ "(Ljava/util/HashMap;[Ljava/lang/Object;)V" ,
24+ Self :: init,
25+ MethodAccessFlags :: empty( ) ,
26+ ) ,
2027 JavaMethodProto :: new( "hasNext" , "()Z" , Self :: has_next, MethodAccessFlags :: PUBLIC | MethodAccessFlags :: FINAL ) ,
2128 JavaMethodProto :: new( "next" , "()Ljava/lang/Object;" , Self :: next, MethodAccessFlags :: PUBLIC ) ,
2229 JavaMethodProto :: new( "remove" , "()V" , Self :: remove, MethodAccessFlags :: PUBLIC | MethodAccessFlags :: FINAL ) ,
2330 ] ,
2431 fields : vec ! [
32+ JavaFieldProto :: new( "map" , "Ljava/util/HashMap;" , FieldAccessFlags :: PRIVATE ) ,
33+ JavaFieldProto :: new( "lastReturned" , "Ljava/util/HashMap$Entry;" , FieldAccessFlags :: PRIVATE ) ,
2534 JavaFieldProto :: new( "elements" , "[Ljava/lang/Object;" , FieldAccessFlags :: PRIVATE ) ,
2635 JavaFieldProto :: new( "index" , "I" , FieldAccessFlags :: empty( ) ) ,
2736 ] ,
2837 access_flags : ClassAccessFlags :: ABSTRACT ,
2938 }
3039 }
3140
32- async fn init ( jvm : & Jvm , _: & mut RuntimeContext , mut this : ClassInstanceRef < Self > , elements : ClassInstanceRef < Array < Object > > ) -> Result < ( ) > {
41+ async fn init (
42+ jvm : & Jvm ,
43+ _: & mut RuntimeContext ,
44+ mut this : ClassInstanceRef < Self > ,
45+ map : ClassInstanceRef < HashMap > ,
46+ elements : ClassInstanceRef < Array < Object > > ,
47+ ) -> Result < ( ) > {
3348 tracing:: debug!( "java.util.HashMap$HashIterator::<init>({this:?}, {elements:?})" ) ;
3449
3550 let _: ( ) = jvm. invoke_special ( & this, "java/lang/Object" , "<init>" , "()V" , ( ) ) . await ?;
3651
52+ jvm. put_field ( & mut this, "java/util/HashMap$HashIterator" , "map" , "Ljava/util/HashMap;" , map)
53+ . await ?;
3754 jvm. put_field ( & mut this, "java/util/HashMap$HashIterator" , "elements" , "[Ljava/lang/Object;" , elements)
3855 . await ?;
3956 jvm. put_field ( & mut this, "java/util/HashMap$HashIterator" , "index" , "I" , 0 ) . await ?;
@@ -66,19 +83,48 @@ impl HashMapHashIterator {
6683 return Err ( jvm. exception ( "java/util/NoSuchElementException" , "HashMap iterator exhausted" ) . await ) ;
6784 }
6885
69- let mut values = jvm. load_array ( & elements, index as usize , 1 ) . await ?;
86+ let mut values: alloc :: vec :: Vec < ClassInstanceRef < Object > > = jvm. load_array ( & elements, index as usize , 1 ) . await ?;
7087 let Some ( element) = values. pop ( ) else {
7188 return Err ( jvm. exception ( "java/util/NoSuchElementException" , "HashMap iterator exhausted" ) . await ) ;
7289 } ;
7390 jvm. put_field ( & mut this, "java/util/HashMap$HashIterator" , "index" , "I" , index + 1 )
7491 . await ?;
92+ jvm. put_field (
93+ & mut this,
94+ "java/util/HashMap$HashIterator" ,
95+ "lastReturned" ,
96+ "Ljava/util/HashMap$Entry;" ,
97+ element. clone ( ) ,
98+ )
99+ . await ?;
75100
76101 Ok ( element)
77102 }
78103
79- async fn remove ( jvm : & Jvm , _: & mut RuntimeContext , this : ClassInstanceRef < Self > ) -> Result < ( ) > {
104+ async fn remove ( jvm : & Jvm , _: & mut RuntimeContext , mut this : ClassInstanceRef < Self > ) -> Result < ( ) > {
80105 tracing:: debug!( "java.util.HashMap$HashIterator::remove({this:?})" ) ;
81106
82- Err ( jvm. exception ( "java/lang/UnsupportedOperationException" , "Iterator.remove" ) . await )
107+ let entry: ClassInstanceRef < HashMapEntry > = jvm
108+ . get_field ( & this, "java/util/HashMap$HashIterator" , "lastReturned" , "Ljava/util/HashMap$Entry;" )
109+ . await ?;
110+ if entry. is_null ( ) {
111+ return Err ( jvm. exception ( "java/lang/IllegalStateException" , "No entry to remove" ) . await ) ;
112+ }
113+ let map = jvm
114+ . get_field ( & this, "java/util/HashMap$HashIterator" , "map" , "Ljava/util/HashMap;" )
115+ . await ?;
116+ let key: ClassInstanceRef < Object > = jvm. get_field ( & entry, "java/util/HashMap$Entry" , "key" , "Ljava/lang/Object;" ) . await ?;
117+ let _: ClassInstanceRef < Object > = jvm
118+ . invoke_virtual ( & map, "java/util/HashMap" , "remove" , "(Ljava/lang/Object;)Ljava/lang/Object;" , ( key, ) )
119+ . await ?;
120+ let null_entry: ClassInstanceRef < HashMapEntry > = None . into ( ) ;
121+ jvm. put_field (
122+ & mut this,
123+ "java/util/HashMap$HashIterator" ,
124+ "lastReturned" ,
125+ "Ljava/util/HashMap$Entry;" ,
126+ null_entry,
127+ )
128+ . await
83129 }
84130}
0 commit comments